装饰者模式:使用装饰者模式可以动态的给对象加上新的任务,使用组合去完成新的任务。如果有新的功能,只需要调用不同的任务组合,或是新增任务,而不需要修改以前的任务,符合java程序的对扩展开放,对修改关闭的原则。
装饰者模式可以分为以下几类角色:
1、抽象构件角色:定义一个接口,定义接受责任的抽象方法
2、具体构件角色:定义一个接受责任的类,实现抽象构件角色
3、装饰角色: 持有一个构件对象的实例,并定义一个与抽象构件接口一致的接口
4、具体装饰角色:继承自装饰角色,实现不同的装饰任务
下面看具体的代码:
首先定义抽象构件角色早晨,定义起床这件事
package com.test.decorate;
/**
* 抽象构件角色
*
*/
public interface Morning {
publicvoid wakeUp();
}
然后定义具体构件角色人类起床,实现抽象构件角色
package com.test.decorate;
/**
* 具体构件角色
*
*/
public class Human implements Morning{
@Override
publicvoid wakeUp() {
System.out.println("humanwakeup!");
}
}
定义装饰角色,其中定义一个抽象构件的实例,实现起床这件事
package com.test.decorate;
/**
* 装饰角色
*
*/
public class DoSomething implementsMorning{
/**
* 抽象构件角色的实例
*/
privateMorning morning;
publicDoSomething(Morning morning) {
super();
this.morning= morning;
}
@Override
publicvoid wakeUp() {
morning.wakeUp();
}
}
最后定义具体的装饰角色,对起床这件事进行装饰
具体装饰角色—刷牙
package com.test.decorate;
/**
* 具体装饰角色
*
*/
public class BrushTeeth extendsDoSomething{
publicBrushTeeth(Morning morning) {
super(morning);
this.wakeUp();
}
@Override
publicvoid wakeUp(){
System.out.println("brushteeth");
}
}
具体装饰角色—洗脸
package com.test.decorate;
/**
*具体装饰角色
*
*/
public class WashFace extends DoSomething{
publicWashFace(Morning morning) {
super(morning);
this.wakeUp();
}
@Override
publicvoid wakeUp(){
System.out.println("washface");
}
}
具体装饰角色—上厕所
package com.test.decorate;
/**
* 具体装饰角色
*
*/
public class GotoWashRoom extendsDoSomething{
publicGotoWashRoom(Morning morning) {
super(morning);
}
@Override
publicvoid wakeUp(){
System.out.println("goto washroom");
}
}
客户端调用时,根据每个人早晨起床要做的事进行调用
package com.test.decorate;
public class Client {
publicstatic void main(String[] args) {
Morningmorning = new Human();
MorningbrushTeeth = new BrushTeeth(morning);
MorningwashFace = new WashFace(brushTeeth);
MorninggotoWashRoom = new GotoWashRoom(washFace);
gotoWashRoom.wakeUp();
}
}
运行结果:
装饰者模式的优点:
装饰者模式可以动态的为类添加功能,避免了复杂的继承关系,而且很容易扩展,符合java的对扩展开放,对修改关闭的代码设计原则。
装饰者模式的缺点:
装饰者模式的程序比较复杂,不利于理解和排查问题。