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

    装饰器模式

    装饰器模式:动态的为一个实例增加额外的功能,装饰器为通过继承来进行功能扩展提供了另一种途径。

    当通过继承父类来实现功能的扩展不太现实的时候,装饰器模式是一种很好的方式。

    装饰器模式有两个显著的优点:

    优点

    • 优点1:相比静态的继承父类来达到扩展功能,装饰器模式提供更加灵活的方式来增加额外的功能,装饰器模式能够在运行时动态的增加或者减少功能(一次或者多次);
    • 优点2:避免了功能类在继承结构上膨胀;相比与一开始就尝试支持所有可预见的功能,从而设计了一个非常复杂的、自定义的类的方式,装饰器模式则是先定义一个简单的类,然后不断的用装饰器装饰增加功能;由于系统能够自由组合不同的装饰器来达到功能的组合、扩展,因此相比于继承,在子类中就不太会出现冗余的功能;

    缺点:由于装饰器模式中的装饰器类仅仅是在某一方面不同,这样在进行复杂的装饰的时候,会产生特别多的小的、比较像的实例对象(装饰器)。

    装饰器模式含有几部分:

    • Component:定义了能够动态增加功能的对象的接口;
    • ConcreteComponent:Component的实现类
    • Decorator:持有一个需要被装饰的实例的引用(Component引用),接口遵循Component,满足里氏替换原则;
    • ConcreteDecorator:Decorator的实现类;

    JDK里面的InputStream、BufferedInputStream 、DataInputStream、FileInputStream等都是利用装饰器模式。

    装饰器模式从某种程度和代理模式相仿,但是两者还是有些细微的区别:

    1. 装饰器模式关注的是动态增加对象实例的功能;而代理模式关注的则是被代理对象访问的控制;
    2. 装饰器模式是增加类似的功能,是对被装饰类的功能增加;而代理模式则是代理增加非类似的功能

    如果用户更关注的的是装饰器带来的功能,则用装饰器模式;而用户更关注的是原来的被代理类的功能,则使用代理模式。

    UML类图

    这里写图片描述

    实例

    
    public interface Component {
        void operation();
    }
    
    public class ConcreteComponent implements Component {
    
        @Override
        public void operation() {
            // TODO Auto-generated method stub
            System.out.println("ConcreteComponent: operation");
        }
    }
    
    
    public abstract class Decorator implements Component {
        Component component;
    
        public Decorator(Component component) {
            this.component = component;
        }
    }
    
    
    public class DecoratorA extends Decorator {
    
        public DecoratorA(Component component) {
            super(component);
            // TODO Auto-generated constructor stub
        }
    
        @Override
        public void operation() {
            // TODO Auto-generated method stub
            addtionalOperationA();//decorate operation
            this.component.operation();
        }
    
        public void addtionalOperationA() {
            System.out.println("addtionalOperationA");
        }
    
    }
    
    public class DecoratorB extends Decorator {
    
        public DecoratorB(Component component) {
            super(component);
            // TODO Auto-generated constructor stub
        }
    
        @Override
        public void operation() {
            // TODO Auto-generated method stub
            addtionalOperationB();
            this.component.operation();
        }
    
        public void addtionalOperationB() {
            System.out.println("addtionalOperationB");
        }
    
    }
    
    
    public class Main {
    
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            Component component = new ConcreteComponent();
            //开始装饰
            component = new DecoratorA(component);
            component.operation();//仅仅被A装饰
            System.out.println("======");
            component = new DecoratorB(component);
            component.operation();//被B A同时装饰
        }
    }
    

    References

    1. 《设计模式:可复用面向对象软件的基础》
  • 相关阅读:
    DDOS攻击
    定时器任务:Timer跟ScheduledExecutorService
    11、分布式Dubbo+Zokeeper+SpringBoot
    10、springboot中的任务:异步任务、邮件发送、定时任务
    PHP算法之最长公共前缀
    PHP算法之罗马数字转整数
    PHP算法之整数转罗马数字
    PHP-SQL查询上升的温度
    PHP算法之统计全为 1 的正方形子矩阵
    PHP算法之增减字符串匹配
  • 原文地址:https://www.cnblogs.com/Spground/p/9567882.html
Copyright © 2011-2022 走看看