内容抄自《设计模式》清华大学出版社,2011
动机:替代继承
定义:动态给一个对象增加一些额外的功能,比生成子类更灵活
结构分析:
包含角色:
1.Component(抽象构件)
2.ConcreteComponent(具体构件)
3.Decorator(抽象装饰类)
4.ConcreteDecorator(具体装饰类)
模式分析: 核心在于抽象装饰类
public class Decorator implements Component{
private Component component;
@Override
public void operation(){
component.operation();
}
}
优点:
1.装饰模式可以提供比继承更多的灵活性
2.可以通过一种动态的方式来扩展一个对象的功能,通过配置文件在运行时选择不同的装饰器,从而实现不同的行为
3.具体构件类与具体装饰类可以独立变化,客户可以根据需要添加具体构件类和具体装饰类,在使用时进行组合,符合开闭原则
缺点:
1.使用时产生很多小对象,增加系统复杂性
2.比继承更容易出错,排查的难度也加大
适用环境:
1.以动态透明的方式给一个类添加动态的功能
2.不用继承或不能用继承(final)
模式应用:InputStream
扩展:
1.简化,如果只有一个具体构件类,而没有抽象构件类,则抽象装饰类可以直接作为具体构件的子类
2.简化,如果只有一个具体装饰类,则可以把抽象装饰类和具体的职责合并
3.透明和半透明,就是指调用抽象构件类new对象的时候使用什么类名
与适配器的区别:
装饰器与适配器都有一个别名叫做 包装模式(Wrapper),它们看似都是起到包装一个类或对象的作用,但是使用它们的目的很不一一样。适配器模式的意义是要将一个接口转变成另一个接口,它的目的是通过改变接口来达到重复使用的目的。
而装饰器模式不是要改变被装饰对象的接口,而是恰恰要保持原有的接口,但是增强原有对象的功能,或者改变原有对象的处理方式而提升性能。所以这两个模式设计的目的是不同的。
模式起源猜想:
/** 装饰器
* @author Administrator
*
*/
public class DecoratorModel {
//继承法,缺乏灵活性代码是死的
static class Pic{
public void show(){
System.out.println("这是一张图片");
}
}
static class PicEx extends Pic{
@Override
public void show(){
super.show();
System.out.println("加边框");
}
}
static class PicExEx extends PicEx{
@Override
public void show(){
super.show();
System.out.println("挂在墙上");
}
}
public static void mainOld(String[] args) {
Pic pic = new PicExEx();
pic.show();
}
//继承法----------------------------------
//包装法
static class Phone{
public void show(){
System.out.println("这是一个手机");
}
}
static class PhoneWrapper{
private Phone phone;
public void show(){
phone.show();
System.out.println("加个手机壳");
}
}
static class PhoneWrapperWrapper{
private PhoneWrapper phoneWrapper;
public void show(){
phoneWrapper.show();
System.out.println("再加个手机壳");
}
}
//这样包装也太麻烦了吧
//办法1
static interface Mark{
public void show();
}
static class Adapter implements Mark{
protected Phone phone;
public Adapter(Phone phone) {
super();
this.phone = phone;
}
@Override
public void show(){
phone.show();
}
}
static abstract class AdapterWrap implements Mark{
protected Mark mark;
public AdapterWrap(Mark mark) {
this.mark = mark;
}
@Override
public abstract void show();
}
static class AdapterWrap1 extends AdapterWrap{
public AdapterWrap1(Mark mark) {
super(mark);
}
@Override
public void show() {
this.mark.show();
System.out.println("加个鸡蛋");
}
}
static class AdapterWrap2 extends AdapterWrap{
public AdapterWrap2(Mark mark) {
super(mark);
}
@Override
public void show() {
this.mark.show();
System.out.println("再加个鸡蛋");
}
}
public static void main(String[] args) {
Phone phone = new Phone();
Adapter adapter = new Adapter(phone);
AdapterWrap adapterWrap1 = new AdapterWrap1(adapter);
AdapterWrap adapterWrap2 = new AdapterWrap2(adapterWrap1);
adapterWrap2.show();
}
//在phone能继承的情况下
static abstract class AbsD extends Phone{
protected AbsD absd;
public AbsD(AbsD absd) {
super();
this.absd = absd;
}
@Override
public abstract void show();
}
}