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.(动态地给一个对象添加一些额外的职责。就增加功能来说,装饰模式相比生成子类更为灵活。)

    装饰模式有四个角色:
    1.Component抽象构件
    Component是一个接口或者是抽象类,就是定义我们最核心的对象,也就是最原始的对
    象。
    2.ConcreteComponent 具体构件
    ConcreteComponent是最核心、最原始、最基本的接口或抽象类的实现,你要装饰的就是
    它。
    3.Decorator装饰角色
    一般是一个抽象类,做什么用呢?实现接口或者抽象方法,它里面可不一定有抽象的方
    法呀,在它的属性里必然有一个private变量指向Component抽象构件。
    4.具体装饰角色
    ConcreteDecoratorA和ConcreteDecoratorB是两个具体的装饰类,你要把你最核心的、最
    原始的、最基本的东西装饰成其他东西。

    具体请看例子:
    Car

    /**
     * @author shuliangzhao
     * @Title: Car
     * @ProjectName design-parent
     * @Description: TODO
     * @date 2019/6/13 23:26
     */
    public abstract class Car {
    
        public abstract void driver();
    }
    

    AudiCar

    /**
     * @author shuliangzhao
     * @Title: AudiCar
     * @ProjectName design-parent
     * @Description: TODO
     * @date 2019/6/13 23:27
     */
    public class AudiCar extends Car {
        @Override
        public void driver() {
            System.out.println("速度为每小时50KM");
        }
    }
    

    DecoratorCar

    /**
     * @author shuliangzhao
     * @Title: DecoratorCar
     * @ProjectName design-parent
     * @Description: TODO
     * @date 2019/6/13 23:28
     */
    public abstract class DecoratorCar extends Car{
    
        private Car car;
    
        public DecoratorCar(Car car) {
            this.car = car;
        }
    
        @Override
        public void driver() {
            car.driver();
        }
    }
    
    

    BlueAudiCar

    /**
     * @author shuliangzhao
     * @Title: BlueAudiCar
     * @ProjectName design-parent
     * @Description: TODO
     * @date 2019/6/13 23:31
     */
    public class BlueAudiCar extends DecoratorCar {
    
        public BlueAudiCar(Car car) {
            super(car);
        }
    
        @Override
        public void driver() {
            this.color();
            super.driver();
        }
    
        private void color() {
            System.out.println("蓝色奥迪车");
        }
    }
    
    /**
     * @author shuliangzhao
     * @Title: BmwCar
     * @ProjectName design-parent
     * @Description: TODO
     * @date 2019/6/13 23:30
     */
    public class RedAudiCar extends DecoratorCar {
    
        public RedAudiCar(Car car) {
            super(car);
        }
    
        @Override
        public void driver() {
            this.color();
            super.driver();
        }
    
        private void color() {
            System.out.println("红色奥迪车");
        }
    }
    

    客户端

    /**
     * @author shuliangzhao
     * @Title: Client
     * @ProjectName design-parent
     * @Description: TODO
     * @date 2019/6/13 23:32
     */
    public class Client {
    
        public static void main(String[] args) {
            Car car = new AudiCar();
            car.driver();
            Car redCar = new RedAudiCar(car) ;
            redCar.driver();
            Car blueCar = new BlueAudiCar(car);
            blueCar.driver();
        }
    }
    

    运行结果

     
    image.png

    装饰模式优点:

    1.装饰类和被装饰类可以独立发展,而不会相互耦合。
    2.装饰模式是继承关系的一个替代方案。
    3.可以动态扩展类。

    装饰模式缺点:

    多层的装饰是比较复杂。

    装饰模式使用场景:

    需要动态地给一个对象增加功能、需要扩展一个类的功能。

    举个简单例子可以看出装饰模式的好处:三个继承关系Father、Son、GrandSon三个类,我要在Son类上增强一些功能怎么办?我想你会坚决地顶回去!不允许,对了,为什么呢?你增强的功能是修改Son类中的方法吗?增加方法吗?对GrandSon的影响呢?特别是GrandSon有多个的情况,你会怎么办?这个评估的工作量就够你受的,所以这是不允许的,那还是要解决问题的呀,怎么办?通过建立SonDecorator类来修饰Son,相当于创建了一个新的类,这个对原有程序没有变更,通过扩展很好地完成了这次变更。

    注意:继承是静态地给类增加功能,而装饰模式则是动态地增加功能。

  • 相关阅读:
    A1141. PAT Ranking of Institutions
    A1140. Look-and-say Sequence
    A1139. First Contact
    A1138. Postorder Traversal
    A1137. Final Grading
    A1136. Delayed Palindrome
    A1135. Is It A Red-Black Tree
    A1134. Vertex Cover
    A1133. Splitting A Linked List
    layer.open打开iframe页面的调用父页面方法及关闭
  • 原文地址:https://www.cnblogs.com/treeshu/p/11020503.html
Copyright © 2011-2022 走看看