Improvement strategy patterns for code optimization

preface

Are you still writing if-else? Are you still bothered by the if-else complexity and low readability? Strategy mode is relatively complex, simple logic using strategy and feel how to kill a chicken with a sword. Let’s take a look at strategic patterns and variations!

The strategy pattern

Definition: In a Strategy Pattern, the behavior or algorithm of a class can be changed at run time. This type of design pattern is behavioral. In the policy pattern, we create objects that represent various policies and a context object whose behavior changes as the policy object changes. The policy object changes the execution algorithm of the context object

Policy Pattern Class diagram (Generic class diagram) :

The interface and implementation of the policy should be well understood:

The interface of a policy is equivalent to the ResultSetHandler interface that defines the behavior of the policy we talked about above.

The concrete implementation is equivalent to the BeanHandler implementation we talked about above.

There are several other implementations, such as ListBeanHandler, MapBeanHandler, and so on

A lot of people who have questions ask. Why is there a context context, instead of just calling the policy?

Answer: more consistent with object-oriented, unified management. If the client interacts directly with the policy, the complexity increases. It’s like we go to the store instead of the factory. Increase complexity.

Without further ado, for example 🌰…………

Examples of Policy Patterns

How do you get on the hot list as a nuggets rookie? I have a lot of ways to document well; Please give a thumbs-up to the fan… And so on.

interface

** * @author * @version Id: IncreaseFansStrategy.java, V 0.1 2021/5/13 8:11 PM wuchaobo Exp $$*/ public interface IncreaseFansStrategy {void action(); }Copy the code

Specific strategy implementation (please water army, effort to write documents, etc.)

