GOF对装饰者模式的定义式 :动态的给一个对象添加一些额外的职责,就增加功能来说,装饰者模式比生成子类会更加灵活。先看基本代码。
/**
*
* @author ricardo
* @Time 下午9:11:18
* @Function:组件抽象类
*
*/
public abstract class Component {
public abstract void Operation();
}
/**
*
* @author ricardo
* @Time 下午9:12:57
* @Function:具体组件类
*
*/
public class ConcreteComponent extends Component{
@Override
public void Operation() {
System.out.println("Basic operation");
}
}
/**
*
* @author ricardo
* @Time 下午9:59:12
* @Function:具体的装饰器A
*
*/
public class ConcreateDecoratorA extends Decorator {
private String addState;
public void Operation() {
super.Operation();
addState = "New State";
System.out.println("this class has a " + addState);
}
}
/**
*
* @author ricardo
* @Time 下午9:59:51
* @Function:具体的装饰器B
*
*/
public class ConcreateDecoratorB extends Decorator{
public void Operation() {
super.Operation();
AddBehavior();
}
public void AddBehavior() {
System.out.println("Now the object has a new method");
}
}
客户端代码:
public class Client {
public static void main(String[] args) {
Component decorator = new ConcreteComponent();
ConcreateDecoratorA a = new ConcreateDecoratorA();
ConcreateDecoratorB b = new ConcreateDecoratorB();
a.SetComponent(decorator);
b.SetComponent(decorator);
System.out.println("装饰器A后的操作");
a.Operation();
System.out.println("装饰器B后的操作");
b.Operation();
}
}
运行截图:
从上面的代码可以看出,装饰者模式就是利用Component来对需要被装饰的对象进行包装,这样做可以讲每个装饰对象的具体实现与如何使用这个对象彻底分离,装饰对象只需要关心自己的功能就可以了。
举个例子来说,演员会涉及的戏份,比如胡歌,会有古装戏李逍遥,也会有伪装者,那么他一个人如何表演不同时空的角色呢?有化妆师对他进行装饰就好了。
/**
*
* @author ricardo
* @Time 下午9:32:47
* @Function:演员
*
*/
public class Actor {
public void Act() {
System.out.println("胡歌老大开始表演了");
}
}
/**
*
* @author ricardo
* @Time 下午10:17:27
* @Function:造型师
*
*/
public class Stylist extends Actor {
protected Actor actor;
public void MakeUp(Actor actor) {
this.actor = actor;
}
public void Act() {
if(actor != null)
actor.Act();
}
}
具体的造型师
/**
*
* @author ricardo
* @Time 下午10:17:52
* @Function:古装剧化妆师
*
*/
public class AncientStylist extends Actor {
private void ShowRole() {
System.out.println("胡歌饰演李逍遥");
}
private void MakeUpForActor() {
System.out.println("给胡歌穿上古装,带上假发,佩戴好仙剑");
}
public void Act() {
ShowRole();
MakeUpForActor();
super.Act();
}
}
/**
*
* @author ricardo
* @Time 下午10:18:32
* @Function:现代造型师
*
*/
public class ModernStylist extends Actor {
private void ShowRole() {
System.out.println("胡歌饰演明台");
}
private void MakeUpForActor() {
System.out.println("给演员穿上中山装,弄好头发,走起");
}
public void Act() {
ShowRole();
MakeUpForActor();
super.Act();
}
}
客户端代码
public class Client {
public static void main(String[] args) {
ModernStylist modernStylist = new ModernStylist();
AncientStylist ancientStylist =new AncientStylist();
modernStylist.Act();
ancientStylist.Act();
}
}
运行截图
从功能上讲,最后完成表演行为的其实是造型师,这里造型师相当于增强了功能的演员,但从代码层面和逻辑上来说,真正完成表演工作的还是演员本身,造型师只是对演员进行了修饰作用。
过分的使用装饰者模式会使程序的结构变得臃肿而混乱,如果通过装饰者添加的功能甚至比装饰类本身功能更多,那么是时候考虑对这个类进行重构了。例外很重要的一点就是装饰者模式起到的还是修饰的作用,而不是教研员新的表演技巧甚至做替身。
装饰者模式把类中的装饰功能从类中搬移到简化原有类的目的,这样做不仅能很好的区分类的核心职责和装饰功能。还可以将几个相关类中重复的修饰逻辑去除,比如男女演员都需要古装/现代造型。所以说装饰模式降低了程序的荣誉。
以上内容,整理自刘径舟,张玉华编著的《设计模式其实很简单》读书笔记,欢迎转载