zoukankan      html  css  js  c++  java
  • 装饰模式笔记

    菜鸟教程连接https://www.runoob.com/design-pattern/decorator-pattern.html

    UML类图入下 :

    在Java的IO流的类图

    解决的问题 :

    • 想给一个类扩展功能,但是不想继承

    • 可以动态扩展功能,撤消功能(不知到体现在哪里)

    • 需要给已有的类扩展功能,并且要添加新字段时可用

    • 可以改变装饰顺序,参考java的io流

      InputStream input = null;
      input = new BufferedInputStream(new GZIPInputStream(new DataInputStream(new FileInputStream("file.txt"))));
      
      input = new GZIPInputStream(new DataInputStream(new BufferedInputStream(new FileInputStream("file.txt"))));
      

    注意点:

    • 装饰器需要继承自被装饰者

    概括:

    • 装饰器需要继承自被装饰者
    • 装饰器有一个被装饰者成员变量,重写接口时可以调用该成员变量的函数

    用到的地方:

    • JDK的IO流

    实现:

    现在我们要做个画图工具,如上面的类图,目前我们已有一个Shape图形接口

    两个具体图形类Rect和Circle,现在我们想要添加一个画红色图形的功能,但是又不想动那两个图形类(不想继承),于是可以添加一个装饰器类,该装饰器拥有图形的所有功能draw(),并且还有扩展的功能setRedBorde()可以画出红色图形,具体做法就是:装饰器实现图形接口,有一个图形成员变量shape,通过构造函数设置shape,实现的接口可以直接调用shape->draw(),于是就可以在装饰器里添加新的功能setRedBorde()了。

    代码如下:

    原来已经有的图形接口Shape和两个具体实现类RectCircle

    // 原来已有的图形接口 
    class Shape : public MajiaoObject { 
        public :  
            Shape() {  } 
            ~Shape() {  } 
    
            // 图形接口类的绘制方法
            virtual void draw() { }
    }; 
    
    // 具体长方形类
    class Rect : public Shape { 
        public :  
        	int w, h;
            Rect() {  } 
            ~Rect() {  } 
            virtual void draw() { cout << "矩形绘制算法" << endl; }
    }; 
    
    // 具体圆形类
    class Circle : public Shape { 
        public :  
        	int r, d;
            Circle() {  } 
            ~Circle() {  } 
            virtual void draw() { cout << "Bresenham画圆算法" << endl; }
    }; 
    

    现在我们要扩展新功能画红色图形,不想去挨个继承RectCircle

    于是有了装饰器类

    // 装饰器接口,必须继承被装饰者的接口 
    class ShapeDecorator : public Shape { 
        public :  
            // 被装饰的对象
            Shape* shape;
        	// 使用构造设置成员变量
            ShapeDecorator(Shape* shape) { this->shape = shape; } 
            ~ShapeDecorator() {  } 
    }; 
    
    // 实现一个具体的装饰器【红色绘制图形装饰器】 
    class RedShapeDecorator : public ShapeDecorator { 
        public :  
            // 调用父类的构造
            RedShapeDecorator(Shape* shape) : ShapeDecorator(shape) {  } 
            ~RedShapeDecorator() {  } 
    
            virtual void draw() {
                // 调用被装饰者的draw
                if (shape) { 
                    setRedBorde(); // 设置画笔颜色
                    shape->draw();
                }
            }
    
            // 给原来的图形类添加一个设置边框为红色的功能,但是不需要继承原来的类
            virtual void setRedBorde() { cout << "画笔设置成红色了" << endl; }
    }; 
    

    在调用方就可以嵌套new(装饰对象)

    • 类似于java的io流
    // 可以实现像 java IO流的嵌套 new 
    Shape *mainRect = new BackgroudShapeDecorator(new RedShapeDecorator(new Rect())), // 先装饰边框颜色,再装饰背景色
          *mainCircle = new RedShapeDecorator(new BackgroudShapeDecorator(new Circle())); // 先装饰背景色,再装饰边框颜色
    mainRect->draw();
    mainRect->draw();
    
  • 相关阅读:
    css 弹出框
    net stop 出现1060错误
    a href=#与 a href=javascript:void(0) 的区别
    ubuntu如何安装Mac主题
    js arguments.callee & caller的用法及区别
    js函数——setinterval和setTimeout
    highcharts简介
    highcharts柱状图和饼图的数据填充
    jqgrid的外观重绘
    laravel定时任务
  • 原文地址:https://www.cnblogs.com/majiao61/p/14902756.html
Copyright © 2011-2022 走看看