Ways to eliminate switch in code [closed]

2018-12-31 18:08发布

What are the ways to eliminate the use of switch in code?

23条回答
与风俱净
2楼-- · 2018-12-31 18:55

Use a language that doesn't come with a built-in switch statement. Perl 5 comes to mind.

Seriously though, why would you want to avoid it? And if you have good reason to avoid it, why not simply avoid it then?

查看更多
永恒的永恒
3楼-- · 2018-12-31 18:57

Switch in itself isn't that bad, but if you have lots of "switch" or "if/else" on objects in your methods it may be a sign that your design is a bit "procedural" and that your objects are just value buckets. Move the logic to your objects, invoke a method on your objects and let them decide how to respond instead.

查看更多
泛滥B
4楼-- · 2018-12-31 18:58

For C++

If you are referring to ie an AbstractFactory I think that a registerCreatorFunc(..) method usually is better than requiring to add a case for each and every "new" statement that is needed. Then letting all classes create and register a creatorFunction(..) which can be easy implemented with a macro (if I dare to mention). I believe this is a common approach many framework do. I first saw it in ET++ and I think many frameworks that require a DECL and IMPL macro uses it.

查看更多
浪荡孟婆
5楼-- · 2018-12-31 18:59

I think that what you are looking for is the Strategy Pattern.

This can be implemented in a number of ways, which have been mentionned in other answers to this question, such as:

  • A map of values -> functions
  • Polymorphism. (the sub-type of an object will decide how it handles a specific process).
  • First class functions.
查看更多
其实,你不懂
6楼-- · 2018-12-31 19:01

if-else

I refute the premise that switch is inherently bad though.

查看更多
笑指拈花
7楼-- · 2018-12-31 19:03

See the Switch Statements Smell:

Typically, similar switch statements are scattered throughout a program. If you add or remove a clause in one switch, you often have to find and repair the others too.

Both Refactoring and Refactoring to Patterns have approaches to resolve this.

If your (pseudo) code looks like:

class RequestHandler {

    public void handleRequest(int action) {
        switch(action) {
            case LOGIN:
                doLogin();
                break;
            case LOGOUT:
                doLogout();
                break;
            case QUERY:
               doQuery();
               break;
        }
    }
}

This code violates the Open Closed Principle and is fragile to every new type of action code that comes along. To remedy this you could introduce a 'Command' object:

interface Command {
    public void execute();
}

class LoginCommand implements Command {
    public void execute() {
        // do what doLogin() used to do
    }
}

class RequestHandler {
    private Map<Integer, Command> commandMap; // injected in, or obtained from a factory
    public void handleRequest(int action) {
        Command command = commandMap.get(action);
        command.execute();
    }
}

If your (pseudo) code looks like:

class House {
    private int state;

    public void enter() {
        switch (state) {
            case INSIDE:
                throw new Exception("Cannot enter. Already inside");
            case OUTSIDE:
                 state = INSIDE;
                 ...
                 break;
         }
    }
    public void exit() {
        switch (state) {
            case INSIDE:
                state = OUTSIDE;
                ...
                break;
            case OUTSIDE:
                throw new Exception("Cannot leave. Already outside");
        }
    }

Then you could introduce a 'State' object.

// Throw exceptions unless the behavior is overriden by subclasses
abstract class HouseState {
    public HouseState enter() {
        throw new Exception("Cannot enter");
    }
    public HouseState leave() {
        throw new Exception("Cannot leave");
    }
}

class Inside extends HouseState {
    public HouseState leave() {
        return new Outside();
    }
}

class Outside extends HouseState {
    public HouseState enter() {
        return new Inside();
    }
}

class House {
    private HouseState state;
    public void enter() {
        this.state = this.state.enter();
    }
    public void leave() {
        this.state = this.state.leave();
    }
}

Hope this helps.

查看更多
登录 后发表回答