开发者

How to avoid if... else and switch cases

I have been programming for alot of time. Generally i program in some languages like PHP, ASP.net, Java, JavaScript and others. In all languages i have to use alot of if else statments . Like if value= 10 then ... if i review my code then i find alot of if conditions. So i would like to minimise them but how not sure.

one point was using classes somewhat minimised but still they are more...

like task, cat, sec and type:

if task = 'add' then
   if cat = "animal" then
      if sec = "man" then
          if type = "male" then
                 'do the following stuffs
          else
                 'do the following stuffs
          end if
      elseif sec = "horse" then
          if type = "run"
                 'do the following stuffs
          else
                 'do the following stuffs
          end if
      elseif....
      end if
   elseif cat = "plant" then
     if sec = "land" then
          if type="tree" then
                 'do the following stuffs
          elseif type = "grass" then..
    开发者_运维知识库             'do the following stuffs
          elseif...
          end if
    elseif sec = "water" then
    ...
...

...

more n more continue n continue

so wonder how can i minimise them and write some efficient codes?

Sorry to inform lately that there may be alot of values for task, cat, sec, and type. My if statements are going nested n nested.

More explanatory my code also looks like same as :

http://thedailywtf.com/Articles/Coding-Like-the-Tour-de-France.aspx


Many if..else statements is often a symptom the Polymorphism is not being used.


It's called 'Arrow Antipattern' Some of the methods of dealing with it are described here: http://c2.com/cgi/wiki?ArrowAntiPattern

One of the ways you migt consider, is to refactor code in nested levels to separate functions like

if cat = "animal" then
  functionForAnimal();
elseif cat = "plant" then
 functionForPlant();
elseif...


function functionForAnimal() 
  if sec = "man" then
    functionForMan();
  elseif sec = "horse" then
    functionForHorse();
  elseif...

etc...

This splits code into smaller fragments which are easier to maintain, and possibly reusable.


Assuming you're always doing equality comparisons, and comparing all four fields, a simple data-driven approach is quite practical. All you need to do is construct a map from (task, cat, sec, type) to a function to call:

handlers = {
    ('add', 'animal', 'man', 'male'): add_man_func,
    ('add', 'animal', 'horse', 'run'): run_horse_func,
    # ...
}

handler = handlers[(task, cat, sec, type)]
handler(some_args)


Polymorphism might be useful when you have different implementations but the task is conceptually the same. Sometimes it's hard to find a natural class structure, and approaches like the state pattern or the strategy pattern might be more appropriate.


You described a matrix with 4 incoming parameters - task, cat, sec, type and one outgoing - stuff. So you have to code it someway.

For example, XML map and an XPath query, i.e. String.Format("task[@value={0}]/cat[@value={1}]/sec[@value={2}]/type[@value={3}]", "add", "animal", "man", "male") but this approach points to a data, not a method delegate.

Another way:

void DoStuffA() { }
void DoStuffB() { }

var arr = new[]
{
    new { Task = "Add", Cat = "Animal", Sec = "Man", Type = "Male", Method = (Action)DoStuffA },
    new { Task = "Add", Cat = "Plant", Sec = "Land", Type = "Tree", Method = (Action)DoStuffB },
    // etc..
};

var action = arr.FirstOrDefault(i =>
     i.Task == "Add" &&
     i.Cat == "Animal" &&
     i.Type == "Male").Method;
action();

Also you can use not anonymous members but declare a class, describe your variants in XML and deserialize them from XML to a number of your class instances.


I think there are some fundamental flaws in your design. I don't know what problem you are trying to solve with this code, but such code should be very rare in an object oriented language. Your code also seems a bit illogical to me, because, for example, the variable type means gender the first time it's used (male) and then it means an action (run). Have you noticed this?

Anyway, if you're indeed using Java (or anything with classes), what you need is abstraction. Next, move all logic you can to your objects -- don't handle it in one monstrous routine. Think this way: my objects know how to do their part.

Actually it's a bit difficult to give good advice in this situation, I suspect your problems have source on some high level in your application and this case code is only a symptom. Try to redesign your program to use object-oriented approach and perhaps a better solution will come to your mind as you go.

If you're not sure what polymorphism, abstraction and other OO terms mean, you will need to read up on this.


If choices for each of those variables are finite, then you can even use tricks like bit fields with OR operation.

Example:

// give each field a byte so that each can have 256 possible values
#define TASK_ADD 0x01
#define TASK_SUB 0x02
...
#define CAT_ANIMAL 0x01
...
#define SEC_BOY 0x03
#define SEC_MAN 0x04
...
#define TYPE_FEMALE 0x01
#define TYPE_MALE 0x02
...

if ((task << 24 | cat << 16 | sec << 8 | type) == 0x01010402) {
  // do stuff
}


Somewhere you will need to check the conditions with if-elses, to make sure you do the right thing. You could create new subs if you don't want to cram one sub

Sub AddAnimalManMale()
    If task = 'add' And cat = 'animal' And sec = 'man' And type = 'male' Then
        'perform the add animal man male action'
    End If
End Sub
Sub AddAnimalHorseRun()
    If task = 'add' And cat = 'animal' And sec = 'horse' And type = 'run' Then
        'perform the add animal horse run action'
    End If
End Sub

then in your main sub

...
Call AddAnimalManMale()
Call AddAnimalHorseRun()
...


Breaking the code up is all what the game is about.

Historically you would do (and there had been good, or at least stable code, and still there is in all of these)

  • as you are doing it now, monolithic in huge functions, with lots of comments

  • split it into small well defined and well named functions

  • naming functions was tricky for complex stuff and also if you keep on passing references to big structures then objects were a natural thing to invent (however, once you go object way then it makes sense to do everything and through reusing the code object oriented patterns emerge... )

Recognizing the patterns is in a way similar to giving good names to functions (plus you get naturally useful methods thrown in, which can be huge win).

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