关系密切的设计模式(一)

来源:互联网 发布:淘宝换货售后卡怎么写 编辑:程序博客网 时间:2024/04/25 23:30

前言

当我们在开发新功能时,一种功能很难使用单一的设计模式实现。而且设计模式之间,往往有很紧密的关系,在程序开发时,常常会同时使用多个模式。本文总结出一些常用的套路,供参考。同时撰写本文也加深了对设计模式的理解。

工厂模式+策略模式

如果我们要根据不同类型,输出不同格式的数字。

// 策略模式class INumberDisplay {public:    virtual int displayNumber(char* buf, size_t buf_size) const = 0;    virtual ~INumberDisplay() {}    INumberDisplay(int number): _number(number) {}protected:    int _number;};class CUintDisplay : public INumberDisplay {public:    virtual int displayNumber(char* buf, size_t buf_size)  const {        return _snprintf_s(buf, buf_size, buf_size - 1, "%u", (unsigned int)_number);    }    CUintDisplay(unsigned int number) : INumberDisplay((int)number) {}};class CSingedIntDisplay : public INumberDisplay {public:    virtual int displayNumber(char* buf, size_t buf_size)  const {        return _snprintf_s(buf, buf_size, buf_size - 1, "%d", _number);    }    CSingedIntDisplay(int number) : INumberDisplay(number) {}};class CHexDisplay : public INumberDisplay {public:    virtual int displayNumber(char* buf, size_t buf_size)  const {        return _snprintf_s(buf, buf_size, buf_size - 1, "0x%x", _number);    }    CHexDisplay(int number) : INumberDisplay(number) {}};// 工厂模式,其实应该还包括上面对类的定义enum _TYPE {    UINT,    SINGED_INT,    HEX_INT};INumberDisplay* createDisplayClass(int number, _TYPE type) {    switch (type) {    case UINT:        return new CUintDisplay(number);    case SINGED_INT:        return new CSingedIntDisplay(number);    default:        return new CHexDisplay(number);    }}// 执行策略int outputNumber(int number, char* buf, size_t buf_size, _TYPE type) {    // 使用工厂    INumberDisplay *pDisplay = createDisplayClass(number, type);    // 执行策略    int ret = pDisplay->displayNumber(buf, buf_size);    destructDisplayClass(pDisplay); // 实现略,用于释放内存    return ret;}

以上代码可以实现针对不同类型,显示不同格式。实际应用中,INumberDisplay接口中的public方法应该不止一个,使用此方法,可以

  • 将数字的格式化,与outputNumber的实现解耦,后续增加其它显示类型时,可以不修改老代码,只需要新增一个INumberDisplay的派生类;
  • 将所有在实现中的switch/case(或if/else if)包含在工厂方法中,减少代码的复杂度;