设计模式之策略模式--慕课网笔记

来源:互联网 发布:阿里云邮箱app 编辑:程序博客网 时间:2024/06/09 21:35
第1章 引子:什么是策略模式
1-1 策略模式简介
  1. 什么是策略模式
  2. 策略模式如何实现
  3. 策略模式总结篇
  4. 实际案例分享

日常生活中的例子:

  • 文本编辑软件–》布局 –》布局算法
    • 算法实现1
    • 算法实现2
    • 算法实现3
  • 购物–》支付–》支付算法
    • 招商银行
    • 建设银行
    • XXX银行

共同点:

  • 抽象出不变部分
  • 定义算法族分别封装起来
  • 客户端不会受算法改变的影响
  • 对新增需求弹性的支持

策略模式将可变的部分从程序中抽象分离成算法接口,在改接口下分别
封装一系列算法实现并使他们可以相互替换,从而导致客户端程序独立
独立于算法的改变。

第2章 光荣与梦想——鸭子应用:策略模式的实现
2-1 光荣与梦想:模拟应用背景介绍

光荣与梦想:鸭子应用

  • 飞行的能力
  • 更多类型的鸭子
  • 每六个月发布一款产品

  • 鸭子的鸣叫

  • 鸭子的显示
  • 原有的功能
  • 飞行的能力
2-2 求索之路:鸭子如何才能飞

原有代码

/* * 超类,所有的鸭子都要继承此类 * 抽象了鸭子的行为:显示和鸣叫 */public abstract class Duck {    /*     * 鸭子发出叫声     * 通用行为,由超类实现     */    public void quack(){        System.out.println("嘎嘎嘎");    }    /*     * 显示鸭子的外观     * 鸭子的外观各不相同,声明为abstract, 由子类实现     */    public abstract void display();}
public class MallardDuck extends Duck {    public MallardDuck(){        super();    }    @Override    public void display() {        System.out.println("我的脖子是绿色的");    }}
public class RedheadDuck extends Duck {    public RedheadDuck(){        super();    }    @Override    public void display() {        System.out.println("我的头是红色的");    }}

让我们的鸭子飞起来
方案一:
在父类中提供实现方法,子类通过继承获得父类中的飞行行为

public void fly(){    System.out.println("用翅膀飞行");}
  • 优点
    • 简(cu)单(bao)易(chou)用(lou),已有应用可以快速添加飞行的能力
  • 缺点
    • 不具有灵活性,对未来变更支持差。
    • 需要通过在子类中覆写飞行的方法以提供新的飞行行为。这很容易造成错误(粗心的程序员忘记覆写)。

方案二:抽象方法
在父类中提供抽象方法,强迫子类实现自己的飞行行为

public abstract void fly();
  • 优点
    • 足够灵活。
    • 小伙伴再也不会忘记覆写代码了。
  • 缺点
    • 累死小伙伴了。
    • 每个子类都要实现一遍代码,及时是相同的行为也不例外。
    • 代码重复,没有复用代码。
2-3 柳暗花明:策略让鸭子飞上天

集成是重用代码的利器
但继承并不总是最好的工具

Favor composition over inheritace ———— Effective Java
复合优先与继承
多用组合,少用继承

面向对象 组合
Car has-a Tyre
汽车通过使用轮胎获得轮胎的能力

在类中增加一个私有域,引用另一个已有的类的实例,通过调
用引用实例的方法从而获得新的功能,这种设计被称作组合(复合)。

方案三:组合
将飞行行为抽象为接口,在父类中持有该接口,并由该接口代理飞行行为。

public interface FlyingStragety{    void performFly();}
private FlyingStragety flyingStragety;public void fly(){    flyingStragety.performFly();}
  • 优点
    • 足够灵活。
    • 复用代码,更易于维护。
  • 缺点
    • 见第三章总结中缺点
