Directory
- 1. About the policy model
- 2. Detailed Strategy model
- 2.1 Policy Mode definition
- 2.2 UML class diagram for policy mode
- 3. Advantages of the Strategy model
- 3.1 An example of using a policy pattern
- 3.2 Comparison with other implementation methods
- 3.3 Advantages of using policy mode
- 4. Using the Factory method mode to improve the original strategy mode
- 5. Summary
- 5. References
1. About the policy model
The polymorphic nature of the policy pattern and the Java language is somewhat like. The polymorphic nature of Java allows us to interface with programming without worrying about the specific implementation of the interface. The implementation class that the interface points to and the specific behavior of the method that is called through the interface can be bound at run time. The best thing to do in this way is to better respond to the changes in the specific implementation class, as much as possible with code reuse. For example, if I want to add an interface implementation or modify some behavior of an existing implementation class, I hardly need to modify any client code. The strategy mode can be said to be the application of this kind of thought in the design pattern. It allows us to better reuse code, while making the program structure design more resilient and better able to cope with changes.
2. Strategy mode detailed 2.1 policy pattern definition
策略模式定义了一系列算法,并将每一个算法封装起来,而且使它们还可以相互替换。策略模式让算法独立于使用它的客户端而独立的变化。
You can use polymorphic analogies to understand the definition of a policy pattern. A series of algorithms can be understood as different implementation classes of interfaces, because different implementation classes implement the same interface, so they can be replaced with each other. The policy pattern makes the algorithm independent of the client and the implementation class of the interface can vary from the client that uses the interface.
2.2 UML class diagram for policy mode
As can be seen from the UML class diagram, there are 3 main roles in the policy pattern
Abstract Policy Interface
Strategy in the abstract policy interface, the interface defines the abstract policy algorithm algorithm ().
Specific policy Implementation classes
The Strategya and strategyb in the specific policy implementation. Different policy implementation classes implement abstract policy interfaces and override their abstract policy methods. Because all implement the same policy interface, so the algorithm can be replaced with each other, and can dynamically change the specific algorithm implementation.
Context for encapsulating policies
The context in which the policy is a contextual environment. It shields the high-level modules from direct access to the strategy algorithm, encapsulating possible changes. It also provides a setter method for modifying strategy, which can dynamically change the concrete implementation of the algorithm.
3. Advantages of the Strategy model
We can use the example of a policy pattern and compare it to other implementations to see what the strategy model is all about.
3.1 An example of using a policy pattern
Define an automobile class car. Since the car's biggest feature is the ability to run, we give that class a move behavior. But to run it needs to provide energy, which is usually petrol, but now more and more cars are powered by batteries. So car's move behavior has two different behavior, one is to use gasoline run, one is to use electric energy to run. So we can define this.
/** * @author: takumiCX * @create: 2018-10-13 **/public abstract class Car { //汽车品牌 private String brand; public Car(String brand) { this.brand = brand; } public Car(String brand, MoveStrategy strategy) { this.brand = brand; this.moveStrategy=strategy; } //汽车的运行策略:使用汽油运行,使用电能运行等等 private MoveStrategy moveStrategy; //运行方法 public void move() { System.out.print(brand); moveStrategy.move(); } public void setMoveStrategy(MoveStrategy moveStrategy) { this.moveStrategy = moveStrategy; }}
A move () method is defined in the abstract car class to indicate that the car has a running behavior, but because it is not directly defined in terms of whether it is running with petrol or using electricity, it calls the Move method defined in the policy interface. The policy interface is packaged in a combination of car interiors and provides a setter method for the client to dynamically switch the way the car is running.
- Strategies for using gasoline to run
/** * @author: takumiCX * @create: 2018-10-14 **//** * 使用汽油运行的策略实现 */public class GasolineMoveStrategy implements MoveStrategy{ @Override public void move() { System.out.println(" Use Gasoline Move!"); }}
- Policy implementation using the battery run
/** * @author: takumiCX * @create: 2018-10-15 **//** * 使用电能运行的策略实现 */public class ElectricityMoveStrategy implements MoveStrategy { @Override public void move() { System.out.println(" Use Electricity Move!"); }}
- Specific Automotive Implementation class
For example, we define a Tesla car by way of inheritance, and Tesla Motors is purely electric by default.
/** * @author: takumiCX * @create: 2018-10-13 **/public class TeslaCar extends Car { public TeslaCar(String brand) { super(brand,new ElectricityMoveStrategy()); }}
- Client code
First, a Tesla was constructed to observe its operating mode and dynamically change its operating mode by setter method for gasoline drive
/** * @author: takumiCX * @create: 2018-10-13 **/public class Client { public static void main(String[] args) { TeslaCar car = new TeslaCar("Tesla"); car.move(); car.setMoveStrategy(new GasolineMoveStrategy()); car.move(); }}
3.2 Comparison with other implementation methods
In fact, the above examples in addition to the use of policy mode, there are other implementations, but they have more obvious shortcomings.
How to implement the 3.2.1 interface
/** * @author: takumiCX * @create: 2018-10-15 **/public interface Move { void move();}
And let the abstract parent class car implement it
/** * @author: takumiCX * @create: 2018-10-13 **/public abstract class Car implements Move{ //汽车品牌 private String brand; public Car(String brand) { this.brand = brand; }}
In this way, all car-inheriting cars must implement their own move method, which is to allow specific car subclasses to determine the specific behavior of the car: whether to run with petrol or batteries. But there are at least a few drawbacks to doing this:
1. Specific car operation behavior is not convenient for later maintenance. Thus, the move behavior cannot be reused, and the concrete implementation is scattered in the subclass. If you want to modify the implementation of a drive way, you have to modify all subclasses, this is simply a disaster.
2. Causes the expansion of the number of classes. The same brand of cars, because of the two operating modes of petrol and electric, have to maintain two classes for them, if you are adding a driving mode, such as hydrogen energy drive, it is not for each brand of the car to add another class.
3. It is inconvenient to expand the move behavior, and it is not convenient to change its implementation mode dynamically.
The way to realize 3.2.2 If-else
The Move method accepts the parameters passed by the client and, through If-else or swich-case, chooses the correct drive mode.
public void move(String moveStrategy) { if("electricity".equals(moveStrategy)){ System.out.println(" Use Electricity Move!"); }else if("gasoline".equals(moveStrategy)){ System.out.println(" Use Gasoline Move!"); }}
However, this is equivalent to hard coding, does not conform to the opening and shutting principle. For example, I want to increase the drive of a hydrogen energy, this implementation will need to modify the code in the move. If you use the above-mentioned policy pattern, you only need to add a specific policy implementation class that implements the policy interface, without modifying any code in the move to be used by the client.
/** * @author: takumiCX * @create: 2018-10-15 **/public class HydrogenMovetrategy implements MoveStrategy { @Override public void move() { System.out.println(" Use Hydrogen Move!"); }}
3.3 Advantages of using policy mode
1. You can optimize the class structure, when there are many implementations of a function of a class, you can define the policy interface in the class and delegate the actual function implementation to the specific policy implementation class. This avoids the expansion of the class and can be extended and maintained better.
2. Avoid the problem of hard coding and poor extensibility caused by using multiple conditional judgments
3. The specific algorithm can be switched freely to enhance the flexibility of the program design.
4. Using the Factory method mode to improve the original strategy mode
All policy implementations need to be exposed externally, and the upper module must know the specific policy implementation class, which is contrary to the Dimitri rule. To do this, the factory method mode can be used for decoupling.
/** * @author: takumiCX * @create: 2018-10-16 **/public interface MoveStrategyFactory { MoveStrategy create();}
- Hydrogen Energy-driven plant
/** * @author: takumiCX * @create: 2018-10-16 **/public class HydrogenMoveStrategyFactory implements MoveStrategyFactory { @Override public MoveStrategy create() { return new HydrogenMovetrategy(); }}
/** * @author: takumiCX * @create: 2018-10-13 **/public class Client { public static void main(String[] args) throws IllegalAccessException, InstantiationException, ClassNotFoundException { TeslaCar car = new TeslaCar("Tesla"); MoveStrategyFactory factory = new HydrogenMoveStrategyFactory(); MoveStrategy moveStrategy = factory.create(); car.setMoveStrategy(moveStrategy); car.move(); }}
This allows us to encapsulate the process of creating a specific policy class through the factory method pattern, while also avoiding exposure to high-level modules. The final run structure is as follows
5. Summary
When there are many different implementations of a feature, you can use the policy mode. The policy pattern encapsulates different algorithms and allows them to be replaced, which increases the reusability of the code and enhances the flexibility of the program design. And can be combined with other design patterns such as factory method mode to block specific policy classes to the upper module, making the code easier to extend and maintain.
5. References
- "Head First design mode"
- "Zen of Design Patterns"
Polymorphism in design mode--A detailed description of the strategy model