设计模式必知必会系列终章

打印 上一主题 下一主题

主题 612|帖子 612|积分 1836

目录
装饰器模式
工厂方法模式
抽象工厂模式
​编辑
适配器模式
代理模式


装饰器模式

官方定义:   动态地给⼀个对象增加⼀些额外的职责。就增加功能而言,装饰器模式比生成子类更为灵活。 —— 《设计模式》GoF
通俗解释:  装饰器是为了给对象增加额外职责而产生的, 有点粉刷的意思, 房子已经存在了, 在房子的表面加上一层粉刷.      (而且它的优势是相较于继承而言的, 相比直接继承, 装饰器更加灵活, 耦合度更低)                     
应对与  ”过度的采取类继承扩展对象的功能“ 的情况
继承为类型引入的静态特质,使得这种扩展方式缺乏灵活性;并且随着子类的增多(扩展功能的增多),各种子类的组合(扩展功能的组合)会导致子类数量的膨胀。
(继承下来就是实实在在的一份负担, 代码的膨胀, 类的膨胀.)  但是很多时候其实我们没有必要去继承, 完全可以使用组合的方式来根据需求动态的实现对象功能的扩展, 以解决子类数量膨胀的问题. 使得功能扩展所带来的影响,代价最小,没必要说来一个新的功能扩展就新创建一个类。

这个类图其实很奇怪, 我刚看见的时候就在想,为啥又是继承, 又是组合的, 继承是为了复用之前的框架, 接口, 裸机 你只有有了之前的房子,才能粉刷装饰吧, 继承体现的是最初的裸机, 接口, 组合完成动态的修饰, 装饰。  
这个组合还是组合抽象类本身,绝对看的让人很迷,组合的虽然是抽象类本身, 但是抽象类是一个接口,它可以代表它的一切派生类, 这样便使得这个组合对象可扩展性很强.

模式要点:

  • 通过采用组合而非继承的手法,Decorator模式实现了在运行时动态扩展对象功能的能力,而且可以根据需要扩展多个功能。避免了使用继承带来的“灵活性差”和“多子类衍生问题”。
  • Decorator类在接口上表现为is-a Component的继承关系,即Decorator类继承了Component类所具有的接口。但在实现上又表现为has-a Component的组合关系,即Decorator类又使用了另外一个Component类。
  • Decorator模式的目的并非解决“多子类衍生的多继承”问题,Decorator模式应用的要点在于解决“主体类在多个方向上的扩展功能”——是为“装饰”的含义。
记忆技巧:  继承复用接口,组合复用实现细节,动态组合
代码场景: 工资计算, 基本员工的工资是天数*100, 经理员工是基本工资 + 加成add. 老板更是在经理员工的基础上增加10倍加成
实现代码如下:
  1. #include <iostream>
  2. using namespace std;
  3. //此处我没有再写componet类了, 想写的兄弟可以添加喔
  4. class Context {
  5. public:
  6.         int day;//天数
  7.         int add;//加成
  8. };
  9. //分发奖金: 普通员工仅仅只是day * 100  
  10. //经理  还有加成
  11. //老总等等加成更加牛逼, 在经理的基础上再10倍加成
  12. //基础员工工资
  13. //DecoratorClass装饰器基类
  14. class BaseWocker {
  15. public:
  16.         BaseWocker(BaseWocker* _base) : base(_base) {
  17.         }
  18.         virtual int CalculateSlary(Context& ctx) {
  19.                 //计算基本工资
  20.                 return ctx.day * 100;
  21.         }
  22.         virtual ~BaseWocker() {}
  23. protected:
  24.         BaseWocker* base;
  25. };
  26. //继承复用接口
  27. //BaseWocker继承下来的是裸机, 最初框架, 接口
  28. //组合扩展细节. 运算.
  29. class Manager : BaseWocker {
  30. public:
  31.         Manager(BaseWocker* _base = nullptr) : BaseWocker(_base) {
  32.         }
  33.         virtual int CalculateSalary(Context& ctx) {
  34.                 int basesalary = base->CalculateSlary(ctx);
  35.                 //...在组合对象的基础上进行扩展运算
  36.                 return basesalary + ctx.add;
  37.         }
  38. };
  39. //Decorator
  40. class Boss : public BaseWocker {
  41. public:
  42.         Boss(BaseWocker* _base) : BaseWocker(_base) {
  43.         }
  44.         virtual int CalculateSalary(Context& ctx) {
  45.                 int basesalary = base->CalculateSlary(ctx);
  46.                 //...在组合对象的基础上进行扩展运算
  47.                 return (basesalary + (ctx.add * 10));
  48.         }
  49. };
