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

第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实现

策略模式的优点

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

策略模式的缺点

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

策略模式的适用场景

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

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

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值