Strategy mode
1. Basic introduction
- The strategy pattern defines the algorithm family and encapsulates them separately so that they can replace each other. This pattern makes the change of the algorithm independent of the customers using the algorithm.
- This model embodies several design principles:
- Opening and closing principle: separate the changed code from the unchanged code;
- Dependency Inversion Principle: programming for interfaces rather than specific classes;
- Composition Reuse Principle: use combination / aggregation more and inheritance less.
2. Schematic class diagram of strategy mode
3. Scene setting
Project preparation:
- There are their own ducks [wild duck, water duck, little yellow duck, Beijing roast duck]
- Behavior of ducks [flying, barking, flying, swimming]
- Display duck information
4. Strategic mode solution project
4.1 train of thought analysis
- Encapsulate the behavior interface and realize the algorithm family. Place interface objects in superclasses and set specific behavior objects in subclasses.
- Principle: separate the changing parts and encapsulate them into interfaces. Write specific details based on the interfaces to make the behavior changes independent of the users of the algorithm.
- The class diagram is as follows:
4.2 FlyBehavior interface and its implementation
/** * @author: zipeng Li * 2021/5/22 10:14 */ public interface FlyBehavior { void fly(); } /** * @author: zipeng Li * 2021/5/22 10:14 */ public class GoodFlyBehavior implements FlyBehavior{ @Override public void fly() { System.out.println("I'm a flying expert..."); } } /** * @author: zipeng Li * 2021/5/22 10:06 */ public class NoFlyBehavior implements FlyBehavior{ @Override public void fly() { System.out.println("I can't fly..."); } }
4.3 QuackBehavior interface and its implementation
/** * @author: zipeng Li * 2021/5/22 10:19 */ public interface QuackBehavior { void quack(); } /** * @author: zipeng Li * 2021/5/22 10:17 */ public class GagaQuackBehavior implements QuackBehavior{ @Override public void quack() { System.out.println("Gaga, Gaga....."); } } /** * @author: zipeng Li * 2021/5/22 10:17 */ public class HahaQuackBehavior implements QuackBehavior{ @Override public void quack() { System.out.println("hahahahhahaha..."); } }
4.4 Duck abstraction and its implementation
/** * @author: zipeng Li * 2021/5/22 10:18 */ public abstract class Duck { FlyBehavior flyBehavior; QuackBehavior quackBehavior; public void setFlyBehavior(FlyBehavior flyBehavior) { this.flyBehavior = flyBehavior; } public void setQuackBehavior(QuackBehavior quackBehavior) { this.quackBehavior = quackBehavior; } public void fly(){ if(flyBehavior != null){ flyBehavior.fly(); } } public void quack(){ if(quackBehavior != null){ quackBehavior.quack(); } } public abstract void display(); } /** * @author: zipeng Li * 2021/5/22 10:26 */ public class PekingDuck extends Duck { public PekingDuck() { quackBehavior = new HahaQuackBehavior(); flyBehavior = new NoFlyBehavior(); } @Override public void display() { System.out.println("I'm Beijing roast duck..."); } } /** * @author: zipeng Li * 2021/5/22 10:29 */ public class WildDuck extends Duck { public WildDuck() { flyBehavior = new GoodFlyBehavior(); quackBehavior = new GagaQuackBehavior(); } @Override public void display() { System.out.println("I'm a wild duck..."); } }
4.5 client test
/** * @author: zipeng Li * 2021/5/22 10:31 */ public class Client { public static void main(String[] args) { PekingDuck pekingDuck = new PekingDuck(); pekingDuck.display(); pekingDuck.quack(); pekingDuck.fly(); System.out.println("==================="); WildDuck wildDuck = new WildDuck(); wildDuck.display(); wildDuck.fly(); wildDuck.quack(); // dynamic alteration wildDuck.setFlyBehavior(new NoFlyBehavior()); wildDuck.fly(); } }
I'm Beijing roast duck... hahahahhahaha... I can't fly... =================== I'm a wild duck... I'm a flying expert... Gaga, Gaga..... I can't fly...
5. Application of policy mode in JDK arrays
The Comparator of JDK's Arrays uses the policy mode
/** * @author: zipeng Li * 2021/5/22 10:46 */ public class Strategy { public static void main(String[] args) { Integer[] data = {9, 1, 2, 8, 4, 3}; /** * 1. Comparator As a policy interface, new comparator < integer > () {} is the object that implements the policy interface * 2. public int compare(Integer o1, Integer o2) {}Method specifies the specific processing method */ Comparator<Integer> comparator = new Comparator<Integer>() { @Override public int compare(Integer o1, Integer o2) { if (o1 > o2) { return 1; } else { return -1; } } }; Arrays.sort(data, comparator); System.out.println(Arrays.toString(data)); } }
// Sort according to the specific policy object c passed in public static <T> void sort(T[] a, Comparator<? super T> c) { if (c == null) { sort(a); } else { if (LegacyMergeSort.userRequested) legacyMergeSort(a, c); else TimSort.sort(a, 0, a.length, c, null, 0, 0); } }
6. Summary
- Advantages: by analyzing the changed and unchanged parts of the requirements, the changed parts are encapsulated by the policy interface, and their implementation is handed over to the specific subclasses. If new strategies need to be added in the later stage, only new classes need to be added without modifying the original code, which reflects the opening and closing principle.
- Disadvantages: every time you add a strategy, you need to create a new class, which will cause too many classes.
Post order
- I am a junior undergraduate majoring in software engineering. At present, we are preparing for internship and autumn recruitment. The intended position is java back-end development engineer. To this end, I hosted a project in codecloud to sort out all my knowledge. Contents involved: computer network, operating system, Java foundation, mainstream Java back-end framework, design pattern, Web front-end framework, etc. Welcome to my open source project The way of programming
- Code cloud address: https://gitee.com/alizipeng/the-way-of-programming
- The above contents are recorded in my open source project