vyhnout if

hlasů
34

Přemýšlel jsem o objektově orientovaného designu dnes, a mě napadlo, jestli byste se měli vyhnout, pokud prohlášení. Moje myšlenka je, že v každém případě, kdy budete potřebovat if můžete jednoduše vytvořit dva objekty, které implementují stejné metody. Obě metody implementace by prostě být dvě možné větve originálu if.

Uvědomuji si, že to vypadá extrémní, ale zdá se, jako by jste se mohli pokusit, a argumentovat, že do určité míry. Jakékoli myšlenky na to?

UPRAVIT

Wow, že netrvalo dlouho. Myslím, že to je příliš extrémní. Je možné říci, i když, že za OOP, měli byste očekávat, že způsob, jak méně if?

DRUHÝ EDIT

A co tohle: Objekt, který určuje její provádění metody na základě svých vlastností. To znamená, že můžete provést someMethod()dvěma způsoby, a specifikovat některá omezení. V každém okamžiku bude objekt cesta ke správné provádění metody na základě jeho vlastností. Takže v případě, že if(x > 5)stačí mít dvě metody, které jsou závislé na xatributu

Položena 26/08/2009 v 22:21
zdroj uživatelem
V jiných jazycích...                            


24 odpovědí

hlasů
32

Řeknu vám jednu věc. Bez ohledu na to, co lidé říkají, přemýšlet o zjednodušení a odstranění zbytečné větvení je znamením budete zrání jako softwarový vývojář. Existuje mnoho důvodů, proč větvení je špatné, testování, údržbu, vyšší míru chyb a tak dále. To je jedna z věcí, které jsem hledat, když rozhovory s lidmi a je výborným ukazatelem, jak zralé jsou jako vývojář. Chtěl bych vás povzbudit, aby se experimentovat, zjednodušení kódu a design pomocí méně podmínek. Když jsem dělal tento přepínač jsem našel mnohem méně času ladění můj kód, to prostě funguje, a pak, když jsem měl něco změnit, změny byly super snadné dělat, protože většina kódu byla postupná. Znovu bych vás povzbudit, 100%, aby dělal to, co děláte, bez ohledu na to, co ostatní lidé říkají. Mějte na paměti, většina vývojářů pracují a myšlení na mnohem nižší úrovni a jen dodržovat pravidla. Takže dobrá práce přináší toto nahoru.

Odpovězeno 29/05/2011 v 18:08
zdroj uživatelem

hlasů
12

Vysvětlují, jak provést následující bez if nebo ternární logika:

if ( x < 5 ) {
   x = 0
} else {
   print x;
}
Odpovězeno 26/08/2009 v 22:23
zdroj uživatelem

hlasů
8

Zcela eliminuje if není reálné, a já si nemyslím, že je to, co Ori navrhuje. Ale oni mohou často být nahrazeny pomocí polymorfismus. (A proto může řada prohlášení switch).

Francesco Cirillo zahájila proti případě, že kampaň na zvýšení povědomí o této problematice. On říká:

Věděl, jak používat objekty umožňuje vývojářům odstranit investićní fondy na základě typu, ty, které nejčastěji ohrozit flexibilitu softwaru a schopnost vyvíjet.

Vy nebo váš tým může také připojit ke kampani .

Odpovězeno 26/08/2009 v 22:33
zdroj uživatelem

hlasů
8

Ano, je to pravda, že často složité podmiňovací způsob může být zjednodušena s polymorphishm. Ale není vhodné po celou dobu. Go číst Fowler Refactoring knihu, aby získali představu o tom, kdy.

http://www.refactoring.com/catalog/replaceConditionalWithPolymorphism.html

Odpovězeno 26/08/2009 v 22:30
zdroj uživatelem

hlasů
6

Jeden z mých učitel říkával, že. Mám tendenci si myslet, že lidé jsou tak dogmatický o takové věci obvykle nemají program pro bydlení.

Odpovězeno 26/08/2009 v 23:05
zdroj uživatelem

hlasů
5

Vyhnout if: Existuje mnoho způsobů, jak, jeden z nich je níže:

