为什么会有装饰模式?
装饰模式是为了解决继承强依赖性和出现大量子类不方便管理问题而出现的。
1. 概述
动态地给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更灵活。
原理:增加一个修饰类包裹原来的类,包裹的方式一般是通过在将原来的对象作为修饰类的构造函数的参数。装饰类实现新的功能,但是,在不需要用到新功能的地方,它可以直接调用原来的类中的方法。修饰类必须和原来的类有相同的接口。
2. 模式中的角色
2.1 抽象构建(Component):定义一个抽象接口,用以给这些对象动态地添加职责。
2.2 具体构建(ConcreteComponent):定义一个具体的对象,也可以给这个对象添加一些职责。
2.3 装饰类(Decorator): 装饰抽象类,继承了Component,从外类来扩展Component类的功能。
2.4 具体装饰者(ConcretorDecorator):负责给构建对象添加职责。
类图解析:
1)Component:抽象接口,用来统一规范准备被装饰的对象。
2)Concrete Component:具体被装饰类,定义一个将要被装饰的类。
3) Decorator:抽象装饰类,要求与被装饰类拥有一致的接口(这个是必须的,否则没有办法将装饰通过多态传递给 被装饰对象)。
4)Concrete Decorator:具体装饰类,负责给被装饰对象添加功能。
3. 模式总结
3.1 优点
3.1.1 每个装饰对象只关心自己的功能,不需要关心如何被添加到对象链当中。它是由Decorator的SetComponent方法来实现的,因而它们的职责是单一的。
3.1.2 类的核心职责与动态添加的职责是分离的。如果再向主类中添加新的功能,一是违反了开放封闭原则,二是增加了主类的复杂度。
比静态继承更灵活 与对象的静态继承相比,Decorator模式提供了更加灵活的向对象添加职责的方式,可以使用添加和分离的方法,用装饰在运行时刻增加和删除职责.
3.2 缺点
产生许多小对象,采用Decorator模式进行系统设计往往会产生许多看上去类似的小对象,这些对象仅仅在他们相互连接的方式上有所不同。
3.3 适用场景
3.3.1 当需要为已有功能动态地添加更多功能时。
3.3.2 类的核心功能无需改变,只是需要添加新的功能时。
4、代码实现
如果只有一个ConcreteComponent类而没有抽象的Component类,那么Decorator类可以是ConcreteComponent的一个子类,同理,如果只有一个ConcreteDecorator类,那么就没有必要建立一个单独的Decorator类,而可以把Decorator和ConcreteDecorator的责任合并成一个类。
so,在这列我们不用Component类,直接让服饰类Decorator继承人类ConcreteComponent就可。
Person类
class Person{
private String name ;
public Person(String name){
this.name = name;
}
public Person(){
}
public void show(){
System.out.println("装扮的" + name);
}
}
服饰类
class Finery extends Person{
protected Person component;
//打扮
public void Decorate(Person component){
this.component = component;
}
public void show(){
if(component != null){
component.show();
}
}
}
具体服饰类
class TShirts extends Finery{
@Override
public void show() {
System.out.print("大TT恤 ");
super.show();
}
}
class BigTrouser extends Finery{
@Override
public void show() {
System.out.print("垮裤 ");
super.show();
}
}
class NewTrouser extends Finery{
@Override
public void show() {
System.out.print("新垮裤 ");
super.show();
}
}
测试类
public class 装饰器模式 {
public static void main(String[] args) {
Person person = new Person("小菜");
TShirts t = new TShirts();
BigTrouser b = new BigTrouser();
NewTrouser n = new NewTrouser();
t.Decorate(person);
b.Decorate(t);
n.Decorate(b);
n.show();
}
}
可以看出, 修饰模式总共有四部分组成,1)抽象被修饰类或接口;2)具体被修饰类;3)抽象修饰类;4)具体修饰类。
Java种I/O就是使用了这种装饰器模式,看了一晚上的装饰器模式,其实装饰模式我认为就是利用了Java中多态的概念来实现的。