This is the third day of my participation in the August More Text Challenge

concept

Define a family of algorithm classes and encapsulate each algorithm individually so that they can be replaced with each other. Policy patterns can make changes to algorithms independent of the clients that use them (by client I mean the code that uses the algorithm).

Key points: define, create, use

  • Define a policy interface, an algorithm, and a set of policy classes that implement the interface;
  • Policy creation is done by the factory, encapsulating the details of the policy creation;
  • Policy selection can be used in two ways:
  • One is to determine statically, directly new the corresponding policy interface;
  • One is dynamic determination, which dynamically instantiates the policy interface according to the running parameters.

The following uses different preferential strategies to implement the strategy pattern.

The policy definition

1. Define policy interfaces

/** * public interface Strategy {/** * public interface Strategy */ Object discount(); }Copy the code

2. Define a set of policy classes that implement interfaces

  • Discount strategy class
Public class DiscountStrategy implements Strategy {@override public Object discount() {system.out.println (" discount "); return null; }}Copy the code
  • Price reduction strategy
Public class ReducePriceStrategy implements Strategy {@override public Object discount() {system.out.println (" reduce "); return null; }}Copy the code
  • Gift coupon strategy class
Public class FreeProductStrategy implements Strategy {@override public Object discount() {system.out.println (" free product "); return null; }}Copy the code

Strategy factory

1. Policy enumeration type

Public enum DiscountEnum {DISCOUNT, /** DISCOUNT **/ REDUCE_PRICE, /** DISCOUNT **/ free_price, /** DISCOUNT **/ FREE_PRODUCT; /** **/}Copy the code

2. Strategy Factory

2.1 Stateless policy factories

When the specific preferential algorithm is stateless, map can be used to match the type and policy, and the corresponding policy implementation can be obtained by “look-up table method” when obtaining the specific implementation policy.

/** * stateless policy factory * stateless refers to pure algorithm, Public class StrategyFactory {private static final Map<DiscountEnum,Strategy> Strategies = new HashMap<>(); static { strategies.put(DiscountEnum.DISCOUNT,new DiscountStrategy()); strategies.put(DiscountEnum.REDUCE_PRICE,new ReducePriceStrategy()); strategies.put(DiscountEnum.FREE_COUPON,new FreeCouponStrategy()); strategies.put(DiscountEnum.FREE_PRODUCT,new FreeProductStrategy()); } @param discountEnum * @return */ public static Strategy getStrategy(discountEnum discountEnum) { if(discountEnum == null) { throw new IllegalArgumentException("discountNum should not be null"); } return strategies.get(discountEnum); }}Copy the code

2.2 Stateful policy factories

When the policy algorithm is stateful, the policy class needs to be recreated each time the policy is fetched. Objects can be dynamically instantiated by reflection, mapped to store the relationship between type and policy Class, or created by annotations.

In this case, map is used to store data.

/** * public class StrategyFactory2 {private static final Map<DiscountEnum, class <? extends Strategy>> strategies = new HashMap<>(); static { strategies.put(DiscountEnum.DISCOUNT, DiscountStrategy.class); strategies.put(DiscountEnum.REDUCE_PRICE, ReducePriceStrategy.class); strategies.put(DiscountEnum.FREE_COUPON, FreeCouponStrategy.class); strategies.put(DiscountEnum.FREE_PRODUCT, FreeProductStrategy.class); } /** * Create a Strategy */ public static Strategy getStrategy(DiscountEnum DiscountEnum) throws InstantiationException, IllegalAccessException { if(discountEnum == null) { throw new IllegalArgumentException("discountNum should not be null"); } Class<? extends Strategy> strategyClass = strategies.get(discountEnum); return strategyClass.newInstance(); }}Copy the code

Use of policies

  • Dynamically created at runtime
// @test public void testStrategy() {// DiscountEnum DiscountEnum = DiscountEnum.REDUCE_PRICE; Strategy strategy = StrategyFactory.getStrategy(discountEnum); strategy.discount(); }Copy the code
  • The static create
// @test public void testStrategy4Static() {// Assume that the algorithm to be used is reduced, Strategy Strategy = new DiscountStrategy(); strategy.discount(); }Copy the code

conclusion

It can be found from the above process that the policy mode is actually the combination of defining algorithm interface + factory mode, defining algorithm signature by defining algorithm interface, and using look-up table method to find the qualified policy in the policy set, so as to realize the switch of different policies. This appears to decouple if-else logic, but in reality decouples policy definition, creation, and use, keeping each part from being overly complex and minimizing, centralized, administrative code.