设计模式03-装饰模式(Java)
4.4 装饰模式
1.模式定义
不改变现有对象结构的情况下,动态地给该对象增加一些职责(即增加其额外功能)的模式。
2.模式结构
抽象构件角色 :定义一个抽象接口以规范准备接收附加责任的对象。客户端可以方便调用装饰类和被装饰类。
具体构件角色 :实现抽象构件,通过装饰角色为其添加一些职责。
抽象装饰角色 : 继承或实现抽象构件,并包含具体构件的实例,可以通过其子类扩展具体构件的功能。
具体装饰角色 :实现抽象装饰的相关方法,并给具体构件对象添加附加的责任。
3.模式原理
在不改变对象本身的基础之上,给对象添加或删除行为,往往可以通过继承机制或者是关联机制实现
- 继承机制:通过子类对父类的继承,重写或添加新的方法来扩展类
- 关联机制:将一个类的对象嵌入另一个类的对象之中,进而在另一个类中扩展其行为(通过递归嵌套实现多层装饰)
4.代码模板
抽象装饰类
public class Decorator implements Component {
//关联抽象构建
private Component component;
//构造注入具体构建
public Decorator(Component component) {
this.component = component;
}
@Override
public void operation() {
component.operation();
}
}
具体装饰类
public class ConcreteDecorator extends Decorator{
public ConcreteDecorator(Component component) {
super(component);
}
public void operation() {
super.operation();
addBehavior();
}
private void addBehavior() {
//新增方法
}
}
5.案例分析
public interface Call {
public void callMusic();
}
public class Phone implements Call {
public Phone() {
System.out.println("普通手机");
}
@Override
public void callMusic() {
System.out.println("来电话了,手机发出响声");
}
}
public class Decorator implements Call{
private Call call;
public Decorator(Call call) {
this.call = call;
}
public void setCall(Call call) {
this.call = call;
}
@Override
public void callMusic() {
System.out.println("来电话了,手机发出响声");
}
}
public class JarPhone extends Decorator {
public JarPhone(Call call) {
super(call);
System.out.println("振动手机");
}
public void jar() {
super.callMusic();
System.out.println("振动~~~");
}
}
public class LightPhone extends Decorator{
public LightPhone(Call call) {
super(call);
System.out.println("闪光手机");
}
public void light() {
super.callMusic();
System.out.println("闪光~~~");
}
}
public class Main {
public static void main(String[] args) {
Phone phone = new Phone();
System.out.println("电话来了");
phone.callMusic();
System.out.println("————————————————");
JarPhone jarPhone = new JarPhone(phone);
System.out.println("电话来了");
jarPhone.jar();
System.out.println("————————————————");
LightPhone lightPhone = new LightPhone(phone);
System.out.println("电话来了");
lightPhone.light();
System.out.println("————————————————");
//将闪光手机改装成可以振动且闪光的手机
System.out.println("组装手机:");
lightPhone.light();
jarPhone.setCall(lightPhone);
jarPhone.jar();
}
}
6.模式优缺点
7.模式使用场景
8.模式应用
- IO流中使用:InputStream和OutputStream中只提供了简单的读写操作,通过装饰模式可以得到具有文件输入输出的FileInputStream等
- javax.swing中也有大量使用