美文网首页
一起来学习设计模式:装饰器模式

一起来学习设计模式:装饰器模式

作者: __y | 来源:发表于2018-10-22 10:54 被阅读4次

    1.装饰器模式的概念

    装饰器模式(Decorator Pattern)允许像一个显示有的对象添加新功能,同时又不改变其结构;是对现有类的一个包装
    创建一个装饰类,来包装原有的类,比如说汽车已经有行驶的功能了,我想锦上添花,在车上加个音箱,这样是不是帅呆了。

    • 作用:动态地给一个对象增加新的功能
    • 要解决的问题:其实看到新增功能这几个字,我们应该想到JAVA中的三大特性中的继承,也可以实现类似的功能,那么为什么还要用装饰器模式呢。这是因为随着我们的系统的扩展,如果我们不断继承的话,子类会越来越多,难以管理
    • 如何实现:
      1、Component 类充当抽象角色,不应该具体实现。
      2、修饰类引用和继承 Component 类,具体扩展类重写父类方法。
      优点:解耦合,不会影响原本的类,是继承的一个替代模式
      缺点:如果功能过多,多层装饰会很麻烦

    2.实现

    image.png

    step1:

    我们还是按图上说的先定义一个Shape接口,和两个实现类;

    public interface Shape {
        void draw();
    }
    
    
    public class Rectangle implements Shape {
        @Override
        public void draw() {
            System.out.println("This is rectangle");
        }
    }
    
    public class Circle implements Shape {
        @Override
        public void draw() {
            System.out.println("This is Circle");
        }
    }
    

    step2:

    装饰器类

    public abstract class ShapeDecorator implements Shape{
        protected Shape decoratedShape;
    
        public ShapeDecorator(Shape decoratedShape) {
            this.decoratedShape = decoratedShape;
        }
    
        public void draw(){
            decoratedShape.draw();
        }
    }
    

    step3:

    这里我们就要扩展新的功能了

    public 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");
        }
    }
    
    

    step4:

    测试程序

    public class DecoratorPatternDemo {
        public static void main(String[] args) {
            Shape circle = new Circle();
            Shape readCircle = new RedShapeDecorator(new Circle());
            System.out.println("Circle with normal border");
            circle.draw();
            System.out.println("Circle of red border");
            readCircle.draw();
        }
    }
    
    image.png

    3.总结:

    其实我们从上面一个简简单单的实例来看,貌似和继承也没多少差别。而且从代码理解上来看,直接继承省心省力多了。但是,我们想想,如果我们的系统越来越大了,要继承的类越来越多,那么我们的.java文件也会越来越多,也许某天你要改功能了就要满世界找,这很影响效率,而如果我们集中在一个装饰类里面管理的话,那将会非常简单,想加啥,减啥,都非常简单,毕竟你全部东西都写在那了,不用看满天的子类了。
    比较经典的装饰器的应用我们可以看看JAVA 的IO的源码~
    参考:
    http://www.runoob.com/design-pattern/decorator-pattern.html

    相关文章

      网友评论

          本文标题:一起来学习设计模式:装饰器模式

          本文链接:https://www.haomeiwen.com/subject/iwywzftx.html