int i=0;
if(i==1)
{
//Statement1
}

if(i==2)
{
//Statement2
}

if(i==3)
{
//Statement3
}

if(i==4)
{
//Statement4
}

Použitím slovníku a delegát:

delegate void GetStatement ();

Dictionary<int,GetStatement > valuesDic=new Dictionary<int,GetStatement >();

void GetStatement1()
{
//Statement1
}
void GetStatement2()
{
//Statement2
}
void GetStatement3()
{
//Statement3
}


void GetStatement4()
{
//Statement4
}

void LoadValues()
{
valuesDic.Add(1,GetStatement1);
valuesDic.Add(2,GetStatement2);
valuesDic.Add(3,GetStatement3);
valuesDic.Add(4,GetStatement4);

}

Výměna Pokud prohlášení:

int i=0;
valuesDic[i].Invoke();
Odpovězeno 15/04/2012 v 16:47
zdroj uživatelem

hlasů
5

Podívejte se na Anti-případě, že kampaň Cílem není nahradit každý-li ve vaší aplikaci se strategickým nebo státní vzor. Myšlenka je, že když máte složitou logiku větvení zejména na základě něčeho takového výčtu, měli byste se podívat do refaktorování na strategický vzor.

A tento případ můžete-li vše dohromady odstranit pomocí Factory. Zde je poměrně jednoduchý příklad. Samozřejmě, jak jsem uvedl v reálném případě, logika ve svých strategiích by být o něco složitější, než jen tisk „Jsem Active“.

public enum WorkflowState
{
  Ready,
  Active,
  Complete
}

public interface IWorkflowStrategy
{
  void Execute();
}

public class ActiveWorkflowStrategy:IWorkflowStrategy
{
  public void Execute()
  {
    Console.WriteLine("The Workflow is Active");
  }
}

public class ReadyWorkflowStrategy:IWorkflowStrategy
{
  public void Execute()
  {
    Console.WriteLine("The Workflow is Ready");
  }
}

public class CompleteWorkflowStrategy:IWorkflowStrategy
{
  public void Execute()
  {
    Console.WriteLine("The Workflow is Complete");
  }
}

public class WorkflowStrategyFactory
{
  private static Dictionary<WorkflowState, IWorkflowStrategy> _Strategies= 
    new Dictionary<WorkflowState, IWorkflowStrategy>();
  public WorkflowStrategyFactory()
  {
    _Strategies[WorkflowState.Ready]=new ReadyWorkflowStrategy();
    _Strategies[WorkflowState.Active]= new ActiveWorkflowStrategy();
    _Strategies[WorkflowState.Complete = new CompleteWorkflowStrategy();
  }
  public IWorkflowStrategy GetStrategy(WorkflowState state)
  {
    return _Strategies[state];
  }
}

public class Workflow
{
    public Workflow(WorkflowState state)
    {
        CurrentState = state;
    }
    public WorkflowState CurrentState { get; set; }
}

public class WorkflowEngine
{
    static void Main(string[] args)
    {
        var factory = new WorkflowStrategyFactory();
        var workflows =
            new List<Workflow>
                {
                    new Workflow(WorkflowState.Active),
                    new Workflow(WorkflowState.Complete),
                    new Workflow(WorkflowState.Ready)
                };
        foreach (var workflow in workflows)
        {
            factory.GetStrategy(workflow.CurrentState).
                Execute();
        }
    }
}   
Odpovězeno 26/08/2009 v 23:08
zdroj uživatelem

hlasů
4

Do jisté míry to může být dobrý nápad. Swiching na typu pole uvnitř objektu je obvykle dobrý nápad, když můžete použít virtuální functtions místo. Ale virtuální funkce mechanismus v žádném případě nahradit if () test obecně.

Odpovězeno 26/08/2009 v 22:27
zdroj uživatelem

hlasů
3

V odpovědi na iftrue otázku:

No, pokud máte otevřené třídy a dostatečně silný závislý typový systém, je to jednoduché, i když trochu hloupé. Neformálně a v žádném konkrétním jazyce:

class Nat {
    def cond = {
        print this;
        return this;
    }
}

class NatLessThan<5:Nat> { // subclass of Nat
    override cond = {
        return 0;
    }
}

x = x.cond();

(Pokračování ...)

Nebo, bez otevřených tříd, ale za předpokladu, že vícenásobné odesílání a anonymní třídy:

class MyCondFunctor {
    function branch(Nat n) {
        print n;
        return n;
    }

