一、 策略模式
策略模式定义了算法(或行为)族,分别封装在不同的类中,算法可以在运行时被选择和替换,让算法的变化独立于使用算法的客户。
非常拗口的定义,使人感到迷惑,还是需要用具体样例来说明。
1. 设计原则
- 分开变化和不变的部分
- 针对接口编程,而非针对实现编程
- 多用组合,少用继承
2. 应用场景
- 一个系统中有许多类,但它们的区别仅有行为不同
3. 应用样例
3.1 问题
- 一个抬升器(Lift)有许多执行器(Motor),根据不同的任务需求,它们需要工作在不同的模式下,不同模式对应电机的移动速度、先后顺序不同。
- 假设该装置由一个抬升电机(z轴)和一个前伸电机(y轴)组成。装置有一级(First)、二级(Second)三种模式。其中,一级先前伸,再抬升;二级则先抬升,再前伸,且速度更快。
- 存在两个用户(Auto/Manual)会使用抬升器。
3.2 分析
- 找出不变的部分:
- 需要设置的两个电机最终位置
set_position
相同 - 不同模式下都需要执行移动(Move)这一动作
- 需要设置的两个电机最终位置
- 找出变化的部分:
- 需要设置的两个电机执行顺序不同
- 电机运动速度
set_speed
不同 - 抬升模式(LiftMode)不同,且需要进行切换
- 谁是用户:
- Auto、Manual是使用算法的用户
- 谁是算法:
- 两种不同抬升模式(LiftMode)的方法是具体的算法
- 用户如何调用算法:
- 需要将抬升模式(LiftMode)的方法抽象为一个接口,从而给用户调用
策略模式 Strategy Mode
--- title: Hello Title config: themeCSS: '.mermaid { background-color: #f0f0f0; }' --- classDiagram class LiftCtr{ +Motor zMotor +Motor yMotor +LiftMode Mode +move() +SetMode() } LiftCtr --> LiftMode class LiftMode{ >>Interface<< +SetMove() } LiftMode <|.. FirstLiftMode class FirstLiftMode{ +SetMove() } LiftMode <|.. SecondLiftMode class SecondLiftMode{ +SetMove() } LiftCtr <|-- AutoLiftCtr class AutoLiftCtr{ +move() +SetMode(LiftMode mode) } LiftCtr <|-- ManualLiftCtr class ManualLiftCtr{ +move() +SetMode(LiftMode mode) } Motor o-- LiftCtr Motor --|> zMotor Motor --|> yMotor class Motor{ +float speed +float position +set_speed(float s) +set_position(float p) +start() +... }
LiftCtr为基本类,由具体的用户(Auto/Manual)继承。抬升模式(LiftMode)是接口,由具体的抬升算法(FirstLiftMode/SencondLiftMode)来继承。运行时,用户可以切换抬升算法,切换方法(SetMode(LiftMode mode))定义在基类中。在运行过程中,用户会调用到当前抬升模式的SetMove()方法,从而执行相应的抬升动作。
3.3 代码
1 |
|