Head First之策略模式
1、策略模式的定义
策略模式定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户。
2、鸭子设计
2.1 需求
定义绿头鸭,红头鸭,橡胶鸭,诱饵鸭(前俩个都是普通鸭子,外观不同,橡胶鸭不会飞,诱饵鸭不会飞也不会叫)
2.2 设计方式1(一般实现)
这种设计应该说是我们大多数人下意识都会想到的,既通过超类抽取了游泳和外观的方法(继承抽取共性,所有的鸭子都会游泳,所有的鸭子都有外貌,当然fly()方法和quack()方法也可以抽取到父类中,子类重写,但是你要这么写,可能你的上司就要找你谈心让你回炉重造了),又通过接口来实现不同鸭子的不同需求(诱饵鸭不会飞就不实现Flyable接口,橡胶鸭呱呱叫就实现Quackable接口。
当我第一次看到这个设计的时候,觉得没毛病,如果是我的话我也会这么做,可是它实在不是一个值得称赞的设计。
2.3 设计方式2 (优化)
①很明显,这样设计增加了我们的代码量(多了两个类实现接口),但是这样做飞行动作和呱呱叫的动作就可以复用了,不必再被迫关联到鸭子超类。
②此外,我们可以动态增加一些行为,又不会对原有的行为造成影响。
3、代码实现
①实现鸭子的基本逻辑

public abstract class Duck { public FlyBehavior flyBehavior; public QuackBehavior quackBehavior; public Duck() { // TODO Auto-generated constructor stub } public abstract void display(); public void performFly() { flyBehavior.fly(); } public void performQuack() { quackBehavior.quack(); } public void swim() { System.out.println("All ducks float, even decoys!"); } }

public interface FlyBehavior { public void fly(); }

public class FlyNoWay implements FlyBehavior{ @Override public void fly() { // TODO Auto-generated method stub System.out.println("I can't fly"); } }

public class FlyWithWings implements FlyBehavior{ @Override public void fly() { // TODO Auto-generated method stub System.out.println("I can fly"); } }

public interface QuackBehavior { public void quack(); }

public interface QuackBehavior { public void quack(); }

public class Squeak implements QuackBehavior{ @Override public void quack() { // TODO Auto-generated method stub System.out.println("squeak"); } }

public class MuteQuack implements QuackBehavior{ @Override public void quack() { // TODO Auto-generated method stub System.out.println("silence"); } }

public class MallardDuck extends Duck{ public MallardDuck() { flyBehavior = new FlyWithWings(); quackBehavior = new Quack(); } public void display() { System.out.println("I'm a real Mallard duck"); } }
MallardDuck
public class MiniDuckSimulator {
public static void main(String[] args) {
Duck mallark = new MallardDuck();
mallark.performFly();
mallark.performQuack();
}
}
运行结果
I can fly
Quack
②动态设定鸭子的行为
Duck类中新增set方法
public void setFlyBehavior(FlyBehavior fb) {
flyBehavior = fb;
}
public void setQuackBehavior(QuackBehavior qb) {
quackBehavior = qb;
}
定义鸭子类型模型鸭

public class ModelDuck extends Duck { public ModelDuck() { // TODO Auto-generated constructor stub flyBehavior = new FlyNoWay(); quackBehavior = new Quack(); } @Override public void display() { // TODO Auto-generated method stub System.out.println("I'm a model duck"); } }
定义火箭飞行行为

public class FlyRocketPowered implements FlyBehavior { @Override public void fly() { // TODO Auto-generated method stub System.out.println("I'm flying with a rocket"); //定义火箭飞行 } }
改变测试类
public class MiniDuckSimulator {
public static void main(String[] args) {
Duck mallark = new MallardDuck();
mallark.performFly();
mallark.performQuack();
Duck model = new ModelDuck();
model.performFly();
model.setFlyBehavior(new FlyRocketPowered()); //动态设定行为
model.performFly();
}
}
运行结果
I can fly
Quack
I can't fly
I'm flying with a rocket
设计总览
4.小结
这个是书上的例子,它很全面但是它不好,它讲得不清楚,更不易理解,虽然结合实际但是看了还是让人不知道什么时候用。所以暂时先放在这里,过段时间写篇易理解的。这篇着实难懂,但我还是不会删它,因为理解了策略模式,你只会觉得这篇just so so.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· Vue3状态管理终极指南:Pinia保姆级教程
2020-02-10 java内存模型