Design Patterns | if / else and you say how can I break up

if和else的难解难分

       The actual programming, we always need a lot of logic to determine what to do to help us in various branches, no matter how kind if and else needs to help us solve the thing? The answer is not necessarily, for java, design patterns is to better package, decoupling, cohesion, for a complex system, there is a greater need to support design patterns, or strenuous and time-consuming maintenance, we will only the body underrun, the following is a summary of some bloggers clever way to reduce if and else.

应用场景
Here Insert Picture Description

       A car networking project, will receive different packets of various types, a variety of data about the car, such as driving motor data, engine data, vehicle location data (GPS), alarm data packets, for which we It defines an enumeration to represent different types of data packets:

枚举

       Message enumeration MsgTypeEnum

public enum MsgTypeEnum {
    /**
     * 驱动电机数据
     */
    DRIVE_MOTOR,
    /**
     * 发动机数据
     */
    ENGINE,
    /**
     * 车辆位置数据
     */
    VEHICLE_POSITION,
    /**
     * 报警数据
     */
    ALARM
}

       Decoding the message class MsgDecoder

  public class MsgDecoder {
    /**
     * 解码消息体
     * @param msgTypeEnum 消息类型
     * @return 协议具体类型
     */
    public String decodeMsg(MsgTypeEnum msgTypeEnum) {
        //开始解析并存储消息
        switch (msgTypeEnum) {
            case DRIVE_MOTOR:
                return "驱动电机数据";
            case ENGINE:
                return "发动机数据";
            case VEHICLE_POSITION:
                return "车辆位置数据";
            case ALARM:
                return "报警数据";
            default:
                return null;
        }
    }

       You can see the code is very clean and Kazakhstan (self-recognition under), it was said replaced if and else is the same, yes, the same, no different, code is also very refreshing, but this is just an ordinary four types of decoding If he's the kind of message do as many as 10 or more, the code Luo together, is not it more "refreshing" of? We know that a lot of car parts, totally there are a lot of kind of messages to describe them, for which we use this method to improve enumeration.

       Public interface class Decoder

public interface Decoder {
    /**
     * 解码方法
     */
    String decode();
}

       The improved enum class MsgTypeEnum

public enum MsgTypeEnum implements Decoder {
    /**
     * 驱动电机数据
     */
    DRIVE_MOTOR{
        @Override
        public String decode() {
            return "驱动电机数据";
        }
    },
    /**
     * 发动机数据
     */
    ENGINE{
        @Override
        public String decode() {
            return "发动机数据";
        }
    },
    /**
     * 车辆位置数据
     */
    VEHICLE_POSITION{
        @Override
        public String decode() {
            return "车辆位置数据";
        }
    },
    /**
     * 报警数据
     */
    ALARM{
        @Override
        public String decode() {
            return "报警数据";
        }
    }
}

       The improved enum class MsgDecoder

public class MsgDecoder {
    /**
     * 解码消息体
     * @param msgTypeEnum 消息类型
     * @return 协议具体类型
     */
    public String decodeMsg(MsgTypeEnum msgTypeEnum) {
        return MsgTypeEnum.valueOf(msgTypeEnum.toString()).decode();
    }
}

       DETAILED service code can be seen to have achieved the improved class enumeration message MsgTypeEnum, decoded only category MsgDecoder valueOf enumerations in the method on the "Auto" is a determination of the type, but this does reduce a class MsgDecoder pressure, switch / case (if / else) also said broke up, but the message enumeration MsgTypeEnum will become bloated, if the post-decoding messages species increased, a class why be tolerant to diversity? So enumeration method is not suitable, but less kind of judgment, or recommended, after all, the enumeration is "the final class," and other classes have not the same nature, he would be more efficient to use than the other classes.

       Since the enumeration still does not fit, is there any way to do it, let's look at how to transform the factory design pattern is the above method:

工厂模式

       Public interface class Decoder

public interface Decoder {
    /**
     * 解码方法
     */
    String decode();
}

       Message enumeration MsgTypeEnum

public enum MsgTypeEnum {
    /**
     * 驱动电机数据
     */
    DRIVE_MOTOR,
    /**
     * 发动机数据
     */
    ENGINE,
    /**
     * 车辆位置数据
     */
    VEHICLE_POSITION,
    /**
     * 报警数据
     */
    ALARM
}

       Various message types (for convenience of explanation, it is listed together, actually four classes)

//报警数据
public class Alarm implements Decoder {
    @Override
    public String decode() {
        return "报警数据";
    }
}
//驱动电机数据
public class DeviceMotor implements Decoder {
    @Override
    public String decode() {
        return "驱动电机数据";
    }
}
//发动机数据
public class Engine implements Decoder {
    @Override
    public String decode() {
        return "发动机数据";
    }
}
//车辆位置数据
public class VehiclePosition implements Decoder {
    @Override
    public String decode() {
        return "车辆位置数据";
    }
}

       Message Type factory

public class MsgTypeFactory {
    /**
     * 消息种类的容器
     */
    private final static Map<String,Decoder> msgTypeMap = new HashMap<>(4);
    static {
        msgTypeMap.put(MsgTypeEnum.VEHICLE_POSITION.toString(),new VehiclePosition());
        msgTypeMap.put(MsgTypeEnum.ALARM.toString(),new Alarm());
        msgTypeMap.put(MsgTypeEnum.DRIVE_MOTOR.toString(),new DeviceMotor());
        msgTypeMap.put(MsgTypeEnum.ENGINE.toString(),new Engine());
    }

    /**
     * 获取对应的解码器
     * @param msgType 消息类型
     * @return 解码器
     */
    public static Decoder getDecoder(String msgType){
        return msgTypeMap.get(msgType);
    }
}

       The improved enum class MsgDecoder

public class MsgDecoder {
    /**
     * 解码消息体
     * @param msgTypeEnum 消息类型
     * @return 协议具体类型
     */
    public String decodeMsg(MsgTypeEnum msgTypeEnum) {
        return MsgTypeFactory.getDecoder(msgTypeEnum.toString()).decode();
    }
}

       As can be seen from the factory model, we can put a good problem to the provisions of a particular class, and also switch / case (if / else) break up, but to mention a mouth that is, an increase in the class, a few initialization decoded and stored in a map inside, object initialization are several relatively small objects, but also often use, advance new decoding speed can be increased without new provisional decoding temporary, use of design patterns, it is relatively becomes more design pattern from another, it is "split", the code for a large, heavy split into a separate class, but closely linked.

       In fact, the plant is divided into three (simple factory, factory method abstract factory) is the difference between them is handed over to a simple factory class to create objects to the client, the factory method and abstract factory were handed over to their specific child to be achieved class object is created, but the factory method and abstract factory by different focus, focus on the factory method abstract methods, abstract factory focuses on the abstract factory (class). In short factories belong creational design patterns, belongs to a design pattern on the creation and use of objects , the factory model of this paper are simple factory upgraded version of the ordinary simple factory pattern, after entering the factory class will Depending on the type and then determine the corresponding new objects, but this paper is loaded in advance on a good, good judgment directly after the return of the object of frequent decoding process, is there a higher efficiency improvement.

策略模式

       Decoder class public interface, a variety of message types (for convenience of explanation, it is listed together, actually four classes) code and the same plant, but also to achieve the same interfaces Decodor

       DecodeContext unified class

public class DecodeContext {
    private Decoder decoder;

    public DecodeContext(Decoder decoder) {
        this.decoder = decoder;
    }

    public String decode(){
        return decoder.decode();
    }
}

       The client uses StrategyTest:

public class StrategyTest {
    public static  void main(String []args){
        DecodeContext decodeContext = new DecodeContext(new VehiclePosition());
        System.out.println(decodeContext.decode());
    }

}

       It can be seen policy model is to define a series of algorithms, each algorithm package, and make them interchangeable. Strategy mode allows the algorithm to use it independently of the client

总结

       Careful readers may find, in fact, there is no reduction strategy pattern if and else, the client will need a new corresponding objects before entering each policy, you still need logic to determine if and else, then we could take the logical decision transfer to a class of it, further reducing their degree of coupling (plant) does, in fact in the middle of variants factory model is the strategy + binding factory, which he judged transferred to a class, but by the get method map directly offset if and else.

Released eight original articles · won praise 5 · Views 693

Guess you like

Origin blog.csdn.net/xianghe_qqq/article/details/104446840