    function branch(n:NatLessThan<5:Nat>) {
        return 0;
    }
}

x = new MyCondFunctor.branch(x);

Nebo, jako předtím, ale s anonymních tříd:

x = new {
    function branch(Nat n) {
        print n;
        return n;
    }

    function branch(n:NatLessThan<5:Nat>) {
        return 0;
    }
}.branch(x);

Budeš mít mnohem větší šanci, když se refactored, že logika, samozřejmě. Nezapomeňte, že existují zcela Turing-kompletní typu systémů.

Odpovězeno 26/08/2009 v 22:44
zdroj uživatelem

hlasů
3

Záleží na tom, co je původní prohlášení je porovnávání. Moje pravidlo je, že pokud je to switchči iftestování rovnost před výčtu, pak je to dobrý kandidát na samostatné metody. Nicméně, switcha ifpříkazy jsou používány pro mnoho, mnoho dalších druhů testů - není dobrý způsob, jak nahradit relační operátory ( <, >, <=, >=) se specializovanými metodami, a některé druhy vyjmenovaných testech pracovat mnohem lépe se standardními výkazů.

Takže byste měli vyměnit pouze ifů v případě, že vypadá takto:

if (obj.Name == "foo" || obj.Name == "bar") { obj.DoSomething(); }
else if (obj.Name == "baz") { obj.DoSomethingElse(); }
else { obj.DoDefault(); }
Odpovězeno 26/08/2009 v 22:28
zdroj uživatelem

hlasů
3

Jak se rozhodnout, který objekt je metoda používat bez if?

Odpovězeno 26/08/2009 v 22:23
zdroj uživatelem

hlasů
2
Assume we have conditional values.

public void testMe(int i){

if(i=1){
somevalue=value1;
}


if(i=2){
 somevalue=value2;
}

if(i=3){
somevalue=value3;
}

}

//**$$$$$you can replace the boring IF blocks with Map.$$$$$**

// ================================================ ============

Same method would look like this:
--------------------------------
public void testMe(int i){

Map<Integer,String> map = new HashMap<Integer,String>();

map.put(1,value1);
map.put(2,value2);
map.put(3,value3);

}
This will avoid the complicated if conditions.

Můžete použít simliar řešení při použití standardního vzorů pro načítání tříd.

public void loadAnimalsKingdom(String animalKingdomType)
    if(animalKingdomType="bird"){
    Bird b = new Bird();
    }
    if(animalKingdomType="animal"){
    Animal a= new Animal();
    }
    if(animalKingdomType="reptile"){
    Reptile r= new Reptile();
    }
  }

Nyní pomocí mapy:

   public void loadAnimalsKingdom(String animalKingdomType)
    {
       Map <String,String> map = new HashMap<String,String>();

       map.put("bird","com.animalworld.Bird.Class");
       map.put("animal","com.animalworld.Animal.Class");
       map.put("reptile","com.animalworld.Reptile.Class");

       map.get(animalKingdomType);

***Use class loader to load the classes on demand once you extract the required class from the map.***
}

Jako řešení? Dej nezkazila. - Vv

Odpovězeno 28/07/2017 v 06:04
zdroj uživatelem

hlasů
2

Vytvoření zcela novou třídu, zda není else, zatímco technicky proveditelné, by pravděpodobně za následek kódu, který je těžko čitelné, udržovat nebo dokonce ukázat správný.

Odpovězeno 26/08/2009 v 22:24
zdroj uživatelem

hlasů
1

Myslím, že to, co se říká, nebo co znamená říci, je, že si myslí, že je nejlepší, aby se zabránilo nadměrnému zneužívání „značkování“ a přidávat vlastní funkce na třídu několika if, kdy lepší smysl podtřídy nebo přehodnotit objekt hierarchie.

