设计模式(十九)——策略模式

mac2026-01-30  4

上一篇:设计模式(十八)——状态模式

下一篇:设计模式(二十)——模板模式

一、概述

官方解释:Define a family of algorithms, encapsulate each one, and make them interchangeable.(定义一组算法,将每个算法都封装起来,并且使他们之间可以互换。)

我的理解:将Strategy引用注入到环境类Context中,客户端通过调用Context类方法间接操作ConcreteStrategy,既满足了客户端需求,有实现了Strategy对客户端的隐藏。

参与者:Context环境类、Strategy策略类(抽象策略类、具体策略类)

类图:

二、代码

代码1——策略模式运算符重载     代码2——策略模式运算符重载扩展

代码1——策略模式运算符重载:

package mypackage; public class DesignPatternDemo { public static void main(String[] args) { Context context=new Context(new OperationAdd()); System.out.println(context.operation(3, 5)); context=new Context(new OperaionSubstract()); System.out.println(context.operation(3, 5)); context=new Context(new OperationMultiply()); System.out.println(context.operation(3, 5)); } } interface Strategy{ public int doOperation(int num1,int num2); } class OperationAdd implements Strategy{ @Override public int doOperation(int num1, int num2) { return num1 + num2; } } class OperaionSubstract implements Strategy{ @Override public int doOperation(int num1, int num2) { return num1 - num2; } } class OperationMultiply implements Strategy{ @Override public int doOperation(int num1, int num2) { return num1 * num2; } } class Context{ private Strategy strategy;//Strategy引用注入到 Context类中,客户端直接操作Context对象,很好的将Strategy隐藏起来 public Context(Strategy strategy){ this.strategy=strategy; } public int operation(int num1,int num2){ return strategy.doOperation(num1, num2); } }

输出1:

8 -2 15

代码2——策略模式运算符重载扩展:

package mypackage; import java.util.Random; public class DesignPatternDemo { public static void main(String[] args) { Context context=new Context(new OperationAdd()); System.out.println(context.operation(3, 5)); context=new Context(new OperaionSubstract()); System.out.println(context.operation(3, 5)); context=new Context(new OperationMultiply()); System.out.println(context.operation(3, 5)); context=new Context(new OperationRandom()); System.out.println(context.operation(3, 5)); } } interface Strategy{ public int doOperation(int num1,int num2); } class OperationAdd implements Strategy{ @Override public int doOperation(int num1, int num2) { return num1 + num2; } } class OperaionSubstract implements Strategy{ @Override public int doOperation(int num1, int num2) { return num1 - num2; } } class OperationMultiply implements Strategy{ @Override public int doOperation(int num1, int num2) { return num1 * num2; } } class OperationRandom implements Strategy{ @Override public int doOperation(int num1, int num2) { Random rand=new Random(45);//45是粒子数 不影响 return rand.nextInt(num1 * num2); } } class Context{ private Strategy strategy;//Strategy引用注入到 Context类中,客户端直接操作Context对象,很好的将Strategy隐藏起来 public Context(Strategy strategy){ this.strategy=strategy; } public int operation(int num1,int num2){ return strategy.doOperation(num1, num2); } }

输出2:

8 -2 15 9

三、小结

策略模式定义一系列运算方法和操作技巧,将它们用一个一个的类封装起来,Strategy引用注入到Context类中,客户端通过调用Context类中的方法间接操作Strategy。

天天打码,天天进步

 

附:状态模式与策略模式区别

1、类图、类的结构一样:

状态模式:Context环境类、State类(抽象状态类、具体状态类)

策略模式:Context环境类、Strategy类(抽象策略类、具体策略类)

两种模式都是行为型模式,UML图相同,都是将核心类(State类或Strategy类)注入到Context类中,在客户端通过操作Context环境类间接操作核心类(State类或Strategy类),巧妙的在客户端屏蔽核心类。

2、表达意义稍有不同:

状态可以看作是Context类的一个内在属性,是必不可少的,新建Context类对象时,Context类的初始化函数中就要初始化状态属性;

策略不是Context的属性,是Context类调用的一个外界的东西;

所以,一般核心类(State类或Strategy类)是内在属性的时候是状态模式,是外界东西的时候是策略模式。

3、代码逻辑稍有不同:状态模式是含有“状态切换”逻辑(最大的不同)

状态模式中一定含有“状态切换”逻辑,不管是在ConcreteState类中还是在Context类中,状态类中一定含有“状态切换”代码;

策略模式只是简单的在客户端切换策略,核心类(Strategy类)中没有“切换”逻辑。

其实,正是因为第二条,State是Context内在属性,所以有切换逻辑,Strategy是外在东西,所有没有切换逻辑。

所以,存在核心类(State类或Strategy类)切换逻辑的是状态模式,不存在的是策略模式。

 

状态模式:

https://blog.csdn.net/qq_36963950/article/details/102866284

策略模式:

https://blog.csdn.net/qq_36963950/article/details/102866291

 

 

上一篇:设计模式(十八)——状态模式

下一篇:设计模式(二十)——模板模式

最新回复(0)