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 使用场景

    • 需要扩展一个类的功能,或给一个类增加附加功能。
    • 需要动态地给一个对象增加功能,这些功能可以再动态地撤销。
    • 需要为一批的兄弟类进行改装或加装功能,当然是首选装饰模式。
  • 相关阅读:
    PHP 实现简易 IOC 容器
    MySQL 5.7原生JSON格式支持
    PHP 使用 array_map 替代 foreach
    深入了解PHP闭包的使用以及实现
    PHP补全固定数字位数前面有0的值
    面试技巧
    Flex 布局语法教程
    如何在phpexcel中设置自动高度(自动换行)?
    宝塔面板和wdcp有什么区别?哪个比较好用?
    linux下如何查找nginx配置文件的位置
  • 原文地址:https://www.cnblogs.com/f-zhao/p/6227592.html
Copyright © 2011-2022 走看看