Odpovězeno 26/08/2009 v 22:26
zdroj uživatelem

hlasů
1

To je zajímavý nápad. Myslím, že byste mohli teoreticky to udělat, ale to by byla obrovská bolest v jazyce, které nejsou specificky navržen tak, aby jej podporují. Já rozhodně nevidím žádný důvod, proč.

Odpovězeno 26/08/2009 v 22:24
zdroj uživatelem

hlasů
0

Musíte pochopit, co (x > 5)vlastně znamenají. Za předpokladu, že xje číslo, pak to v podstatě „klasifikuje“ všechna čísla větší než pět. Takže kód bude vypadat takto v jazyce s syntaxe python:

class Number(Object):

    # ... Number implementation code ... #

    def doSomething():
        self = 0
        return self

    def doSomethingElse():
        pass

class GreaterThan5(Number):
    def doSomething():
        print "I am " + self

    def doSomethingElse():
        print "I like turtles!"

Pak bychom mohli spustit kód, jako je následující:

>>> type(3)
<class Number>
>>> type(3+3)
<class GreaterThan5>
>>> 3.doSomething()
0
>>> (3 + 3).doSomething()
I am 6
>>> (7 - 3).doSomethingElse()
>>>

Automatický typ konverze je zde důležitá. Pokud je mi známo, žádný z jazyků dnes vám umožní, aby si s celými čísly tolik.

Na konci, můžete tak učinit v kódu cokoliv. Tak dlouho, jak lidé to čtou mohou okamžitě pochopit. Takže polymorfní expedice na celá čísla nebo něco nad rámec běžného musí mít opravdu dobrý úvahy za ním.

Odpovězeno 28/01/2018 v 03:02
zdroj uživatelem

hlasů
0

Souhlasím s Vance, že IF není dobrá, protože zvyšuje podmíněnou složitost a je třeba se vyhnout, jak je to možné.

Polymorfismus je úplně schůdné řešení na stavu, ve kterém je použita, aby rozum a ne na „vyhnout, pokud“.

Boční poznámka, který se nevejde do vašich požadavků OOP ale orientovaný přístup dat má také tendenci vyhnout větvení .

Odpovězeno 06/09/2017 v 10:28
zdroj uživatelem

hlasů
0

Mí dva bity tady z toho, co vím o přístupu objektově orientovaného -

Za prvé, jaké objekty v rámci programu by mělo být intuitivní. To znamená, že bych neměl snažit vytvořit třídu ‚Arithmatic‘ poskytovat matematických funkcí. Jedná se o zneužití OOD.

Druhým, a to je velmi silný názor dolu. Nemělo by to být nazýván objektově orientovaného designu, ale objekt a Method orientovaný design! Pokud jsou samy názvy metoda objektů není intuitivní pak zděděné objekty by mohly skončit reimplementing metody jsou již k dispozici.

Objektově orientovaný přístup, podle mne, není náhradou za procesního přístupu. Spíše je to hlavně ze dvou hlavních důvodů, proč tvůrci jazyka -

  1. Lepší schopnost scoping proměnných.

  2. Lepší schopnost sběru odpadků, spíše než mít příliš mnoho globální proměnné.

Odpovězeno 26/09/2009 v 14:19
zdroj uživatelem

hlasů
0

Sledoval jsem anti-li to talk v poslední době, a to znít jako extrémní / hyperbolické rétoriky ke mně. Nicméně si myslím, že je to pravda v tomto prohlášení: často logika příkazu if může být více vhodně realizována prostřednictvím polymorfismus. Myslím, že je dobré mít na paměti, že pokaždé, když kliknete pravým if. Jak již bylo řečeno, myslím, že v případě prohlášení je stále logická struktura jádra, a neměl by se obávat ani vyhnout jako princip.

Odpovězeno 26/08/2009 v 23:01
zdroj uživatelem

hlasů
0

If-výroky jsou dost core programování tak, stručně řečeno, nelze rozumně se jim vyhnout.

