《Head First 设计模式》第一章 - 笔记

本书是本人写的设计模式的笔记,写下核心要点,如果你掌握过设计模式,想快速阅读本书内容,这个笔记适合你阅读。如果你是新手,有 java 基础和 oo 设计原则基础,你适合跟我一样从零阅读本书。

第一章 策略模式

本章要点:

  • OO 原则:封装变化;多用组合少用继承;针对接口编程,不针对实现编程
  • 策略模式

策略模式(Strategy Pattern)是一种行为型设计模式,在策略模式定义了一系列算法或策略,并将每个算法封装在独立的类中,使得它们可以互相替换。

我对策略模式的理解:

解耦与职责分离

  • 没有策略模式的设计中,通常会把多种行为写在同一个类里,用一堆 if-else 或者 switch 来决定执行哪段逻辑。这样代码臃肿、可读性差,也不利于维护。
  • 采用策略模式后,把每一种行为都做成一个独立的策略类,实现同一个接口。上下文(Context)只负责持有一个接口引用、并在适当的时候调用它。

public abstract class Duck {
    // 上下文(Context)只负责持有一个接口引用、并在适当的时候调用它
    protected FlyBahavior flyBahavior;
    protected QuackBehavior quackBehavior;

    public Duck(){

    }

    /**
     * 鸭子飞行能力委托给行为接口
     */
    public void performFly(){
        flyBahavior.fly();
    }

    // 委托给行为接口
    public void performQuack() {
        quackBehavior.quack();
    }
// ...... 

}

动态可替换与运行时灵活性

  • 过向上下文注入不同的策略实例,或者在运行中调用 setStrategy(),就能立刻改变程序的行为,而不用改动或重编译现有类。
  • 这对需求常变、或者在不同场景下要使用不同算法的系统来说,提供了极大的灵活性。例如,同一个支付模块里,可以在支付宝、微信、银行卡之间动态切换支付策略。

符合开闭原则

  • 单个策略类职责单一、代码量小,非常适合单元测试。
  • 同样的策略也可以在不同的上下文中复用,比如在一个图像处理项目里,对同一张图片做不同滤镜,只要把滤镜算法抽成策略,就能在多个处理流程里共享。

本章有一个鸭子的实例,使用了策略模式实现

如下图,将鸭子的能力拆分并封装,组合到Duck类中,实现高内聚低耦合,灵活扩展鸭子的能力。另外在 Duck 类中有 setFlyBehavior() 和 setQuackBehavior 支持动态改变鸭子的行为。

贴上代码:

行为接口

// FlyBehavior.java
public interface FlyBehavior {
    void fly();
}

// QuackBehavior.java
public interface QuackBehavior {
    void quack();
}

行为实现类

// FlyWithWings.java —— 可以飞
public class FlyWithWings implements FlyBehavior {
    @Override
    public void fly() {
        System.out.println("I'm flying with wings!");
    }
}

// FlyNoWay.java —— 不能飞
public class FlyNoWay implements FlyBehavior {
    @Override
    public void fly() {
        System.out.println("I can't fly.");
    }
}

// Quack.java —— 正常叫声
public class Quack implements QuackBehavior {
    @Override
    public void quack() {
        System.out.println("Quack!");
    }
}

// Squeak.java —— 吱吱叫(橡皮鸭)
public class Squeak implements QuackBehavior {
    @Override
    public void quack() {
        System.out.println("Squeak!");
    }
}

// MuteQuack.java —— 沉默,不叫
public class MuteQuack implements QuackBehavior {
    @Override
    public void quack() {
        System.out.println("<< Silence >>");
    }
}

Duck 抽象类

// Duck.java
public abstract class Duck {
    // 组合:持有行为接口引用
    protected FlyBehavior flyBehavior;
    protected QuackBehavior quackBehavior;

    public Duck() {}

    // 委托给行为接口
    public void performFly() {
        flyBehavior.fly();
    }

    public void performQuack() {
        quackBehavior.quack();
    }

    // 动态设置行为
    public void setFlyBehavior(FlyBehavior fb) {
        flyBehavior = fb;
    }

    public void setQuackBehavior(QuackBehavior qb) {
        quackBehavior = qb;
    }

    // 每个具体鸭子必须实现自己的展示方法
    public abstract void display();
}

鸭子实现类

// MallardDuck.java —— 绿头鸭,会飞会叫
public class MallardDuck extends Duck {
    public MallardDuck() {
        // 构造时注入具体行为
        flyBehavior = new FlyWithWings();
        quackBehavior = new Quack();
    }

    @Override
    public void display() {
        System.out.println("I'm a real Mallard duck!");
    }
}

// RedheadDuck.java —— 红头鸭,会飞会叫
public class RedheadDuck extends Duck {
    public RedheadDuck() {
        flyBehavior = new FlyWithWings();
        quackBehavior = new Quack();
    }

    @Override
    public void display() {
        System.out.println("I'm a real Redhead duck!");
    }
}

// RubberDuck.java —— 橡皮鸭,不能飞,会吱吱叫
public class RubberDuck extends Duck {
    public RubberDuck() {
        flyBehavior = new FlyNoWay();
        quackBehavior = new Squeak();
    }

    @Override
    public void display() {
        System.out.println("I'm a rubber duck!");
    }
}

// DecoyDuck.java —— 诱饵鸭,不能飞,不会叫
public class DecoyDuck extends Duck {
    public DecoyDuck() {
        flyBehavior = new FlyNoWay();
        quackBehavior = new MuteQuack();
    }

    @Override
    public void display() {
        System.out.println("I'm a decoy duck!");
    }
}

模拟测试鸭子各个功能

// MiniDuckSimulator.java
public class MiniDuckSimulator {
    public static void main(String[] args) {
        // 创建不同类型的鸭子
        Duck mallard = new MallardDuck();
        Duck redhead = new RedheadDuck();
        Duck rubber = new RubberDuck();
        Duck decoy = new DecoyDuck();

        System.out.println("--- Mallard Duck ---");
        mallard.display();
        mallard.performFly();
        mallard.performQuack();

        System.out.println("\n--- Rubber Duck ---");
        rubber.display();
        rubber.performFly();
        rubber.performQuack();

        // 动态更改行为示例
        System.out.println("\n--- Dynamic Behavior Change ---");
        Duck model = new MallardDuck();
        model.display();
        model.performFly();   // 默认:用翅膀飞
        // 给模型鸭装上火箭
        model.setFlyBehavior(new FlyNoWay() {
            @Override
            public void fly() {
                System.out.println("I'm flying with a rocket!");
            }
        });
        model.performFly();   // 现在会“火箭飞”
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值