从例子开始讲解,比如今天你要出门约会,你肯定是要决定好你要穿什么样的衣服出门,用衣服来装饰下自己,让自己拥有一个完美的约会。比如,你会穿一件衬衫,然后穿一件西服裤,最后穿皮鞋出门。这就是装饰者模式的一个例子。为了实现这个功能,会有下面的代码。
1、代码路一发
public class People {
public void wearShirt(){
System.out.println("******穿衬衫******");
}
public void wearTrouser(){
System.out.println("******穿西服裤******");
}
public void wearShoes(){
System.out.println("******穿皮鞋******");
}
}
public class Client {
public static void main(String[] args) {
People people = new People();
people.wearShirt();
people.wearTrouser();
people.wearShoes();
}
}
虽然上面的代码实现了出门穿衣服的功能,但是这里会问题。如果我现在要增加一个功能,我要先穿袜子,再穿皮鞋。此时就要在People类中增加一个穿袜子的方法。这就违背了设计模式的开闭原则,所谓开闭原则就是类可以进行扩展,但是不可以进行修改。所以就有如下的设计:
2、代码路一发
public interface People {
public void wearClothing();
}
public class Xiaoming implements People{
private String name;
public Xiaoming(){
name = "小明";
}
public void wearClothing(){
System.out.println(name+"******开始穿衣服******");
}
public String getName() {
return name;
}
}
public abstract class Finery implements People {
protected People people;
public Finery(People people){
this.people = people;
}
public abstract void wearClothing();
}
public class ShirtFinery extends Finery {
public ShirtFinery(People people){
super(people);
}
@Override
public void wearClothing() {
people.wearClothing();
System.out.println("******穿衬衫******");
}
}
public class ShoesFinery extends Finery {
public ShoesFinery(People people){
super(people);
}
@Override
public void wearClothing() {
people.wearClothing();
System.out.println("******穿皮鞋*******");
}
}
public class TrouserFinery extends Finery {
public TrouserFinery(People people){
super(people);
}
@Override
public void wearClothing() {
people.wearClothing();
System.out.println("******穿西服裤*******");
}
}
public class Client {
public static void main(String[] args) {
People people = new Xiaoming();
Finery shirtFinery = new ShirtFinery(people);
Finery trouserFinery = new TrouserFinery(shirtFinery);
Finery shoesFinery = new ShoesFinery(trouserFinery);
shoesFinery.wearClothing();
}
}
3、其结构图如下:
4 、描述
装饰者模式共有四大角色:
Component:抽象组件
可以是一个接口或者是抽象类,其充当的就是被装饰的原始对象,用来定义装饰者和被装饰者的基本行为。
ConcreteComponent:组件具体实现类
该类是 Component 类的基本实现,也是我们装饰的具体对象。
Decorator:抽象装饰者
装饰组件对象,其内部一定要有一个指向组件对象的引用。在大多数情况下,该类为抽象类,需要根据不同的装饰逻辑实现不同的具体子类。当然,如果是装饰逻辑单一,只有一个的情况下我们可以忽略该类直接作为具体的装饰者。
ConcreteDecoratorA 和 ConcreteDecoratorB:装饰者具体实现类对抽象装饰者的具体实现。
在已有的 Component 和 ConcreteComponent 体系下,实现装饰者模式来扩展原有系统的功能,可以分为
5 个步骤
- 继承或者实现 Component 组件,生成一个 Decorator 装饰者抽象类;
- 在生成的这个 Decorator 装饰者类中,增加一个 Component 的私有成员对象;
- 将 ConcreteComponent 或者其他需要被装饰的对象传入 Decorator 类中并赋值给上一步的 Component 对象;
- 在装饰者 Decorator 类中,将所有的操作都替换成该 Component 对象的对应操作;
- 在 ConcreteDecorator 类中,根据需要对应覆盖需要重写的方法。
5 、总结
People是定义了一个接口,用来添加具体的职责,而Xiaoming是具体的People,也就是被装饰的对象。对于Finery实现了People接口,进而对People进行扩展,而Finery的子类就是具体的装饰类,Finery中依赖People类,装饰的具体对象。 这就是所谓的装饰者模式。如果我要添加穿袜子的步骤,则只需要再添加一个实现类,完全不需要修改其他代码(Client是客户端类,肯定是要修改的)。