Nicméně, jedním z hlavních cílů v OOP - ve skutečnosti, jeden z „pilířů“ - je zapouzdření. Starý „zapouzdřit, co se pohybuje“ pravidlo pomůže odstranit ty problematické, zda a případové prohlášení, kde se snažíte k účtu pro každou možnost ve svém objektu. Lepším řešením pro zacházení s pobočkami, speciální případy, atd je použít něco jako „tovární“ návrhový vzor (Abstract Factory nebo Factory Method - v závislosti na potřebách, samozřejmě).

Například, spíše než mít své hlavní kontrolní kód smyčky, která OS vaše použití s ​​if pak větví vytvořit GUI okna s různými možnostmi pro každý operační systém, váš hlavní kód by vytvořit objekt z továrny, které používají operační systém určit, jaký operační systém -specifické konkrétní objekt dělat. Přitom užíváte varianty (a dlouho if-then-else doložky) z vašeho hlavního kódu smyčky a nechal podřízené objekty s ní zacházet - Takže až se příště budete muset provést změnu, jako je podporovat nový OS , pouze přidat novou třídu z továrny rozhraní.

Odpovězeno 26/08/2009 v 22:41
zdroj uživatelem

hlasů
0

Řeknu, že odpověď je ano nejasně-ish. Zvlášť, když se jazyk umožňuje určitou heavy duty funkcionální programování (tj C #, F #, OCaml).

Komponenta, která obsahuje 2, pokud tak výroky silně páry dva obchodní pravidla tím skonči.

Brát jako velmi obecné pravidlo, ale já bych souhlasit. Pokud máte spoustu if, možná byste měli uvažovat o jiném přístupu.

Odpovězeno 26/08/2009 v 22:40
zdroj uživatelem

hlasů
0

Myslím, že použití tohoto argumentu s myšlenkou každé if je docela extrémní, ale některé jazyky vám možnost uplatnit tuto myšlenku v určitých situacích.

Zde je ukázka implementace Python jsem napsal v minulosti za pevnou velikostí deque (double-ended fronty). Namísto vytváření metodu „Odebrat“ a má-li příkazy uvnitř ní, zda je seznam plný, nebo ne, stačí jen vytvořit dvě metody a přiřadit je do funkce „odstranit“, jak je potřeba.

Následující příklad uvádí pouze metoda „odstranit“, ale samozřejmě existují „připojit“ metody a podobně také.

class StaticDeque(collections.deque):

    def __init__(self, maxSize):

        collections.deque.__init__(self)
        self._maxSize = int(maxSize)
        self._setNotFull()

    def _setFull(self):

        self._full = True
        self.remove = self._full_remove

    def _setNotFull(self):

        self._full = False
        self.remove = self._not_full_remove

    def _not_full_remove(self,value):

        collections.deque.remove(self,value)

    def _full_remove(self,value):

        collections.deque.remove(self,value)
        if len(self) != self._maxSize and self._full:
            self._setNotFull()

Ve většině případů to není tak užitečné nápadu, ale někdy to může být užitečné.

Odpovězeno 26/08/2009 v 22:28
zdroj uživatelem

hlasů
0

Určitě nějaká forma porovnání je třeba provést bez ohledu na to, co děláte? Na konci ... že můžete vyhnout, pokud závěrce, ale budeš výrobu kód, který je shodný s kódem pomocí if.

Někdo se mě, jestli im špatně opravit, ale nemůžu myslet na dobu, kdy jste mohli dostat nějakou formu win dělá.

Odpovězeno 26/08/2009 v 22:24
zdroj uživatelem

hlasů
0

Je to docela extrémní. Dělat to, co navrhujete, by způsobit mnoho zbytečných kódu duplikace, pokud celá funkce byla úplně jiná, na základě jediné okolní pokud; a pokud ano, že pokud by se pravděpodobně byli na druhé straně volání metody.

If-výroky rozhodně mají své místo v objektově-orientální design.

Odpovězeno 26/08/2009 v 22:24
zdroj uživatelem

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more