设计模式学习笔记(8)--装饰模式

1.定义

       装饰模式(Decorator Pattern) :动态地给一个对象增加一些额外的职责(Responsibility),就增加对象功能来说,装饰模式比生成子类实现更为灵活。其别名也可以称为包装器(Wrapper),与适配器模式的别名相同,但它们适用于不同的场合。它是一种对象结构型模式。

2.UML图

(1)组件的uml图

(2)变形金刚的uml图

3.代码

(1)组件的代码:

package com.wuhuiskiff.www.decorator.code.component;

/**
 * @Auther: 一叶扁舟
 * @Date: 2019/2/11 15:48
 * @Description:
 */
public abstract class Component {
    public abstract void operation();
}
package com.wuhuiskiff.www.decorator.code.component;

/**
 * @Auther: 一叶扁舟
 * @Date: 2019/2/11 15:51
 * @Description:
 */
public class ConcreteComponent extends Component {
    @Override
    public void operation() {
        //具体的组件
        System.out.println("具体的组件");
    }
}
package com.wuhuiskiff.www.decorator.code.component;

/**
 * @Auther: 一叶扁舟
 * @Date: 2019/2/11 15:52
 * @Description:装饰器
 */
public class Decorator extends Component{
    private Component component;

    @Override
    public void operation() {
        this.component.operation();
    }

    public Decorator(Component component) {
        this.component = component;
    }


}
package com.wuhuiskiff.www.decorator.code.component;

/**
 * @Auther: 一叶扁舟
 * @Date: 2019/2/11 16:00
 * @Description:
 */
public class ConcreteDecoratorA extends Decorator {

    @Override
    public void operation() {
        // 调用原有的业务方法
        super.operation();
        // 调用新增的方法
        this.changeStatus();
    }

    public ConcreteDecoratorA(Component component) {
        super(component);

    }

    public void changeStatus(){
        System.out.println(" ConcreteDecoratorA 改变组件的状态。。。");
    }
}
package com.wuhuiskiff.www.decorator.code.component;

/**
 * @Auther: 一叶扁舟
 * @Date: 2019/2/11 16:03
 * @Description:
 */
public class ConcreteDecoratorB extends Decorator {
    @Override
    public void operation() {
        super.operation();
        this.changeBehavior();
    }

    public ConcreteDecoratorB(Component component) {
        super(component);
    }

    public void changeBehavior(){
        System.out.println("ConcreteDecoratorB 改变行为状态。。。");

    }
}
package com.wuhuiskiff.www.decorator.code.component;

/**
 * @Auther: 一叶扁舟
 * @Date: 2019/2/11 16:06
 * @Description:
 */
public class ClientTest {
    public static void main(String[] args) {
        Component component = new ConcreteComponent();
        Decorator decorator = new ConcreteDecoratorA(component);
        decorator.operation();
        System.out.println("---------------------------");
        decorator = new ConcreteDecoratorB(component);
        decorator.operation();

    }
}

(2)变形金刚代码

package com.wuhuiskiff.www.decorator.code.car;

/**
 * @Auther: 一叶扁舟
 * @Date: 2019/2/11 16:29
 * @Description: 变形金刚接口
 */
public interface TransForm {
     void move();
}
package com.wuhuiskiff.www.decorator.code.car;

/**
 * @Auther: 一叶扁舟
 * @Date: 2019/2/11 16:30
 * @Description:
 */
public class Car implements TransForm {
    public Car() {
        System.out.println("变形金刚是一辆车。。。");
    }

    @Override
    public void move() {
        System.out.println("车可以在地面上移动。。。");
    }
}
package com.wuhuiskiff.www.decorator.code.car;

/**
 * @Auther: 一叶扁舟
 * @Date: 2019/2/11 16:31
 * @Description:变形
 */
public class Changer implements TransForm {
    private TransForm transForm;

    public Changer(TransForm transForm) {
        this.transForm = transForm;
    }

    @Override
    public void move() {
        this.transForm.move();
    }
}
package com.wuhuiskiff.www.decorator.code.car;

