Home >Java >javaTutorial >Introduction to Strategy Pattern and Template Method Pattern in Java (with code)
This article brings you an introduction to the strategy pattern and template method pattern in Java (with code). It has certain reference value. Friends in need can refer to it. I hope it will be helpful to you.
Strategy Pattern
Introduction
Strategy Pattern belongs to the behavior pattern of an object. Its purpose is to encapsulate each algorithm into an independent class with a common interface for a set of algorithms, so that they can be replaced with each other. The strategy pattern allows the algorithm to change without affecting the client.
The main purpose is to replace the writing of if else statements by defining similar algorithms, and they can be replaced with each other at any time.
Strategy mode is mainly composed of these three roles, environmental role (Context), abstract strategy role (Strategy) and concrete strategy role (ConcreteStrategy).
Environment role (Context): holds a reference to a strategy class and provides it to the client.
Abstract Strategy Role (Strategy): This is an abstract role, usually implemented by an interface or abstract class. This role gives all the interfaces required by the specific policy classes.
Concrete Strategy Role (ConcreteStrategy): Packages related algorithms or behaviors.
The example diagram is as follows:
To facilitate understanding, let’s take the calculation method used when we first learned Java.
When using a calculator for calculations, addition, subtraction, multiplication and division methods are often used. If we want to get the sum of the addition of two numbers, we need to use the " " symbol, to get the difference of the subtraction, we need to use the "-" symbol, etc. Although we can write a general method using if/else through string comparison, every time the calculated symbol is added, we have to add the corresponding code to the original method. If the subsequent calculation method is added, modified or deleted, then This will make subsequent maintenance difficult.
But among these methods, we found that the basic methods are fixed. At this time, we can develop through the strategy mode, which can effectively avoid judgment through if/else, even if other calculation rules are added later. Flexibility to make adjustments.
First define an abstract strategy role and have a calculation method.
interface CalculateStrategy { int doOperation(int num1, int num2); }
Then define the specific strategic roles of addition, subtraction, multiplication and division and implement methods.
Then the code is as follows:
class OperationAdd implements CalculateStrategy { @Override public int doOperation(int num1, int num2) { return num1 + num2; } } class OperationSub implements CalculateStrategy { @Override public int doOperation(int num1, int num2) { return num1 - num2; } } class OperationMul implements CalculateStrategy { @Override public int doOperation(int num1, int num2) { return num1 * num2; } } class Operationp implements CalculateStrategy { @Override public int doOperation(int num1, int num2) { return num1 / num2; } }
Finally, define an environment role and provide a computing interface for the client to use.
The code is as follows:
class CalculatorContext { private CalculateStrategy strategy; public CalculatorContext(CalculateStrategy strategy) { this.strategy = strategy; } public int executeStrategy(int num1, int num2) { return strategy.doOperation(num1, num2); } }
After writing it, let’s test it.
The test code is as follows:
public static void main(String[] args) { int a=4,b=2; CalculatorContext context = new CalculatorContext(new OperationAdd()); System.out.println("a + b = "+context.executeStrategy(a, b)); CalculatorContext context2 = new CalculatorContext(new OperationSub()); System.out.println("a - b = "+context2.executeStrategy(a, b)); CalculatorContext context3 = new CalculatorContext(new OperationMul()); System.out.println("a * b = "+context3.executeStrategy(a, b)); CalculatorContext context4 = new CalculatorContext(new Operationp()); System.out.println("a / b = "+context4.executeStrategy(a, b)); }
Output result:
a + b = 6 a - b = 2 a * b = 8 a / b = 2
Strategy mode advantages:
Good scalability, you can add new classes to implement new algorithms without modifying the object structure;
Good flexibility, you can switch algorithms freely;
Disadvantages of strategy mode:
Using more strategy classes will increase the complexity of the system. ;
The client must know all the policy classes before calling;
Usage scenarios:
If there are many classes in a system, and the only difference between them is their behavior, then using the strategy pattern can dynamically let an object choose one behavior among many behaviors;
A system needs to dynamically choose one of several algorithms;
If an object has many behaviors, without appropriate patterns, these behaviors will have to use multiple conditional selection statements. To achieve;
Introduction
In the Template Pattern (Template Pattern), an abstract class Publicly defines the way/template of the method to execute it. Its subclasses can override the method implementation as needed, but the calls will be made in the manner defined in the abstract class. This type of design pattern is a behavioral pattern. Define the skeleton of an algorithm in one operation, deferring some steps to subclasses.
The main idea of template mode is to make a template and provide it to the client for calling. In addition to resume templates, contract templates, etc. that we often use in life, there are also very classic templates used in Java, that is Servlet. The HttpService class provides a service() method, which calls one of the seven do methods or Several, complete responses to client calls. These do methods need to be provided by the subclass of HttpServlet.
Template mode Mainly consists of the Abstract Template role and the Concrete Template role.
抽象模板(Abstract Template): 定义了一个或多个抽象操作,以便让子类实现。这些抽象操作叫做基本操作,它们是一个顶级逻辑的组成步骤;定义并实现了一个模板方法。这个模板方法一般是一个具体方法,它给出了一个顶级逻辑的骨架,而逻辑的组成步骤在相应的抽象操作中,推迟到子类实现。顶级逻辑也有可能调用一些具体方法。
具体模板(Concrete Template): 实现父类所定义的一个或多个抽象方法,它们是一个顶级逻辑的组成步骤;每一个抽象模板角色都可以有任意多个具体模板角色与之对应,而每一个具体模板角色都可以给出这些抽象方法(也就是顶级逻辑的组成步骤)的不同实现,从而使得顶级逻辑的实现各不相同。
示例图如下:
这里为了方便理解,我们依旧使用一个简单的示例来加以说明。
我们以前在玩魂斗罗、双截龙、热血物语、忍者神龟等等游戏的时候,都需要在小霸王游戏机上插卡,然后启动游戏才能玩,其中魂斗罗这种游戏,启动游戏之后就可以直接玩了,但是忍者神龟这种游戏则在启动游戏之后,需要选择其中一个角色才能开始玩。那么我们可以根据这个场景写出一个通用的模板,主要包含启动游戏,玩游戏,结束游戏这几个必须实现的方法,选择人物这个方法改成可选。
那么这个抽象类的代码如下:
abstract class Game{ //启动游戏 protected abstract void runGame(); //选择人物 protected void choosePerson() {}; //开始玩游戏 protected abstract void startPlayGame(); //结束游戏 protected abstract void endPlayGame(); //模板方法 public final void play() { runGame(); choosePerson(); startPlayGame(); endPlayGame(); } }
定义好该抽象类之后,我们再来定义具体模板实现类。这里定义两个游戏类,一个是魂斗罗,一个忍者神龟。
那么代码如下:
class ContraGame extends Game{ @Override protected void runGame() { System.out.println("启动魂斗罗II..."); } @Override protected void startPlayGame() { System.out.println("1P正在使用S弹打aircraft..."); } @Override protected void endPlayGame() { System.out.println("1P被流弹打死了,游戏结束!"); } } class TMNTGame extends Game{ @Override protected void runGame() { System.out.println("启动忍者神龟III..."); } @Override protected void choosePerson() { System.out.println("1P选择了Raph !"); } @Override protected void startPlayGame() { System.out.println("Raph正在使用绝技 “火箭头槌” "); } @Override protected void endPlayGame() { System.out.println("Raph 掉进井盖里死了,游戏结束了! "); } }
最后再来进行测试,测试代码如下:
public static void main(String[] args) { Game game = new ContraGame(); game.play(); System.out.println(); game = new TMNTGame(); game.play(); }
输出结果:
启动魂斗罗II...1P正在使用S弹打aircraft...1P被流弹打死了,游戏结束! 启动忍者神龟III...1P选择了Raph ! Raph正在使用绝技 “火箭头槌” Raph 掉进井盖里死了,游戏结束了!
模板模式优点:
扩展性好,对不变的代码进行封装,对可变的进行扩展;
可维护性好,因为将公共代码进行了提取,使用的时候直接调用即可;
模板模式缺点:
因为每一个不同的实现都需要一个子类来实现,导致类的个数增加,会使系统变得复杂;
使用场景:
有多个子类共有逻辑相同的方法;
重要的、复杂的方法,可以考虑作为模板方法。
注意事项:
为防止恶意操作,一般模板方法都加上 final 关键词!
The above is the detailed content of Introduction to Strategy Pattern and Template Method Pattern in Java (with code). For more information, please follow other related articles on the PHP Chinese website!