Update 设计模式 - 策略.md

实现一节改用运费的例子演示 Context,类图说明同步。
This commit is contained in:
CyC2018
2026-11-04 22:39:59 +08:00
parent f458bf7676
commit f7577dc5fd
+36 -61
View File
@@ -9,71 +9,11 @@
- Strategy 接口定义了一个算法族,它们都实现了 behavior() 方法;
- Context 是使用到该算法族的类,其中的 doSomething() 方法会调用 behavior(),setStrategy(Strategy) 方法可以动态地改变 strategy 对象,即可以在运行时更换 Context 使用的算法。
下图按后文的鸭子示例画出:Duck 是 Context,QuackBehavior 是 Strategy,quack()、performQuack() 和 setQuackBehavior() 分别对应 behavior()、doSomething() 和 setStrategy()。
下图按后文的运费示例画出:Order 是 Context,FreightStrategy 是 Strategy,fee()、freight() 和 setFreightStrategy() 分别对应 behavior()、doSomething() 和 setStrategy()。
<div align="center"> <img src="pics/dp-strategy.png" width="760px"/> </div><br>
### 实现
设计一个鸭子,它可以动态地改变叫声。这里的算法族是鸭子的叫声行为。
```java
public interface QuackBehavior {
void quack();
}
```
```java
public class Quack implements QuackBehavior {
@Override
public void quack() {
System.out.println("quack!");
}
}
```
```java
public class Squeak implements QuackBehavior{
@Override
public void quack() {
System.out.println("squeak!");
}
}
```
```java
public class Duck {
private QuackBehavior quackBehavior;
public void performQuack() {
if (quackBehavior != null) {
quackBehavior.quack();
}
}
public void setQuackBehavior(QuackBehavior quackBehavior) {
this.quackBehavior = quackBehavior;
}
}
```
```java
public class Client {
public static void main(String[] args) {
Duck duck = new Duck();
duck.setQuackBehavior(new Squeak());
duck.performQuack();
duck.setQuackBehavior(new Quack());
duck.performQuack();
}
}
```
```text
squeak!
quack!
```
#### 1. 用策略替代 if-else
@@ -132,6 +72,41 @@ public class PickupFreight implements FreightStrategy {
}
```
Order 是 Context,持有一个运费策略,计算运费时交给它;用户改选配送方式时,换一个策略对象即可:
```java
public class Order {
private FreightStrategy freightStrategy;
public void setFreightStrategy(FreightStrategy freightStrategy) {
this.freightStrategy = freightStrategy;
}
public int freight(int kg) {
return freightStrategy.fee(kg);
}
}
```
```java
public class Client {
public static void main(String[] args) {
Order order = new Order();
order.setFreightStrategy(new StandardFreight());
System.out.println(order.freight(3));
order.setFreightStrategy(new ExpressFreight()); // 用户改选加急
System.out.println(order.freight(3));
}
}
```
```text
16
37
```
同样的结构也适用于支付渠道、消息推送渠道等场景,只是各实现类的内容换成对应的处理逻辑。
#### 2. 与简单工厂和 Spring 容器结合