复制代码
如下是大佬写的一份代码: 大家也可以赏析一下:
  1. //业务操作, Component抽象基类
  2. class Stream{
  3. public:
  4.     virtual char Read(int number)=0;
  5.     virtual void Seek(int position)=0;
  6.     virtual void Write(char data)=0;
  7.    
  8.     virtual ~Stream(){}
  9. };
  10. //主体类具体的Component类
  11. class FileStream: public Stream{
  12. public:
  13.     virtual char Read(int number){
  14.         //读文件流
  15.     }
  16.     virtual void Seek(int position){
  17.         //定位文件流
  18.     }
  19.     virtual void Write(char data){
  20.         //写文件流
  21.     }
  22. };
  23. class NetworkStream :public Stream{
  24. public:
  25.     virtual char Read(int number){
  26.         //读网络流
  27.     }
  28.     virtual void Seek(int position){
  29.         //定位网络流
  30.     }
  31.     virtual void Write(char data){
  32.         //写网络流
  33.     }
  34.    
  35. };
  36. class MemoryStream :public Stream{
  37. public:
  38.     virtual char Read(int number){
  39.         //读内存流
  40.     }
  41.     virtual void Seek(int position){
  42.         //定位内存流
  43.     }
  44.     virtual void Write(char data){
  45.         //写内存流
  46.     }
  47.    
  48. };
  49. //扩展操作
  50. //扩展操作采取的是装饰器类, has a 的特征
  51. DecoratorStream: public Stream{
  52. protected:
  53.     Stream* stream;//...
  54.    
  55.     DecoratorStream(Stream * stm):stream(stm){
  56.    
  57.     }
  58.    
  59. };
  60. //具体的decorator类
  61. class CryptoStream: public DecoratorStream {
  62. public:
  63.     CryptoStream(Stream* stm):DecoratorStream(stm){
  64.    
  65.     }
  66.    
  67.    
  68.     virtual char Read(int number){
  69.       
  70.         //额外的加密操作...
  71.         stream->Read(number);//读文件流
  72.     }
  73.     virtual void Seek(int position){
  74.         //额外的加密操作...
  75.         stream::Seek(position);//定位文件流
  76.         //额外的加密操作...
  77.     }
  78.     virtual void Write(byte data){
  79.         //额外的加密操作...
  80.         stream::Write(data);//写文件流
  81.         //额外的加密操作...
  82.     }
  83. };
  84. class BufferedStream : public DecoratorStream{
  85.    
  86.     Stream* stream;//...
  87.    
  88. public:
  89.     BufferedStream(Stream* stm):DecoratorStream(stm){
  90.         
  91.     }
  92.     //...
  93. };
复制代码
工厂方法模式

官方定义: 定义一个用于创建对象的接口,让子类决定实例化哪一个类。Factory Method使得一个类的实例化延迟(目的:解耦,手段:虚函数)到子类。——《设计模式》GoF
通俗解释:简单来说就是在工厂基类中定义一个抽象接口,  将整个接口的实例化延迟到一个具体的子类工厂(具体工厂),解耦合.                     ----    之后对于工厂的依赖都是依赖稳定的工厂基类

这个类图感觉不算特别完善, 最好可以在Factory下面在继承具体的Factory感觉比较好.
实现代码如下:
[code]//抽象产品类class Operator {public:        Operator(int l, int r)                 : lhs(l)                , rhs(r) {        }        //抽象操作        virtual int Operation() = 0;         virtual ~Operator() {}protected:        int lhs;        int rhs;};//具体产品类class AddOperator : public Operator{public:        AddOperator(int l, int r)                : Operator(l, r) {        }        virtual int Operation() {                return lhs + rhs;        }};class SubOperator : public Operator{public:        SubOperator(int l, int r)                : Operator(l, r) {        }        virtual int Operation() {                return lhs - rhs;        }};class MulOperator : public Operator{public:        MulOperator(int l, int r)                : Operator(l, r) {        }        virtual int Operation() {                return lhs * rhs;        }};class DivOperator : public Operator{public:        DivOperator(int l, int r)                : Operator(l, r) {        }        virtual int Operation() {                if (rhs == 0) {                        cerr  r;                cout  op;                OperatorFactory* factory = nullptr;                //创建工厂                switch (op) {                        case '+': {                                factory = new AddOperatorFactory();                        } break;                        case '-': {                                factory = new SubOperatorFactory();                        } break;                        case '*': {                                factory = new MulOperatorFactory();                        } break;                        case '/': {                                factory = new DivOperatorFactory();                        } break;                }                //生产产品运行Operaction                cout CreateMethod(l, r)->Operation()
回复

使用道具 举报

0 个回复

正序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

老婆出轨

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表