设计模式之装饰模式
装饰模式,很容易想到模式的定义,动态地给一个对象添加一些额外的职责,起到一个填充装饰的目的,旨在更加灵活地扩充对象的功能。
装饰模式重在形式结构,也是结构型设计模式,结构也形成了装饰模式的作用。我们来看看装饰模式的类图,初步了解下装饰模式的形式:
装饰模式的构件是由四部分组成的:
1、抽象构件角色(Component):定义一个抽象接口,规范对象的职责;
2、具体构件角色(ConcreteComponent):被装饰者,定义一个将要被装饰增加功能的类,且完成基本的职责;
3、装饰角色(Decorator):拥有一个构件对象的实例,并定义了抽象构件的接口;
4、具体装饰角色(ConcreteDecorator):负责给构件添加增加的功能以完成装饰目的。
下面以一个例子来加深装饰模式的具体使用印象:
1 //抽象构件角色 2 public interface Test{ 3 public abstract int countTestCase(); 4 public abstract void run(TestResult result); 5 } 6 //具体构件角色,但是这里是个抽象类 7 public abstract class TestCase extends Assert implements Test{ 8 public int countTestCase(){ 9 return 1; 10 } 11 public TestResult run(){ 12 TestResult result = createResult(); 13 run(result); 14 return result; 15 } 16 public void run(TestResult result){ 17 result.run(this); 18 } 19 } 20 //装饰角色 21 public class TestDecorator extends Assert implements Test{ 22 protected Test fTest;//保留一个对构件对象的实例 23 public TestDecorator(Test test){ 24 fTest = test; 25 } 26 public void basicRun(TestResult result){ 27 fTest.run(result); 28 } 29 public int countTestCase(){ 30 return fTest.countTestCase(); 31 } 32 public void run(TestResult result){ 33 basicRun(result); 34 } 35 } 36 //具体装饰角色,作用就是可以设置测试类的执行次数 37 public class RepeatedTest extends TestDecorator{ 38 private int fTimesRepeat; 39 public RepeatedTest(Test test, int repeat){ 40 super(test); 41 if(repeat < 0) 42 throw new IllegalArgumentException("Repetition count must be > 0"); 43 fTimesRepeat = repeat; 44 } 45 46 public int countTestCase(){ 47 return super.countTestCase()*fTimesRepeat; 48 } 49 public void run(TestResult result){ 50 for(int i = 0;i<fTimesRepeat;i++){ 51 if(result.shouldStop()) break; 52 super.run(result); 53 } 54 } 55 } 56 57 使用的时候,就可以采用下面的方式: 58 TestDecorator test = new RepeatedTest(new TestCase(), 3);
装饰模式是一个非常好用的临时添加类功能的方式,在不影响其他对象的情况下,能动态、透明地给单个对象辅以新的能力。非常适用于不能采用生成子类的方法进行扩充的情况。
装饰模式的偶尔使用会达到很不错的效果,但是在一个系统里因为前期考虑不周,大量使用,则会给系统的可读性和复杂度带来麻烦。