Policy mode, refactoring if-else

Posted by behzad on Sun, 04 Aug 2019 05:40:11 +0200

Recently completed the development of our company's public number. WeChat's message routing was judged by if-else at the beginning. The more if-else messages written in the following month, the more confused.Check the solution on the web, and if there are a lot of dry goods, the most classic and concise way to feel is to use the strategy mode to reconstruct too many if-else choices.

First let's create a new interface

public interface InnerCommand {
    void process(String msg);
}

Then extract each if logic into a class separately, such as

/**
 * @author lee.
 * @date 2019/5/24 15:53
 */
@Service
public class PrintAdminCommand implements InnerCommand {
    @Override
    public void process(String msg) {
        System.out.println("PrintAdminCommand");
    }
}

Not all of them are listed here.

* Then we'll create a new enum CommonCode here

/**
 * @author lee.
 * @date 2019/5/24 15:51
 */
public enum CommonCode {

    USER("user", "user", "com.yumstone.invoiceapply.Command.impl.PrintUserCommand"),
    ADMIN("admin", "Administrators", "com.yumstone.invoiceapply.Command.impl.PrintAdminCommand");
    private String code;
    private String desc;
    private String clazz;
    private static final Map<String, String> classes = new HashMap<String, String>();

    static {
        for (CommonCode refer : CommonCode.values()) {
            classes.put(refer.getCode(), refer.getClazz());
        }
    }

     CommonCode(String code, String desc, String clazz) {
        this.code = code;
        this.desc = desc;
        this.clazz = clazz;
    }

    public static Map<String, String> getAllClazz() {
        return classes;
    }
    public static String getDescByCode(int code) {
        return classes.get(code);
    }
    public String getCode() {
        return code;
    }
    public void setCode(String code) {
        this.code = code;
    }
    public String getDesc() {
        return desc;
    }
    public void setDesc(String desc) {
        this.desc = desc;
    }
    public String getClazz() {
        return clazz;
    }
    public void setClazz(String clazz) {
        this.clazz = clazz;
    }
}

Here we can see that a static block of code in an enumerated class loads the class and its corresponding code into memory at the beginning of the program execution.

Then we create a new component to handle getting different processing classes based on different code s.

/**
 * @author lee.
 * @date 2019/5/24 15:59
 */
@Component
public class InnerCommandContext {
    @Autowired
    ApplicationContext applicationContext;

    public InnerCommand getInstance(String command) {
        //getAllClazz
        Map<String, String> allClazz = CommonCode.getAllClazz();
        String clazz = allClazz.get(command);
        InnerCommand innerCommand = null;
        try {
            if (clazz==null||clazz.length()==0) {
                clazz = PrintAdminCommand.class.getName() ;
            }
            innerCommand = (InnerCommand)applicationContext.getBean(Class.forName(clazz));
        } catch (Exception e) {
            e.printStackTrace();
        }
        return innerCommand;
    }
}

Here we can see that the obtained classes are found by reflection in the spring container.Now that we're ready, we're done with the final logical part.

/**
 * @author lee.
 * @date 2019/5/24 16:06
 */
@RestController
public class TextController {
    @Autowired
    InnerCommandContext innerCommandContext;
    @RequestMapping("text")
    public String test(@RequestParam String name){
        InnerCommand innerCommand = innerCommandContext.getInstance(name);
        innerCommand.process(name);
        return "ok" ;
    }
}

Is it particularly concise? Many if-else judgments may now be optimized to two lines of code

  InnerCommand innerCommand = innerCommandContext.getInstance(name);
  innerCommand.process(name);
The summary program loads the class names of all the logical classes into memory at startup, finds the required types through code, builds them through reflection, and finally executes the business that needs to be processed. Only one new logic needs to be added

The implementation class of InnerCommand is added to the enumeration class.It can then be obtained from this type of code.

Topics: PHP Spring