HeadFirst设计模式-策略模式-鸭子类的策略模式实现

本文通过鸭子类的例子介绍了策略模式的应用,强调了设计原则——将可能变化的部分独立出来,使用接口编程而非实现编程。文章展示了如何通过组合而非继承来实现鸭子行为的动态变化,如飞行和叫声,允许在运行时动态改变鸭子的行为。通过这种方式,系统具有更高的灵活性和可扩展性,体现了多用组合少用继承的设计原则。
摘要由CSDN通过智能技术生成

接《HeadFirst设计模式-策略模式-鸭子类的常规实现》上文,当前场景下,推荐做法是使用组合。引入一个设计原则:

设计原则

找出应用中可能需要变化之处,把它们独立出来,不要和那些不需要变化的代码混在一起。

这里会经常发生变化的是飞行和叫声行为,则将这两个行为抽出单独成类。

飞行行为flyBehavior,叫声行为quackBehavior。

那么,具体如何设计这两个行为呢。我们希望一切都能有弹性,毕竟,正是因为一开始的鸭子行为没有弹性,才让我们走上现在这条路。我们还想能够指定行为到鸭子的实例。比如,想要产生绿头鸭实例,并指定特性类型的飞行行为给它。干脆顺便让鸭子的行为可以动态地改变好了。话句话说,我们应该在鸭子类中包含设定行为的方法,就可以在运行时动态地改变绿头鸭的飞行行为。

为了实现这个目标,引入第二个设计原则:

设计原则

针对接口编程,而不是针对实现编程。

也就是这次鸭子类不会负责具体实现飞行接口和叫声接口,反而是由其他类专门实现飞行行为和叫声行为。

这样,实际的行为就不会被绑死在鸭子的子类中。

代码实例:

public abstract class Duck {
    FlyBehavior flyBehavior;
    QuackBehavior quackBehavior;
    public abstract void display();
    
    public void performFly() {
        flyBehavior.fly();
    }
    
    public void performQuack() {
        quackBehavior.quack();
    }
    
    public void swim() {
        System.out.println("swim");
    }
}
public class MallardDuck extends Duck {
    public MallardDuck() {
        // 具体行为实现
        quackBehavior = new QuackNormal();
        flyBehavior = new FlyWithWings();
    }
}

具体实例的调用

public static void main(String[] args) {
    Duck mallard = new MallardDuck();
    mallard.performQuack();
    mallard.performFly();
}

动态设定行为

现在在鸭子里建立的动态功能还没有用到,我们可以在鸭子子类通过设定方法(setter method)来设定鸭子的行为,而不是在鸭子的构造器内实例化

在Duck类中,加入两个新方法:

public void setFlyBehavior(FlyBehavior fb) {
    flyBehavior = fb;
}

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

从此以后,我们可以随时调用这两个方法改变鸭子的行为。

小结

通过本例子,可以继续引出一个设计原则

设计原则

多用组合,少用继承。

如你所见,使用组合建立系统具有很大的弹性,不仅可将算法封装成类,更可以在运行时动态地改变行为。

这就是策略模式,将会变化的算法分别封装起来,让它们之间可以互相替换,让算法的变化独立于使用算法的客户。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值