返回
剑走偏锋:《设计模式之美》里的策略模式真相,远非简化分支判断!
Android
2023-12-22 08:37:57
提起策略模式,许多程序员的第一反应就是"啊!原来设计模式还可以用来减少if-else或者switch的冗长判断,代码变得可读了,我也能变得帅了!"。然而,策略模式的价值远非如此,它是一种应对变化的通用解决方案,通过将算法或策略的实现与使用它们的环境分离,可以提高代码的可复用性和灵活性。
在《设计模式之美》一书中,作者用一个有趣的例子来介绍策略模式——一个图形绘制应用程序需要支持多种绘图形状,如圆形、矩形、三角形等。如果采用传统的if-else或者switch来判断绘图形状,那么代码将会变得冗长而难以维护。此时,策略模式就派上用场了。
// 定义一个绘图形状接口
interface Shape {
void draw();
}
// 定义一个绘图器类,负责调用不同的绘图形状接口的draw()方法
class Drawer {
private Shape shape;
public void setShape(Shape shape) {
this.shape = shape;
}
public void drawShape() {
shape.draw();
}
}
// 定义具体的绘图形状类,如圆形、矩形、三角形等
class Circle implements Shape {
@Override
public void draw() {
System.out.println("绘制圆形");
}
}
class Rectangle implements Shape {
@Override
public void draw() {
System.out.println("绘制矩形");
}
}
class Triangle implements Shape {
@Override
public void draw() {
System.out.println("绘制三角形");
}
}
// 使用绘图器类来绘制不同的绘图形状
Drawer drawer = new Drawer();
drawer.setShape(new Circle());
drawer.drawShape(); // 输出:绘制圆形
drawer.setShape(new Rectangle());
drawer.drawShape(); // 输出:绘制矩形
drawer.setShape(new Triangle());
drawer.drawShape(); // 输出:绘制三角形
通过这种方式,我们可以将绘图形状的具体实现与绘图器类解耦,使得绘图器类可以独立于绘图形状的具体实现进行工作。如果我们需要增加新的绘图形状,只需实现一个新的Shape接口即可,而无需修改绘图器类。
策略模式的优点显而易见:
- 代码复用: 通过将算法或策略的实现与使用它们的环境分离,可以提高代码的可复用性。
- 灵活设计: 策略模式可以使设计更具灵活性,便于在需要时更改算法或策略。
- 扩展性强: 策略模式可以使代码具有很强的扩展性,当需要增加新的算法或策略时,只需实现一个新的策略类即可。
然而,策略模式也存在一些缺点和局限性:
- 性能开销: 策略模式可能会带来一些性能开销,因为每次调用策略时都需要进行一次方法调用。
- 代码复杂性: 策略模式可能会增加代码的复杂性,尤其是当策略数量较多时。
- 维护成本: 策略模式可能会增加代码的维护成本,因为当需要更改算法或策略时,需要修改相应的策略类。
总的来说,策略模式是一种非常有用的设计模式,可以帮助我们应对变化,提高代码的可复用性和灵活性。在实际应用中,需要根据具体情况权衡策略模式的优点和缺点,以决定是否使用策略模式。