2-4 脚踏实地:用代码放飞鸭子
/* * 策略接口,实现鸭子的飞行行为 */public interface FlyingStragety {    void performFly();}
/* * 超类,所有的鸭子都要继承此类 * 抽象了鸭子的行为:显示和鸣叫 */public abstract class Duck {    /*     * 鸭子发出叫声     * 通用行为,由超类实现     */    public void quack(){        System.out.println("嘎嘎嘎");    }    /*     * 显示鸭子的外观     * 鸭子的外观各不相同,声明为abstract, 由子类实现     */    public abstract void display();    private FlyingStragety flyingStragety;    public void setFlyingStragety(FlyingStragety flyingStragety) {        this.flyingStragety = flyingStragety;    }    public void fly(){        flyingStragety.performFly();    }}
public class FlyWithWin implements FlyingStragety {    public void performFly() {        System.out.println("振翅高飞");    }}
public class MallardDuck extends Duck {    public MallardDuck(){        super();        super.setFlyingStragety(new FlyWithWin());    }    @Override    public void display() {        System.out.println("我的脖子是绿色的");    }}
public class RedheadDuck extends Duck {    public RedheadDuck(){        super();        super.setFlyingStragety(new FlyWithWin());    }    @Override    public void display() {        System.out.println("我的头是红色的");    }}
public class DuckTest {    public static void main(String[] args){        System.out.println("测试鸭子程序");        System.out.println("************************");        Duck duck = null;//      duck = new MallardDuck();        duck = new RedheadDuck();        duck.display();        duck.quack();        duck.fly();        System.out.println("************************");        System.out.println("测试完毕");    }}
2-5 拥抱变化:用策略模式提供高复用性代码

新加两款产品,不能飞行

public class FlyNoWay implements FlyingStragety {    public void performFly() {        System.out.println("我不会飞行!");    }}
public class RubberDuck extends Duck {    public RubberDuck() {        super();        super.setFlyingStragety(new FlyNoWay());    }    @Override    public void display() {        System.out.println("我全身发黄,嘴巴很红");    }    public void quack(){        System.out.println("嘎~嘎~嘎~");    }}
public class BigYellow extends Duck {    public BigYellow() {        super();        super.setFlyingStragety(new FlyNoWay());    }    @Override    public void display() {        System.out.println("我身体很大,全身黄黄");    }}
2-6 万变不离其宗:向宇宙进军

新增太空鸭

public class FlyWithRocket implements FlyingStragety {    public void performFly() {        System.out.println("用火箭在太空遨游");    }}
public class SpaceDuck extends Duck {    public SpaceDuck() {        super();        super.setFlyingStragety(new FlyWithRocket());    }    @Override    public void display() {        System.out.println("我头戴宇航头盔");    }    public void quack(){        System.out.println("我通过无线电与你通信");    }}

橡胶鸭、大黄鸭
- 代码复用
太空鸭
- 更换策略模式

一生二,二生三,三生无穷!

第3章 总结篇
3-1 知识点总结

策略模式中的设计原则

  • 找出应用中需要变化的部分,把他们独立出来,不要和那些不需要变化的代码混在一起。
  • 面向接口编程,而不是面向实现编程。
  • 多用组合,少用继承。

策略模式的实现

  1. 通过分离变化得出的策略接口Strategy
  2. Strategy的实现类
  3. 客户程序“有一个”Strategy
  4. 在客户程序中选择/组装正确的Strategy实现

策略模式的优点

  • 使用了组合,使架构更加灵活
  • 富有弹性,可以较好的应对变化(开—闭原则)
  • 更好的代码复用性(相对于继承)
  • 消除大量的条件语句

策略模式的缺点

  • 客户代码需要了解每个策略实现的细节
  • 增加了对象的数目

策略模式的适用场景

  • 许多相关的类仅仅是行为差异
  • 运行时选取不同的算法变体
  • 通过条件语句在多个分支中选取一

《模式的秘密–策略模式》视频地址

原创粉丝点击