有时如果需要对某一个类增加一个功能,可以使用继承来实现。但是如果想要只是对某一个对象来增加一项功能,则可能会用到装饰模式。装饰模式的主要作用是动态的给某一个对象添加某些功能。如果此时使用继承来添加功能时,会产生大量的子类,导致难以维护。
装饰模式的简要类图如下:
其中:
Component为待增加功能(即待装饰)的抽象部件
ConcreateComponent为具体部件
Decorate为实施装饰作用的抽象类
ConcreateDecorate1和ConcreateDecorate2为具体的装饰类
Client为实际用户
简要实现代码如下:
抽象部件,一辆汽车
package com.example.Decorate;
public interface ICar {
public void Run();
}
具体部件,一辆普通的汽车
package com.example.Decorate;
public class NormalCar implements ICar {
@Override
public void Run( ) {
System.out.println("Car begin to run!");
}
}
抽象的装饰类
package com.example.Decorate;
public class Decorate implements ICar {
private ICar mCar = null;
public Decorate( ICar car ) {
this.mCar = car;
}
@Override
public void Run( ) {
this.mCar.Run( );
}
}
具体的装饰类1,让汽车会报警
package com.example.Decorate;
public class AlarmCar extends Decorate {
public AlarmCar( ICar car ) {
super( car );
}
@Override
public void Run( ) {
super.Run( );
alarm( );
}
private void alarm(){
System.out.println("Car alarmed!");
}
}
具体的装饰类2,让汽车的喇叭会响
package com.example.Decorate;
public class BeepCar extends Decorate {
public BeepCar( ICar car ) {
super( car );
}
@Override
public void Run( ) {
super.Run( );
beep( );
}
private void beep(){
System.out.println("Car beeped");
}
}
客户端
package com.example.Decorate;
public class Client {
/**
*
* @author lengxue
* @date 24 Jul 2012 11:42:55
* @param args
* @note
*/
public static void main( String[] args ) {
ICar myCar = new NormalCar( );
myCar = new AlarmCar( myCar );
myCar = new BeepCar( myCar );
myCar.Run( );
}
}
运行结果如下:
Car begin to run!
Car alarmed!
Car beeped
简单说明:
1、客户端首先产生一辆具体的汽车
2、然后对汽车进行装饰,让汽车可以报警
3、再对汽车进行装饰,让汽车的喇叭可以响
4、如果还需要其他的装饰,可以再继续增加
这样,原来的汽车对象保持不变,如果需要对其增加某项功能,则可以采用这种方式。不管客户需要增加什么功能,都不会影响原来的汽车类。而且可以灵活组合,产生所需要的任意功能的汽车。如果通过继承机制来实现的话,那可能类的数量会根据功能的数量呈现指数式增长。
具体代码下载:http://download.csdn.net/my