zoukankan      html  css  js  c++  java
  • 设计模式-装饰模式

    一、定义

    装饰模式(Decorator Pattern)是一种比较常见的模式,其定义如下:Attach additional responsibilities to an object dynamically keeping the same interface.Decorators provide a flexible alternative to subclassing for extending functionality.(动态地给一个对象添加一些额外的职责。 就增加功能来说,装饰模式相比生成子类更为灵活。)

    通用类图如下:

    装饰模式通用类图

    在类图中,有四个角色:

    • Component抽象构件

    Component是一个接口或者是抽象类,就是定义我们最核心的对象,也就是最原始的对象

    注意 在装饰模式中,必然有一个最基本、最核心、最原始的接口或抽象类充当 Component抽象构件。

    • ConcreteComponent 具体构件

    ConcreteComponent是最核心、最原始、最基本的接口或抽象类的实现,你要装饰的就是它。

    • Decorator装饰角色

    一般是一个抽象类,做什么用呢?实现接口或者抽象方法,它里面可不一定有抽象的方 法呀,在它的属性里必然有一个private变量指向Component抽象构件。

    • 具体装饰角色

    ConcreteDecoratorA和ConcreteDecoratorB是两个具体的装饰类,你要把你最核心的、最 原始的、最基本的东西装饰成其他东西。

    //抽象构件 
    public abstract class Component { 
        //抽象的方法 
        public abstract void operate(); 
    }
    
    //具体构件
    public class ConcreteComponent extends Component { 
        //具体实现 
        @Override 
        public void operate() {
            System.out.println("do Something");
        } 
    }
    
    //抽象装饰者
    public abstract class Decorator extends Component { 
        private Component component = null; 
        //通过构造函数传递被修饰者 
        public Decorator(Component _component){
            this.component = _component; 
        } 
        //委托给被修饰者执行 
        @Override 
        public void operate() {
            this.component.operate();
        }
    }
    
    //具体的装饰类
    public class ConcreteDecorator1 extends Decorator {
        //定义被修饰者 
        public ConcreteDecorator1(Component _component){
            super(_component); 
        } 
        //定义自己的修饰方法 
        private void method1(){
            System.out.println("method1 修饰"); 
        } 
        //重写父类的Operation方法 
        public void operate(){ 
            this.method1(); 
            super.operate(); 
        } 
    } 
    
    public class ConcreteDecorator2 extends Decorator {         
        //定义被修饰者 
        public ConcreteDecorator2(Component _component){
            super(_component); 
        }
        //定义自己的修饰方法
        private void method2(){
            System.out.println("method2修饰"); 
        } 
        //重写父类的Operation方法 
        public void operate(){
            super.operate(); 
            this.method2();
        }
    }
    
    //场景类
    public class Client {
        public static void main(String[] args) {
            Component component = new ConcreteComponent(); 
            //第一次修饰 
            component = new ConcreteDecorator1(component); 
            //第二次修饰 
            component = new ConcreteDecorator2(component); 
            //修饰后运行 
            component.operate();
        }
    }
    

    二、应用

    2.1 优点

    • 装饰类和被装饰类可以独立发展,而不会相互耦合。换句话说,Component类无须知 道Decorator类,Decorator类是从外部来扩展Component类的功能,而Decorator也不用知道具 体的构件。
    • 装饰模式是继承关系的一个替代方案。我们看装饰类Decorator,不管装饰多少层,返 回的对象还是Component,实现的还是is-a的关系。
    • 装饰模式可以动态地扩展一个实现类的功能,这不需要多说,装饰模式的定义就是如 此。

    2.2 缺点

    对于装饰模式记住一点就足够了:多层的装饰是比较复杂的。为什么会复杂呢?你想想 看,就像剥洋葱一样,你剥到了最后才发现是最里层的装饰出现了问题,想象一下工作量吧,因此,尽量减少装饰类的数量,以便降低系统的复杂度。

    2.3 使用场景

    • 需要扩展一个类的功能,或给一个类增加附加功能。
    • 需要动态地给一个对象增加功能,这些功能可以再动态地撤销。
    • 需要为一批的兄弟类进行改装或加装功能,当然是首选装饰模式。
  • 相关阅读:
    gain 基尼系数
    luogu P5826 【模板】子序列自动机 主席树 vector 二分
    牛客挑战赛39 树与异或 离线 树上莫队 树状数组 约数
    4.22 省选模拟赛 三元组 manacher 回文自动机
    4.22 省选模拟赛 最优价值 网络流 最大权闭合子图
    4.18 省选模拟赛 消息传递 树剖 倍增 线段树维护等比数列
    luogu P4008 [NOI2003]文本编辑器 splay 块状链表
    牛客挑战赛39 密码系统 后缀数组
    luogu P1526 [NOI2003]智破连环阵 搜索+最大匹配+剪枝
    luogu P4095 [HEOI2013]Eden 的新背包问题 多重背包 背包的合并
  • 原文地址:https://www.cnblogs.com/f-zhao/p/6227592.html
Copyright © 2011-2022 走看看