1 概述
装饰者与被装饰者拥有共同的超类,继承的目的是继承类型,而不是行为;Java的I/O就是使用的装饰者模式,装饰者模式,动态地将责任附加到对象上。若要扩展功能,装饰者提供了比继承更加有弹性的替代方案。
2 装饰者模式的优缺点
1、装饰者模式可以提供比继承更多的灵活性
2、可以通过一种动态的方式来扩展一个对象的功能,在运行时选择不同的装饰器,从而实现不同的行为。
3、通过使用不同的具体装饰类以及这些装饰类的排列组合,可以创造出很多不同行为的组合。可以使用多个具体装饰类来装饰同一对象,得到功能更为强大的对象。
4、具体构件类与具体装饰类可以独立变化,用户可以根据需要增加新的具体构件类和具体装饰类,在使用时再对其进行组合,原有代码无须改变,符合“开闭原则”。
缺点
1、会产生很多的小对象,增加了系统的复杂性
2、这种比继承更加灵活机动的特性,也同时意味着装饰模式比继承更加易于出错,排错也很困难,对于多次装饰的对象,调试时寻找错误可能需要逐级排查,较为烦琐。
3 适用场景1、在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。
2、需要动态地给一个对象增加功能,这些功能也可以动态地被撤销。 当不能采用继承的方式对系统进行扩充或者采用继承不利于系统扩展和维护时。
4 代码
装饰者和被装饰者共同的超类
public interface Project {
public void doCoding();
}
public abstract class Manager implements Project {
private Project coder;
public Manager(Project coder) {
super();
this.coder = coder;
}
@Override
public void doCoding() {
doBefore();
coder.doCoding();
doAfter();
}
public abstract void doBefore();
public abstract void doAfter();
}
public class CEO extends Manager {
public CEO(Project coder) {
super(coder);
// TODO 自动生成的构造函数存�?
}
@Override
public void doBefore() {
System.out.println("我是CEO,我负责项目的前期接洽工作");
}
@Override
public void doAfter() {
System.out.println("我负责陪同客户吃饭");
}
}
public class Manag extends Manager {
public Manag(Project coder) {
super(coder);
// TODO 自动生成的构造函数存�?
}
@Override
public void doBefore() {
System.out.println("我是项目经理,我负责任务分析,任务的拆解");
}
@Override
public void doAfter() {
System.out.println("我是项目经理,我负责乙方项目验收");
}
}
public class Leader extends Manager {
public Leader(Project coder) {
super(coder);
// TODO 自动生成的构造函数存�?
}
@Override
public void doBefore() {
System.out.println("我是项目组长,我来分配任务");
}
@Override
public void doAfter() {
System.out.println("我是项目组长,我负责抽查代码");
}
}
public class Coder implements Project {
@Override
public void doCoding() {
System.out.println("我是码农!!!");
}
}
测试类
public class Test {
public static void main(String[] args) {
Coder c = new Coder();
Leader l = new Leader(c);
Manag m = new Manag(l);
CEO ceo = new CEO(m);
ceo.doCoding();
}
}
运行结果