1. What is the strategy model?
Define a family of algorithms, encapsulate each one, and make them interchangeable. Strategy lets the algorithm vary independently from clients that use it.
Strategy Pattern: define a family of algorithm classes, encapsulate each algorithm separately, so that they can replace each other.
2. Policy pattern definition
![](/images/think/e5ea5c03c696c0cebdc904c24bfe9de1.jpg)
① Context encapsulates roles
It is also called context role, which serves as a connecting link between the preceding and the following, shields the direct access of high-level modules to policies and algorithms, and encapsulates possible changes.
② Strategy Abstract policy role
The abstraction of a policy or algorithm family, usually an interface, defines the methods and attributes that each policy or algorithm must have.
③ Concrete strategy specific policy roles
Implement the operations in the abstract policy. This class contains specific algorithms.
3. Policy mode common code
public class Context { // Abstract strategy private Strategy strategy = null; // Constructor to set specific policies public Context(Strategy strategy) { this.strategy = strategy; } // Encapsulated strategy and method public void doAnything(){ this.strategy.doSomething(); } }
public interface Strategy { // Algorithm of policy mode public void doSomething(); }
public class ConcreteStrategy1 implements Strategy{ @Override public void doSomething() { System.out.println("ConcreteStrategy1"); } }
public class ConcreteStrategy2 implements Strategy{ @Override public void doSomething() { System.out.println("ConcreteStrategy2"); } }
Test:
public class StrategyClient { public static void main(String[] args) { // Declare a specific policy Strategy strategy = new ConcreteStrategy1(); // Declare context object Context context = new Context(strategy); // Post encapsulation method context.doAnything(); } }
4. Rewrite if else with policy mode
Suppose we want to process an office file, which is divided into three types: docx, xlsx and pptx. They represent Word file, Excel file and PPT file respectively, which are parsed according to the file suffix.
4.1 conventional writing
public class OfficeHandler { public void handleFile(String filePath){ if(filePath == null){ return; } String fileExtension = getFileExtension(filePath); if(("docx").equals(fileExtension)){ handlerDocx(filePath); }else if(("xlsx").equals(fileExtension)){ handlerXlsx(filePath); }else if(("pptx").equals(fileExtension)){ handlerPptx(filePath); } } public void handlerDocx(String filePath){ System.out.println("handle docx file"); } public void handlerXlsx(String filePath){ System.out.println("handle xlsx file"); } public void handlerPptx(String filePath){ System.out.println("handle pptx file"); } private static String getFileExtension(String filePath){ // Resolve the file name to obtain the file extension, such as document. Docx, and return docx String fileExtension = filePath.substring(filePath.lastIndexOf(".")+1); return fileExtension; } }
If the processing logic is all placed in one class, the whole class will be very large. Suppose we want to add a new type of processing. For example, for office files before version 2007, the suffixes are doc/xls/ppt respectively, we have to add else if logic, which violates the opening and closing principle. How to solve this problem? The answer is through the policy mode.
4.2 strategy mode rewriting
public interface OfficeHandlerStrategy { void handlerOffice(String filePath); }
public class OfficeHandlerDocxStrategy implements OfficeHandlerStrategy { @Override public void handlerOffice(String filePath) { System.out.println("handle docx"); } }
//Omit the OfficeHandlerXlsxStrategy/OfficeHandlerPptxStrategy class
public class OfficeHandlerStrategyFactory { private static final Map<String,OfficeHandlerStrategy> map = new HashMap<>(); static { map.put("docx",new OfficeHandlerDocxStrategy()); map.put("xlsx",new OfficeHandlerXlsxStrategy()); map.put("pptx",new OfficeHandlerPptxStrategy()); } public static OfficeHandlerStrategy getStrategy(String type){ return map.get(type); } }
Test:
public class OfficeHandlerStrategyClient { public static void main(String[] args) { String filePath = "C://file/123.xlsx"; String type = getFileExtension(filePath); OfficeHandlerStrategy strategy = OfficeHandlerStrategyFactory.getStrategy(type); strategy.handlerOffice(filePath); } private static String getFileExtension(String filePath){ // Resolve the file name to obtain the file extension, such as document. Docx, and return docx String fileExtension = filePath.substring(filePath.lastIndexOf(".")+1); return fileExtension; } }
4. Advantages of strategic mode
① The algorithm can be switched freely
This is defined by the policy pattern itself. As long as the abstract policy is implemented, it becomes a member of the policy family. It is encapsulated by encapsulating roles to ensure that "freely switchable" policies are provided externally.
② Avoid using multiple conditional judgments
Simplify multiple if else, or multiple switch case branches.
③ Good expansibility
To add a policy, you only need to implement one interface.
5. Policy mode application scenario
① Multiple classes have only slightly different scenarios in algorithm or behavior.
② Scenarios where the algorithm needs to be switched freely.
③ . scenarios that need to mask algorithm rules.