装饰者模式在JAVA语言中是一种较为重要的设计模式,尤其在“流”的类中作用极为显著,大大提高了使用各种流时的效率。
定义:动态的给对象添加一些附加的职责。当需要对已有对象进行功能增强时,可以定义装饰类,将已有对象传入,在已有功能的基础之上,进行功能的增强,那么这个自定义的类便成为了装饰类。
从装饰者模式的定义中可以看出,它和JAVA语言的三大特性之一的继承有着相似之处,继承是子类通过继承父类,可重写父类中的方法也可实现方法的扩展,但他们两种设计结构有着截然不同的地方:首先装饰者模式的代码结构比继承会更加简洁;同时装饰者模式可以提供比继承更多的灵活性,对于一个抽象装饰类而言,既可以对同一对象进行不同的装饰,也可以对不同的对象进行相同的修饰,最关键的一点是没有破坏对象本身的核心方法的执行,仅仅实在其核心方法之上对对象加以修饰而已,这点同样和继承有着不一样的设计思想。
注:在装饰者模式中也用到了类之间组合的关系,对于类之间的关系这点也可以深挖,有时间可以去认真了解一下。
接下来通过一个恋爱的例子来设计一个装饰者模式的Demo,学生可以谈恋爱,工人也可以谈恋爱,学生谈恋爱的方式多样,工人谈恋爱的方式也很多样。
1.首先定义一个抽象构建角色(Compponent):给出一个抽象的接口,以规范接收附加责任的对象,相当于IO流里的InputStream/OutputStream.
在这个Demo里边定义一个Love接口作为抽象构建角色,Love()方法即为被修饰角色需要被扩展的方法:
package decorator;
//抽象构建角色
public interface Love {
public void Love();
}
2.定义具体的构建角色(可有多个具体构建角色)(ConcreteComponent):构建角色即为将要接收附加责任的类,这些类需要实现抽象构建角色的接口,实现里面的方法,相当于IO流里的 FileInputStream/FileOutputStream
在这个Demo里边定义两个类:Student类与Worker类:
package decorator;
//具体构建角色
public class Student implements Love{
//实现抽象构建角色的方法,该方法为学生对象的核心方法,装饰类将该方法进行扩展.
public void Love() {
System.out.println("学生谈恋爱。。。");
}
}
package decorator;
public class Worker implements Love{
public void Love(){
System.out.println("工人谈恋爱。。");
}
}
3.定义抽象装饰者角色类(Decorator):这个类要持有抽象构建角色的引用(体现了组合的类关系),同时定义一个含有该引用的构造方法,并且实现这个抽象构造接口,即直接调用父接口的方法即可
在该Demo中即定义一个Decorator类:
package decorator;
//抽象装饰角色:持有一个抽象构建角色的引用,并实现这个抽象构建接口,相当于FilterInputStream/FilterOutputStream
public class Decorator implements Love{
private Love love;
public Decorator(Love love){
this.love = love;
}
public void Love(){
this.love.Love();
}
}
4.定义具体的装饰角色(可以有多个具体装饰角色):在该类中就是给构建角色加上附加的责任,重点是自己的责任也要完成的。
在该Demo中定义两个装饰类:
package decorator;
public class ConcreteDecorator1 extends Decorator{
public ConcreteDecorator1(Love love){
super(love);
}
//开始进行一个装饰方法
public void Love(){
System.out.println("相识。。。");
super.Love(); //调用父类的Love()方法已得到具体对象的核心行为
System.out.println("分手。。。");
}
}
package decorator;
public class ConcreteDecorator2 extends Decorator{
public ConcreteDecorator2(Love love){
super(love);
}
//装饰工人的Love方法
public void Love(){
System.out.println("相识。。。");
super.Love();
System.out.println("结婚。。。");
}
}
以上就是装饰者模式的设计结构,从该结构中可以看出,抽象构建角色和抽象装饰角色在本结构中起着至关重要的作用,正是因为这两种结构的存在,使得一个对象可被多种装饰器修饰,一个装饰器也可以修饰多个对象。这样的代码结构真是非常灵活啊。
写一个测试类:
package decorator;
public class TestDecorator {
public static void main(String[] args) {
//装饰学生了
Love love1 = new Student();
ConcreteDecorator1 cds = new ConcreteDecorator1(love1);
cds.Love();
System.out.println("***********************");
Love love2 = new Student();
ConcreteDecorator2 cds2 = new ConcreteDecorator2(love2);
cds2.Love();
System.out.println("*************************");
//装饰工人了
Love love3 = new Worker();
ConcreteDecorator2 cdo = new ConcreteDecorator2(love3);
cdo.Love();
}
}
测试结果为:
以上就是本人对装饰者模式的理解。