策略设计模式解读

简介: 策略设计模式解读

问题引进

鸭子问题

编写鸭子项目,具体要求如下:
1) 有各种鸭子(比如 野鸭、北京鸭、水鸭等, 鸭子有各种行为,比如 叫、飞行等)
2) 显示鸭子的信息

传统方案解决鸭子问题的分析和代码实现

传统的设计方案(类图)

代码实现

Duck

1. public abstract class Duck {
2. public Duck() {
3.     }
4. public abstract void display();//显示鸭子信息
5. public void quack() {
6.         System.out.println("鸭子嘎嘎叫~~");
7.     }
8. public void swim() {
9.         System.out.println("鸭子会游泳~~");
10.     }
11. public void fly() {
12.         System.out.println("鸭子会飞翔~~~");
13.     }
14. }

PekingDuck  

1. public class PekingDuck extends  Duck{
2. @Override
3. public void display() {
4.         System.out.println("~~北京鸭~~~");
5.     }
6. 
7. //因为北京鸭不能飞翔,因此需要重写 fly
8. @Override
9. public void fly() {
10.         System.out.println("北京鸭不能飞翔");
11.     }
12. }

ToyDuck  

1. public class ToyDuck extends  Duck{
2. @Override
3. public void display() {
4.         System.out.println("玩具鸭");
5.     }
6. //需要重写父类的所有方法
7. public void quack() {
8.         System.out.println("玩具鸭不能叫~~");
9.     }
10. public void swim() {
11.         System.out.println("玩具鸭不会游泳~~");
12.     }
13. public void fly() {
14.         System.out.println("玩具鸭不会飞翔~~~");
15.     }
16. 
17. }

WildDuck  

1. public class WildDuck extends  Duck{
2. @Override
3. public void display() {
4.         System.out.println(" 这是野鸭 ");
5.     }
6. }

传统的方式实现的问题分析和解决方案

1) 其它鸭子,都继承了 Duck 类,所以 fly 让所有子类都会飞了,这是不正确的
2) 上面说的 1 的问题,其实是继承带来的问题:对类的局部改动,尤其超类的局部改动,会影响其他部分。会有溢出效应
3) 为了改进 1 问题,我们可以通过覆盖 fly 方法来解决 => 覆盖解决
4) 问题又来了,如果我们有一个玩具鸭子 ToyDuck, 这样就需要 ToyDuck 去覆盖 Duck 的所有实现的方法 => 解决思路 -》 策略模式 (strategy pattern)

策略模式基本介绍

基本介绍

1) 策略模式(Strategy Pattern)中,定义算法族(策略组),分别封装起来,让他们之间可以互相替换,此模式让算法的变化独立于使用算法的客户
2) 这算法体现了几个设计原则,第一、把变化的代码从不变的代码中分离出来;第二、针对接口编程而不是具体类(定义了策略接口);第三、多用组合/聚合,少用继承(客户通过组合方式使用策略)。

策略模式的原理类图

说明:从上图可以看到,客户 context 有成员变量 strategy 或者其他的策略接口,至于需要使用到哪个策略,我们可以在构造器中指定

策略模式解决鸭子问题

1) 应用实例要求

编写程序完成前面的鸭子项目,要求使用策略模式

2) 思路分析(类图)

策略模式:分别封装行为接口,实现算法族,超类里放行为接口对象,在子类里具体设定行为对象。原则就是:分离变化部分,封装接口,基于接口编程各种功能。此模式让行为的变化独立于算法的使用者

代码实现

FlyBehavior  

1. public interface FlyBehavior {
2. 
3. void fly(); // 子类具体实现
4. }

BadFlyBehavior  

1. public class BadFlyBehavior implements  FlyBehavior{
2. 
3. @Override
4. public void fly() {
5.         System.out.println("飞翔技术一般");
6.     }
7. }

GoodFlyBehavior  

1. public class GoodFlyBehavior implements  FlyBehavior {
2. 
3. @Override
4. public void fly() {
5. // TODO Auto-generated method stub
6.         System.out.println(" 飞翔技术高超 ~~~");
7.     }
8. }

NoFlyBehavior  

1. public class NoFlyBehavior implements  FlyBehavior{
2. @Override
3. public void fly() {
4.         System.out.println("不会游泳");
5.     }
6. }

Duck  

1. public abstract class Duck {
2. //属性, 策略接口
3.     FlyBehavior flyBehavior;
4. public Duck() {
5.     }
6. public abstract void display();//显示鸭子信息
7. public void fly() {
8. //改进
9. if(flyBehavior != null) {
10.             flyBehavior.fly();
11.         }
12.     }
13. public void setFlyBehavior(FlyBehavior flyBehavior) {
14. this.flyBehavior = flyBehavior;
15.     }
16. }

