设计模式-装饰器模式

装饰器模式可以动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更有弹性的替代方案。

装饰器和被装饰的对象有两个特点:

1)他们实现同一个接口

2)装饰器中使用了被装饰的对象

1.假设老王来到商店里进行购物,老王可以这样做:

public class LaoWang {

    public void show(){
        System.out.println("我穿上衣服,累计花费100元");
        System.out.println("我穿上裤子,累计花费250元");
        System.out.println("我穿上帽子,花费300元");
    }
}

每买一样东西,老王都得对show方法进行修改,违背了我们开发的开闭原则,所以老王可以使用装饰器模式动态的将需要做的事情添加到对象上。

2.构建装饰器超类,为装饰器提供被装饰的对象

/**
 * 装饰器超类,和被装饰的对象实现同一个接口 Person
 * 作用就是为装饰器类提供被装饰的对象
 * @author yuans
 * @create 2018-10-30-21:02
 */
public class ClothesDecorator implements Person {
    //装饰器中要使用被装饰器的对象,构造方法中传入
    protected Person person;

    public ClothesDecorator(Person person) {
        this.person = person;
    }
    @Override
    public Double cost() {
        return null;
    }

    @Override
    public void show() {

    }
}

3.老王穿上jacket

/**
 * 具体的装饰,夹克
 *
 * @author yuans
 * @create 2018-10-30-21:04
 */
public class Jacket extends ClothesDecorator {
    public Jacket(Person person) {
        super(person);
    }

    @Override
    public void show() {
        person.show();
        System.out.println("穿上夹克,累计消费" + this.cost());
    }

    @Override
    public Double cost() {
        return person.cost() + 100; //夹克100元
    }
}

4.老王穿上帽子

/**
 * 具体的装饰,帽子
 *
 * @author yuans
 * @create 2018-10-30-21:06
 */
public class Hat extends ClothesDecorator {
    public Hat(Person person) {
        super(person);
    }

    @Override
    public void show() {
        //执行已有功能
        person.show();
        //此处是附加的功能
        System.out.println("戴上帽子,累计消费" + this.cost());
    }

    @Override
    public Double cost() {
        return person.cost() + 50; //帽子50元
    }
}

5.测试类

/**
 * 装饰器模式测试类
 * 1.装饰器和被装饰类要实现同一个接口(实际开发中也可能用继承)
 * 2.装饰器中使用了被装饰的对象。
 * @author yuans
 * @create 2018-10-30-21:09
 */
public class DecorateMain {
    public static void main(String[] args) {
//        Person laoWang = new Jacket(new LaoWang());
        Person laoWang = new LaoWang();
        laoWang = new Jacket(laoWang);
        laoWang = new Hat(laoWang);
        laoWang.show();
        System.out.println("买单,老王总共消费:" + laoWang.cost());
    }
}

6.测试结果及总结

装饰器模式的作用是动态给对象增加一些功能,而不需要修改对象本身;扩展功能的方式比较灵活;每一个装饰器相互独立,需要修改时不会互相影响。

原文地址:https://www.cnblogs.com/ysit/p/9879866.html