zoukankan      html  css  js  c++  java
  • 结构类型7-6:装饰器模式(Decorator Pattern)

    1. 概述

    动态地给一个对象添加一些额外的职责。就增加功能来说,Decorator模式相比生成子类更为灵活。装饰器模式允许向一个现有的对象添加新的功能,同时又不改变其结构。

    这种模式创建了一个装饰类,用来包装原有的类,并在保持类方法签名完整性的前提下,提供了额外的功能。

    2. 介绍

    2.1 意图

    动态地给一个对象添加一些额外的职责。就增加功能来说,装饰器模式相比生成子类更为灵活。

    2.2 主要解决

    一般的,我们为了扩展一个类经常使用继承方式实现,由于继承为类引入静态特征,并且随着扩展功能的增多,子类会很膨胀。

    2.3 何时使用

    在不想增加很多子类的情况下扩展类。

    2.4 如何解决

    将具体功能职责划分,同时继承装饰者模式。

    2.5 关键代码

    1、Component 类充当抽象角色,不应该具体实现。 2、修饰类引用和继承 Component 类,具体扩展类重写父类方法。

    2.6应用实例

    1、孙悟空有 72 变,当他变成"庙宇"后,他的根本还是一只猴子,但是他又有了庙宇的功能。 2、不论一幅画有没有画框都可以挂在墙上,但是通常都是有画框的,并且实际上是画框被挂在墙上。在挂在墙上之前,画可以被蒙上玻璃,装到框子里;这时画、玻璃和画框形成了一个物体。

    2.7 优点

    装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能。

    2.8 缺点

    多层装饰比较复杂。

    2.9 使用场景

    1、扩展一个类的功能,在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。

    2、处理那些可以撤消的职责,动态增加功能,动态撤销。

    3、当不能采用生成子类的方法进行扩充时。

    2.10 注意事项

    可代替继承。

    3. 参与者

    1.Component
    	定义一个对象接口,可以给这些对象动态地添加职责。
    
    2.ConcreteComponent
    	定义一个对象,可以给这个对象添加一些职责。
    
    3.Decorator
    	维持一个指向Component对象的指针,并定义一个与Component接口一致的接口。
    
    4.ConcreteDecorator
    	向组件添加职责。
    

    4. 类图

    在这里插入图片描述

    5. 例子

    5.1 Componen

    public interface Person {
        void eat();
    }
    

    5.2 ConcreteComponen

    public class Man implements Person {
    		public void eat() {
    				System.out.println("男人在吃");
    		}
    }
    

    5.3 Decorator

    public abstract class Decorator implements Person {
        protected Person person;
        public void setPerson(Person person) {
            this.person = person;
        }
        public void eat() {
            person.eat();
        }
    }
    

    5.4 ConcreteDecorator

    public class ManDecoratorA extends Decorator {
        public void eat() {
            super.eat();
            reEat();
            System.out.println("ManDecoratorA类");
        }
    
        public void reEat() {
            System.out.println("再吃一顿饭");
        }
    }
    
    public class ManDecoratorB extends Decorator {
        
        public void eat() {
            super.eat();
            System.out.println("===============");
            System.out.println("ManDecoratorB类");
        }
    }
    

    Test

    public class Test {
    
        public static void main(String[] args) {
            Man man = new Man();
            ManDecoratorA md1 = new ManDecoratorA();
            ManDecoratorB md2 = new ManDecoratorB();
            
            md1.setPerson(man);
            md2.setPerson(md1);
            md2.eat();
        }
    }
    

    result

    男人在吃
    再吃一顿饭
    ManDecoratorA类
    ===============
    ManDecoratorB类
    

    6. 示例2

    我们将创建一个 Shape 接口和实现了 Shape 接口的实体类。然后我们创建一个实现了 Shape 接口的抽象装饰类 ShapeDecorator,并把 Shape 对象作为它的实例变量。

    RedShapeDecorator 是实现了 ShapeDecorator 的实体类。

    DecoratorPatternDemo,我们的演示类使用 RedShapeDecorator 来装饰 Shape 对象。
    在这里插入图片描述

    public interface Shape {
        void draw();
    }
    
    class Rectangle implements Shape{
        @Override
        public void draw() {
            System.out.println("Shape: Rectangle");
        }
    }
    
    class Circle implements Shape{
        @Override
        public void draw() {
            System.out.println("Shape: Circle");
        }
    }
    
    abstract class ShapeDecorator implements Shape {
        protected Shape decoratedShape;
    
        public ShapeDecorator(Shape decoratedShape){
            this.decoratedShape = decoratedShape;
        }
    
        public void draw(){
            decoratedShape.draw();
        }
    }
    
    class RedShapeDecorator extends ShapeDecorator {
    
        public RedShapeDecorator(Shape decoratedShape) {
            super(decoratedShape);
        }
    
        @Override
        public void draw() {
            decoratedShape.draw();
            setRedBorder(decoratedShape);
        }
    
        private void setRedBorder(Shape decoratedShape){
            System.out.println("Border Color: Red");
        }
    }
    
    class DecoratorPatternDemo {
        public static void main(String[] args) {
    
            Shape circle = new Circle();
            ShapeDecorator redCircle = new RedShapeDecorator(new Circle());
            ShapeDecorator redRectangle = new RedShapeDecorator(new Rectangle());
            //Shape redCircle = new RedShapeDecorator(new Circle());
            //Shape redRectangle = new RedShapeDecorator(new Rectangle());
            System.out.println("Circle with normal border");
            circle.draw();
    
            System.out.println("
    Circle of red border");
            redCircle.draw();
    
            System.out.println("
    Rectangle of red border");
            redRectangle.draw();
        }
    }
    
  • 相关阅读:
    PDF文件中的Form保存问题
    Understanding IP Fragmentation
    tcp ip guide IPsec IKE
    Windows安全事件日志中的事件编号与描述
    Cisco PIX fix up and Juniper firewall FTP ALG
    很好的IPSec介绍,详细解释了IKE协商的2个阶段的作用
    virtualbox 下运行Ubuntu 8.10的分辨率和guest additions的问题。
    Fixing the ‘Do you want to display nonsecure items’ message
    windows xp 开始菜单里面所有项目右键不起作用。
    HP backup and recovery manager
  • 原文地址:https://www.cnblogs.com/daozhangblog/p/12446365.html
Copyright © 2011-2022 走看看