定义:
装饰者是在不改变对象的情况下动态给对象添加属性和行为,将责任动态的附加在对象上。 与继承有类似功能即扩展功能。
装饰者模式与继承的区别:
**继承:**在子类扩展功能的时候是静态的,并且是已知需要扩展的功能,是在编译时实现的。
**装饰者模式:**比继承更灵活,可以动态的扩展功能,可以在编译时实现。符合开闭原则:类对扩展开发,对修改关闭。 这也是装饰者模式的优点。
缺点:
会出现很多的小类,难管理。
角色:
- 装饰者和被装饰者的父类:一个抽象的接口或抽象类,定义基本行为。 装饰者也继承(实现)这个类不是为了继承固定的行为,而是为了让装饰者和被装饰者属于同一类型从而在装饰的时候被装饰者不会被修改。 也因此,装饰类可以替换被装饰类。
- 被装饰者:具体被装饰的对象
- 抽象装饰者(Decorator):一个接口或抽象类,从外类装饰被装饰者,被装饰者不需要知道装饰者的存在。
- 具体装饰者:继承(实现)被装饰者,定义需要附加在被装饰者的责任,即扩展被装饰者。
程序示例:
对于游戏装备的定价系统,一套游戏装备可能会附加武器、头饰等其他的装饰品一起售出,并且搭配不同的饰品售价不一,并且搭配的饰品是动态的。因此可以使用装饰者模式,游戏装备是被装饰者,武器、头饰是装饰者。
Java中的IO就是典型的装饰者模式。
/**
* 被装饰者和装饰者的父类
*/
public abstract class GameComponent {
String desc = "游戏装备";
public String getDesc() {
return desc;
}
public abstract int getPrice();
}
/**
* 具体被装饰者
*/
public class WangzheCon extends GameComponent {
@Override
public String getDesc() {
return "王者荣耀的装备:";
}
@Override
public int getPrice() {
return 99;
}
}
/**
* 抽象装饰者
*/
public abstract class MyDecorator {
public abstract String getDecs();
}
public class ClothDecora extends GameComponent {
GameComponent gameComponent;
public ClothDecora(GameComponent gameComponent) {
this.gameComponent = gameComponent;
}
@Override
public String getDesc() {
return "增加一种头饰:";
}
@Override
public int getPrice() {
return 20+gameComponent.getPrice();
}
}
/**
* 具体装饰者--武器装饰者
* 继承同一子类是为了与被装饰者关联,保持被装饰者的类型
*/
public class WeaponDecora extends GameComponent{
//需要持有被装饰者
GameComponent gameComponent ;
public WeaponDecora(GameComponent gameComponent) {
this.gameComponent = gameComponent;
}
@Override
public String getDesc() {
return "添加一种武器:";
}
@Override
public int getPrice() {
return 30+gameComponent.getPrice();
}
}
测试类:
public static void main(String[] agrs){
WangzheCon wangzheCon= new WangzheCon();
System.out.println("描述:"+wangzheCon.getDesc()+wangzheCon.getPrice());
WeaponDecora weaponDecora = new WeaponDecora(wangzheCon);
System.out.println("武器装饰描述:"+weaponDecora.getDesc()+weaponDecora.getPrice());
ClothDecora clothDecora = new ClothDecora(wangzheCon);
System.out.println("头饰装饰描述:"+clothDecora.getDesc()+clothDecora.getPrice());
//或者
WangzheCon wangzheCon1 = new WangzheCon();
WeaponDecora weaponDecora1 = new WeaponDecora(new ClothDecora(wangzheCon1));
System.out.println("装备描述:"+weaponDecora1.getDesc()+weaponDecora1.getPrice());
}
代码示例:https://github.com/MarinaTsang/demo/tree/master/decorator