策略模式实战 - 鸭展

该示例出自著名的《HeadFirst》系列的《HeadFirst设计模式》图书的第一个设计模式。用一个鸭子展览的小应用,一步步揭示了如何引入和使用策略模式将示例改造的完美一些。

文章目录

红头鸭与绿头鸭

当鸭展应用中仅有红头鸭和绿头鸭时,我们从中总结出鸭子的共性行为,比如都会"嘎嘎"叫(quack)、游泳戏水(swim),因此我们将这些方法抽取到基类Duck中,这样子类继承过来直接使用即可。而外观的展示方法(display),红头鸭和绿头鸭展示出来不一样,需要子类自己实现,因此将Duck定义为一个抽象类,并提供抽象的display方法,由继承的子类自己负责实现。

橡皮鸭和诱饵鸭

现在鸭展丰富了新的类型,玩具类的鸭子。此时发现了继承的弊端,因为继承后的方法并不都是子类都具有的,此时就要考虑子类的覆盖。也就是说每引入一种新的类型的子类,都要评估其继承的方法,是直接沿用,还是在此基础上扩展还是直接完全覆盖。

用接口代替继承

Java语言的特性从C++摒弃了多继承,转而使用实现接口的形式来代替多继承。当需要设计的类具备某种行为,可以定义相应的接口,让子类自己实现接口即可。比如这里的鸭子,具备某种行为则实现相关的接口,而不具备时,不实现接口则避免了子类继承的方法重写。

需要注意的是,实现接口的场景要求具体的行为在每个具体类上不存在共性,如果存在共性,那么这个接口的实现逻辑其实是存在的重复的代码逻辑,代码逻辑冗余无法被复用,这是滥用接口导致的。此时我们应当考虑,如何将接口的实现逻辑进行复用,这就是接下来要引入的策略模式。

组合关系与策略模式

上面提到了过度依赖类的继承以及接口实现的一些弊端,最好的解决办法是:用组合关系代替过度的类继承和接口实现。

比如,这里的鸭子的各种行为使用组合的关系,在鸭子基类中定义相关行为的属性,属性类型为特定行为的接口,面向接口编程的本质是面向对象编程的多态机制的使用。因此因为接口的具体实现可以任意扩展,这种具体的可复用的行为的封装就是策略模式。

**如果子类不具备某种行为的策略,那也不是通过重写父类调用相关策略的方法,而是实现这种"不具备某种行为"这一策略。**比如橡皮鸭不会飞,则复用FlyNoWay的具体策略即可。

完整类图:

相关推荐
Java_2017_csdn2 天前
Java 策略模式(Strategy Pattern)-(二)
java·开发语言·策略模式
Java_2017_csdn2 天前
Java 策略模式(Strategy Pattern)-(一)
java·开发语言·策略模式
拾光Ծ2 天前
【Linux系统编程】线程池项目实战与基于策略模式的日志系统
linux·bash·线程池·策略模式·日志
星原望野3 天前
JAVA:策略模式的实战使用
java·开发语言·策略模式
前端张三3 天前
从零构建大模型(零)——搭建配置环境
策略模式
j_xxx404_3 天前
Linux 线程日志系统设计:从策略模式、RAII 到 pthread 线程安全与内核写入路径|附源码
linux·运维·服务器·开发语言·c++·人工智能·策略模式
代码小书生6 天前
shutil,一个文件操作的 Python 库!
开发语言·python·策略模式
ting94520006 天前
ModelHub 深度技术解析:macOS 原生菜单栏 LLM 模型管理工具,补齐 Ollama/MLX/LM Studio 生态短板
人工智能·macos·架构·策略模式
张小姐的猫6 天前
【Linux】多线程实战 —— 日志类 | 策略模式
linux·运维·服务器·c++·bash·策略模式
老码观察7 天前
设计模式实战解读(五):策略模式——干掉 if-else 的优雅方案
java·设计模式·策略模式