ToyDuck  

1. public class ToyDuck extends  Duck{
2. public ToyDuck() {
3.         flyBehavior = new NoFlyBehavior();
4.     }
5. @Override
6. public void display() {
7.         System.out.println("玩具鸭");
8.     }
9. 
10. }

WildDuck  

1. public class WildDuck extends Duck{
2. @Override
3. public void display() {
4.         System.out.println("野鸭");
5.     }
6. 
7. public WildDuck() {
8.         flyBehavior =new GoodFlyBehavior();
9.     }
10. 
11. }

PekingDuck  

1. public class PekingDuck  extends  Duck{
2. 
3. //假如背景鸭可以游泳但飞翔技术一般
4. public PekingDuck() {
5.         flyBehavior =new BadFlyBehavior();
6.     }
7. 
8. @Override
9. public void display() {
10.         System.out.println("北京鸭");
11.     }
12. }

策略模式的注意事项和细节

1) 策略模式的关键是:分析项目中变化部分与不变部分
2) 策略模式的核心思想是:多用组合/聚合 少用继承;用行为类组合,而不是行为的继承。更有弹性
3) 体现了“对修改关闭,对扩展开放”原则,客户端增加行为不用修改原有代码,只要添加一种策略(或者行为)即可,避免了使用多重转移语句(if..else if..else)
4) 提供了可以替换继承关系的办法: 策略模式将算法封装在独立的 Strategy 类中使得你可以独立于其 Context 改变它,使它易于切换、易于理解、易于扩展
5) 需要注意的是:每添加一个策略就要增加一个类,当策略过多是会导致类数目庞

相关文章
|
2月前
|
设计模式 安全 测试技术
【C/C++ 设计模式 单例】单例模式的选择策略:何时使用,何时避免
【C/C++ 设计模式 单例】单例模式的选择策略:何时使用,何时避免
66 0
|
2月前
|
设计模式 编解码 C++
【ffmpeg 视频播放】深入探索:ffmpeg视频播放优化策略与设计模式的实践应用(一)
【ffmpeg 视频播放】深入探索:ffmpeg视频播放优化策略与设计模式的实践应用
59 0
|
2月前
|
设计模式 存储 缓存
【ffmpeg 视频播放】深入探索:ffmpeg视频播放优化策略与设计模式的实践应用(二)
【ffmpeg 视频播放】深入探索:ffmpeg视频播放优化策略与设计模式的实践应用
31 0
|
1月前
|
设计模式 监控 Java
设计模式 - 观察者模式(Observer):Java中的战术与策略
【4月更文挑战第7天】观察者模式是构建可维护、可扩展系统的关键,它在Java中通过`Observable`和`Observer`实现对象间一对多的依赖关系,常用于事件处理、数据绑定和同步。该模式支持事件驱动架构、数据同步和实时系统,但需注意避免循环依赖、控制通知粒度,并关注性能和内存泄漏问题。通过明确角色、使用抽象和管理观察者注册,可最大化其效果。
|
1月前
|
设计模式 缓存 安全
分析设计模式对Java应用性能的影响,并提供优化策略
【4月更文挑战第7天】本文分析了7种常见设计模式对Java应用性能的影响及优化策略:单例模式可采用双重检查锁定、枚举实现或对象池优化;工厂方法和抽象工厂模式可通过对象池和缓存减少对象创建开销;建造者模式应减少构建步骤,简化复杂对象;原型模式优化克隆方法或使用序列化提高复制效率;适配器模式尽量减少使用,或合并多个适配器;观察者模式限制观察者数量并使用异步通知。设计模式需根据应用场景谨慎选用,兼顾代码质量和性能。
|
2月前
|
设计模式 编解码 算法
【ffmpeg 视频播放】深入探索:ffmpeg视频播放优化策略与设计模式的实践应用(三)
【ffmpeg 视频播放】深入探索:ffmpeg视频播放优化策略与设计模式的实践应用
33 0
|
4月前
|
设计模式 算法 调度
行为型设计模式:模板设计模式/观察者设计模式/策略设计模式/责任链设计模式
行为型设计模式:模板设计模式/观察者设计模式/策略设计模式/责任链设计模式
34 0
|
4月前
|
设计模式 算法 C++
【C++ 策略设计模式 】
【C++ 策略设计模式 】
|
9月前
|
设计模式 算法 搜索推荐
设计模式—策略(Strategy)模式
设计模式—策略(Strategy)模式
131 1
|
8月前
|
设计模式 算法
策略设计模式介绍与应用实战
策略设计模式介绍与应用实战
33 0