/** * @author * @version Id: NavyIHandler.java, V 0.1 2021/5/13 8:16 PM Exp $$*/ public implements IncreaseFansStrategy {@override public void IncreaseFansStrategy {@override public void IncreaseFansStrategy Println () {system.out.println (); }} /** * try to write the article * @version Id: greatHandler.java, V 0.1 2021/5/13 8:18 PM wuzhaobo Exp $$*/ public class GreatHandler implements IncreaseFansStrategy {@override public Void action() {system.out.println (" try to write the article "); }}......Copy the code

Strategy algorithm

/** * @author * @version Id: ResultHandler.java, V 0.1 2021/5/13 8:21 PM Exp $$*/ public class ResultHandler {private IncreaseFansStrategy IncreaseFansStrategy; public ResultHandler(IncreaseFansStrategy increaseFansStrategy){ this.increaseFansStrategy = increaseFansStrategy; } / / specific operation method of execution public void the exec () {increaseFansStrategy. The action (); }}Copy the code

The test class

/** * @author * @version Id: Class.java, V 0.1 2021/5/13 8:24 PM Exp $$*/ public class {public static void main(String[] args) {ResultHandler resultHandler = new ResultHandler(new NavyIHandler()); resultHandler.exec(); System.out.println(); System.out.println(); System.out.println(); System.out.println(); resultHandler = new ResultHandler(new GreatHandler()); resultHandler.exec(); }}Copy the code

Specific execution results

Ps: You will find that many classes need to be created if there are many policies implemented, which is relatively tedious and costly.

Conclusion:

  • Advantages:

    • Algorithms can be switched freely
      • A change of strategy is convenient
  • Good scalability

    • If you add one policy, you add one more class. (But also a disadvantage)
  • Disadvantages:

    • The number of policy classes increases
    • Each policy is a class, with a low likelihood of reuse and an increasing number of classes
    • All policy classes need to be exposed
    • The upper module must know which policies are available before it can decide which to use

. . . Therefore, it is difficult to use strategy mode in daily development. But complicated if-else is a headache, so most people choose to compromise. But here comes a new solution

Variant approach to policy pattern (Map+ functional interface)

Example 1: Do a simple policy check with string ()

public static void main(String[] args) { Map<String, Function<String, String>> checkResultDispatcherMuti = new HashMap<>(); CheckResultDispatcherMuti. Put (" check 1 ", the order - > String. The format (to perform business logic 1 "% s", the order)); CheckResultDispatcherMuti. Put (" check 2 ", the order - > String. The format (" execute the business logic for % s 2 ", the order)); CheckResultDispatcherMuti. Put (" three check ", the order - > String. The format (" execute the business logic for % s 3 ", the order)); CheckResultDispatcherMuti. Put (" check 4 ", the order - > String. The format (" execute the business logic for % s 4 ", the order)); CheckResultDispatcherMuti. Put (" check 5 ", the order - > String. The format (" execute the business logic for % s. 5 ", the order)); CheckResultDispatcherMuti. Put (" 6 "check, order - > String. The format (" execute the business logic for % s 6", the order)); Check (checkResultDispatcherMuti. Put (" 7 ", the order - > String. The format (to perform business logic 7 "% s", the order)); CheckResultDispatcherMuti. Put (" check 8 ", the order - > String. The format (" execute the business logic for % s 8 ", the order)); CheckResultDispatcherMuti. Put (9 "check", the order - > String. The format (" execute the business logic for % s 9 ", the order)); / / business logic code from logic dispatch of the Dispatcher, result variable is a lambda expression Function < String, the String > result = checkResultDispatcherMuti. Get (" three check "); if (result ! System.out.println(result.apply(" check3 ")); }else{system.out.println (" error "); }}Copy the code

Ps :(The general policy mode is class basic, which leads to too many classes and poor reusability. After the change, it is method level.)

/** * policy method * @version Id: Wuzhaobo Exp $$*/ public class TestHandler {Function<TestClass, TestClass> strategy1() { return test -> { TestClass test1 = new TestClass(); Test1. Elegantly-named setName (" zhang "); test1.setSex(test.getSex()); return test1; }; } public Function<TestClass, TestClass> strategy2() { return test -> { TestClass test1 = new TestClass(); test1.setName(test.getName()); test1.setSex("10"); return test1; }; }}Copy the code

Policy Entity Class

public class TestClass { private String name; private String sex; public String getName() { return name; } public String getSex() { return sex; } public void setName(String name) { this.name = name; } public void setSex(String sex) { this.sex = sex; }}Copy the code

Policy encapsulation method

Public static Map<String, Function< object, Object>> convert(Object object){ Map<String, Function<Object, Object>> implMap = new ConcurrentHashMap<>(); try{ java.lang.Class<? > aClass = object.getClass(); Method[] declaredMethods =aClass.getDeclaredMethods(); for (Method declaredMethod : declaredMethods) { String name = declaredMethod.getName(); If (name. Contains ("$")){system.out.println (1111); continue; } System.out.println(name); String str = name; declaredMethod.setAccessible(true); Function<Object, Object> invoke = (Function<Object, Object>) declaredmethod.invoke (Object); System.out.println("1231313"+invoke); implMap.put(str,invoke); } System.out.println(implMap); return implMap; }catch (Exception e){ throw new RuntimeException(e); }}Copy the code

The test class

public static void main(String[] args) throws InvocationTargetException, IllegalAccessException { Map<String, Function<Object, Object>> convert = ParamUtils.convert(new TestHandler()); Function<Object, Object> strategy2 = (Function<Object, Object>) convert.get("strategy2"); System.out.println(strategy2); TestClass testClass = new TestClass(); TestClass. Elegantly-named setName (" test "); testClass.setSex("100"); SurrenderOrderDto surrenderOrderDto2 = (SurrenderOrderDto)strategy2.apply(testClass); System.out.println(surrenderOrderDto2.getOrderNo()); }Copy the code

The test results

conclusion

This scheme solves the disadvantages brought by the strategy mode well. It can solve if-else complex situations in normal business, and is not entangled with if-ELSE and policy patterns. Ps: (You can also use the extension point ApplicationContextAware provided by Spring to store the corresponding policy method in the Map when the system is started, and provide the external execution entrance execute)

The first time to write an article about code life, we light spray

The first time to write an article about code life, we light spray

The first time to write an article about code life, we light spray