装饰者设计模式
简介
装饰者模式是一种更加灵活的扩展类的功能的方法。传统的拓展一个类的功能最常用的就是继承(JAVA的三大特性之一)。但是如果修改原有的类,那么久违背了“开闭原则”。如果一味的为了新功能就去使用继承结构,那么就会导致子类膨胀,难以维护。装饰者模式就是在不使用继承的情况下扩展类的功能,而且可以灵活的组合调用。
类图
实现方式
package com.rabbit.pattern.decorator;
/**
* 奶茶抽象类
* Created by vip on 2018/2/27.
*/
public abstract class MilkyTea {
public abstract void make();//制作奶茶
}
package com.rabbit.pattern.decorator;
/**
* 珍珠奶茶类
* Created by vip on 2018/2/27.
*/
public class Pearl extends MilkyTea {
@Override
public void make() {
System.out.println("加入珍珠......");
}
}
package com.rabbit.pattern.decorator;
/**
* 珍珠奶茶装饰类
* Created by vip on 2018/2/27.
*/
public abstract class MilkyTeaDecorator extends MilkyTea {
private MilkyTea mt;//保存要装饰的对象,使用抽象而不是具体,这样具体的类只有在执行的时候才找到
public MilkyTeaDecorator(MilkyTea mt) {
this.mt = mt;
}
@Override
public void make() {
if (mt != null) {
mt.make();
}
}
}
package com.rabbit.pattern.decorator;
/**
* 加入果冻功能
* Created by vip on 2018/2/27.
*/
public class JellyDecorator extends MilkyTeaDecorator {
public JellyDecorator(MilkyTea mt) {
super(mt);
}
@Override
public void make() {
super.make();
System.out.println("加入果冻......");
}
}
package com.rabbit.pattern.decorator;
/**
* 加入烧仙草功能
* Created by vip on 2018/2/27.
*/
public class MesonaDecorator extends MilkyTeaDecorator {
public MesonaDecorator(MilkyTea mt) {
super(mt);
}
@Override
public void make() {
super.make();
System.out.println("加入烧仙草......");
}
}
package com.rabbit.pattern.decorator;
/**
* Created by vip on 2018/2/27.
*/
public class Demo {
//装饰者模式可以随意组合扩展的功能
public static void main(String[] args) {
//做法一:先加入珍珠,果冻,烧仙草
System.out.println("制作珍珠奶茶做法一开始......");
Pearl p = new Pearl();
JellyDecorator jd = new JellyDecorator(p);
MesonaDecorator md = new MesonaDecorator(jd);
md.make();
//做法二:先加入珍珠,烧仙草,果冻
System.out.println("制作珍珠奶茶做法二开始......");
Pearl p1 = new Pearl();
MesonaDecorator md1 = new MesonaDecorator(p1);
JellyDecorator jd1 = new JellyDecorator(md1);
jd1.make();
}
}
总结
使用场景
1)扩展一个类的功能而不想使用继承。
2)动态添加或者撤销类的功能。
优点
装饰类和被装饰类可以独立发展,不会相互耦合,装饰者模式其实可以看做是继承的一种替代方案,但是装饰者模式可以动态的扩展一个类的功能。
缺点
当多层装饰的时候类会显得比较复杂。