美文网首页
装饰模式

装饰模式

作者: Simple_a | 来源:发表于2019-03-12 23:06 被阅读0次

    装饰模式又名包装模式。装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案。

    动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更灵活。

    原理:

    增加一个修饰类包裹原来的类,包裹的方式一般是通过在将原来的对象作为修饰类的构造函数的参数。装饰类实现新的功能,但是,在不需要用到新功能的地方,它可以直接调用原来的类中的方法。修饰类必须和原来的类有相同的接口。

    好处:

    1. 使主功能和附加功能相分离,可独立扩展。
    2. 降低主功能和附加功能之间的耦合性。

    模式中的角色

    类图:

    image

    2.1 抽象构建(Component):定义一个抽象接口,用以给这些对象动态地添加职责。

    2.2 具体构建(ConcreteComponent):定义一个具体的对象,也可以给这个对象添加一些职责。这个类是主功能类。

    2.3 装饰类(Decorator): 装饰抽象类,继承了Component,从外类来扩展Component类的功能。

    2.4 具体装饰者(Decorator1,2,3):负责给构建对象添加职责。附加功能类。

    下面是具体代码实现:

    抽象构件类:装饰类的公共接口

        public interface Component {  
            void sampleOperation();  
        }  
    

    具体构件类(主功能类):

            public class ConcreteComponent implements Component{  
          
            public ConcreteComponent() {  
                  
            }  
            @Override  
            public void sampleOperation() {  
                /*
                * 实现主功能
                */
                System.out.println("ConcreteComponent");  
            }  
              
        }  
    

    装饰类(所有附加功能类的父类):

        public class Decorator implements Component{  
            protected Component component;  
            public Decorator(Component component) {  
                this.component = component;//component为对另一个类对象的引用  
            }  
            public Decorator() {}  
            @Override  
            public void sampleOperation() {
                /*
                * 实现附加功能
                */
                component.sampleOperation();  
            }  
              
        }  
    

    具体装饰类(附加功能类):Decorator1

        public class Decorator1 extends Decorator{  
            public Decorator1(Component component) {  
                super(component);  
            }  
          
            @Override  
            public void sampleOperation() {
                /*
                * 实现附加功能
                */
                System.out.println("Decorator1");  
                component.sampleOperation();  
            }  
          
        }  
    

    具体装饰类(附加功能类):Decorator2

        public class Decorator2 extends Decorator {  
          
            public Decorator2(Component component) {  
                super(component);  
                  
            }  
          
            @Override  
            public void sampleOperation() {  
                /*
                * 实现附加功能
                */
                System.out.println("Decorator2");  
                component.sampleOperation();  
            }  
        }  
    

    具体装饰类(附加功能类):Decorator3

        public class Decorator3 extends Decorator{  
          
            public Decorator3(Component component) {  
                super(component);  
            }  
          
            @Override  
            public void sampleOperation() {  
                /*
                * 实现附加功能
                */  
                System.out.println("Decorator3");  
                component.sampleOperation();  
            }  
              
        }  
    

    客户端:调用了Decorator1的sampleOperation(),实现了四个功能。

        public class TestDecorator {  
          
            public static void main(String[] args) {  
                //定义主功能类
                ConcreteComponent c = new ConcreteComponent();
                
                //定义三个附加功能类。
                Decorator1 d1 = new Decorator3(c);
                Decorator2 d2 = new Decorator2(d1);
                Decorator1 d3 = new Decorator1(d2);//将三个功能都交给Decorator3
                //实现功能
                d1.sampleOperation();
            }  
          
        }  
    

    输出:

    Decorator3

    Decorator2

    Decorator1

    ConcreteComponent

    总结:

    优点:

    1. 比静态继承更灵活 与对象的静态继承相比,Decorator模式提供了更加灵活的向对象添加职责的方式,可以使用添加和分离的方法,用装饰在运行时刻增加和删除职责.
    2. 降低主功能和附加功能之间的耦合性。
    3. 降低了主功能类的复杂度,遵循了开闭原则。

    适用情景:

    1. 当需要为已有功能动态地添加更多功能时。
    2. 类的核心功能无需改变,只是需要添加新的功能时。

    相关文章

      网友评论

          本文标题:装饰模式

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