Head First 设计模式详解之一:策略模式

本文探讨了Head First设计模式中的策略模式,解释了如何将变化的算法独立出来,通过组合而非继承来优化代码。文章通过鸭子类的例子展示了如何利用策略模式解决飞行行为的多样化问题,使得代码更易于维护。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文为Head First设计模式笔记。

什么是策略模式


策略模式是将应用中实现方法多变的算法独立出来,封装为算法族,通过组合或者其他方式,让算法的调用切换独立于算法的调用者。

举个例子 


 我们要设计一个duck鸭子类。我们首先想到设计一个duck基类,然后派生出各种各样的鸭子。

class Duck{
    virtual void display();
    virtual void swim() { std::cout << "swim";}
};

class GreenDuck:public Duck{
    void display(){ std::cout << "GreenDuck";}
};

class RedDuck:public Duck{
    void display(){ std::cout << "RedDuck";}
};

这样设计看似毫无问题,而当我们需要添加fly()飞行属性时,却发现,有的鸭子会飞,有的鸭子却不会飞,不能在基类中,直接定义fly()函数。如果我们使用接口来让会飞的鸭子实现接口,不会飞的鸭子没有接口,这样看似没有问题。但是我们如果有几百种会飞的鸭子,将要把飞行实现几百遍,并且我们还要为每一种鸭子检查接口。因此使用接口并不是一个良好的解决方案。接下来,我们将利用设计模式的思想,优化类的实现。

利用设计模式优化


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

对于fly()函数来说,它是类中的变化部分。让它与基类揉搓在一起,明显不是明智之举,因此我们要把它独立出来,单独封装为一个类。

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

在以往的做法中,我们会将fly等行为声明在基类或者接口,让子类继承,并由子类实现。这两种做法都依赖于“实现”,函数需要在子类中进行定义,函数的实现都与子类的实现相捆绑。

而我们可以将fly独立为一个全新的flyBehavior类,fly通过继承flyBehavior,完成不同的实现,fly动作的实现和Duck子类的实现完全脱离。所以,函数的实现可以与子类的实现相脱离。

3、多用组合,少用继承

在Duck类中,我们可以声明一个flyBehavior类对象。利用组合的方式,将fly动作添加到Duck类中,而不是采取继承的老路,让fly与Duck相捆绑。

优化后的Duck


class FlyBehavior{
public:
    virtual void fly() = 0;
};

class CanFly:public FlyBehavior{
    void fly(){ std::cout << "can Fly";}
};

class CanontFly:public FlyBehavior{
    void fly(){ std::cout << "cannnot fly";}
};
class Duck{
public:
    FlyBehavior* flyType;
    virtual void display() = 0;
    virtual void swim() { std::cout << "swim";}
    void Duckfly() {flyType -> fly();}
};

class GreenDuck:public Duck{
public:
    GreenDuck(){
        flyType = new CanFly();
    }
    void display(){ std::cout << "GreenDuck";}
    ~GreenDuck(){
        delete flyType;
    }
};

从实现可以看出,变化的fly算法被独立出来实现,与算法的调用者Duck实现分开。策略模式可以使我们的代码更加易于维护。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值