/**
 * @Auther: 一叶扁舟
 * @Date: 2019/2/11 16:36
 * @Description:
 */
public class Airplane extends Changer {
    public Airplane(TransForm transForm) {
        super(transForm);
        System.out.println("变形金刚变成了飞机。。。");
    }

    @Override
    public void move() {
        super.move();
    }


    public void fly(){
        System.out.println("变形金刚变成了飞机,可以飞。。。");
    }
}
package com.wuhuiskiff.www.decorator.code.car;

/**
 * @Auther: 一叶扁舟
 * @Date: 2019/2/11 16:32
 * @Description:
 */
public class Robot extends Changer {
    public Robot(TransForm transForm) {
        super(transForm);
        System.out.println("变形金刚变成了机器人。。。");
    }

    @Override
    public void move() {
        super.move();
    }
    public void say(){
        System.out.println("变形金刚变成了机器人,可以说话。。。");
    }
}
package com.wuhuiskiff.www.decorator.code.car;

/**
 * @Auther: 一叶扁舟
 * @Date: 2019/2/11 16:39
 * @Description:
 */
public class ClientTest {
    public static void main(String[] args) {
        TransForm transForm = new Car();
        transForm.move();
        System.out.println("--------------------------");
        Changer changer;
        Airplane airplane = new Airplane(transForm);
        airplane.move();
        //fly是对原有的move方法的扩展
        airplane.fly();
        System.out.println("============================");
        Robot robot = new Robot(transForm);
        robot.move();
        robot.say();
    }
}

4.优缺点

(1)装饰模式的优点

     装饰模式与继承关系的目的都是要扩展对象的功能,但是装饰模式可以提供比继承更多的灵活性。

      可以通过一种动态的方式来扩展一个对象的功能,通过配置文件可以在运行时选择不同的装饰器,从而实现不同的行为。

       通过使用不同的具体装饰类以及这些装饰类的排列组合,可以创造出很多不同行为的组合。可以使用多个具体装饰类来装饰同一对象,得到功能更为强大的对象。

        具体构件类与具体装饰类可以独立变化,用户可以根据需要增加新的具体构件类和具体装饰类,在使用时再对其进行组合,原有代码无须改变,符合“开闭原则”。

(2)装饰模式的缺点

     使用装饰模式进行系统设计时将产生很多小对象,这些对象的区别在于它们之间相互连接的方式有所不同,而不是它们的类或者属性值有所不同,同时还将产生很多具体装饰类。这些装饰类和小对象的产生将增加系统的复杂度,加大学习与理解的难度。

      这种比继承更加灵活机动的特性,也同时意味着装饰模式比继承更加易于出错,排错也很困难,对于多次装饰的对象,调试时寻找错误可能需要逐级排查,较为烦琐。



5.应用

(1) 在javax.swing包中,可以通过装饰模式动态给一些构件增加新的行为或改善其外观显示。 如JList构件本身并不支持直接滚动,即没有滚动条,要创建可以滚动的列表,可以使用如下代码实现:

JList list = new JList();

JScrollPane sp = new JScrollPane(list); 

(2). 装饰模式在JDK中最经典的实例是Java IO。

以InputStream为例:

6.总结

       装饰模式用于动态地给一个对象增加一些额外的职责,就增加对象功能来说,装饰模式比生成子类实现更为灵活。它是一种对象结构型模式。

      装饰模式包含四个角色:

  抽象构件定义了对象的接口,可以给这些对象动态增加职责(方法);

  具体构件定义了具体的构件对象,实现了在抽象构件中声明的方法,装饰器可以给它增加额外的职责(方法);

抽象装饰类是抽象构件类的子类,用于给具体构件增加职责,但是具体职责在其子类中实现;

具体装饰类是抽象装饰类的子类,负责向构件添加新的职责。

使用装饰模式来实现扩展比继承更加灵活,它以对客户透明的方式动态地给一个对象附加更多的责任。装饰模式可以在不需要创造更多子类的情况下,将对象的功能加以扩展。

猜你喜欢

转载自blog.csdn.net/u011662320/article/details/87031774
今日推荐