Java学习笔记——设计模式之三.装饰模式

 

函数应该做一件事,做好这件事,只做这一件事。

                    ——Clean Code

 

 

装饰模式,上代码:

先定义零件类:

1 package cn.no3.decorator.template;
2 
3 public abstract class Component {
4 
5     public abstract void operation();
6 }

再定义具体零件类(即被装饰类)继承零件类:

 1 package cn.no3.decorator.template;
 2 
 3 public class ConcreteComponent extends Component{
 4 
 5     @Override
 6     public void operation() {
 7         // TODO Auto-generated method stub
 8         System.out.println("对一个Object进行装饰:");
 9     }
10 
11 }

然后定义装饰类,继承零件类:

 1 package cn.no3.decorator.template;
 2 
 3 public class Decorator extends Component {
 4 
 5     protected Component component;
 6     
 7     public void setComponent(Component component) {
 8         this.component = component;
 9     }
10 
11     @Override
12     public void operation() {
13         //调用的是传入component的operation方法
14         if (component != null) {
15             component.operation();
16         }
17 
18     }
19 
20 }

定义装饰类的子类:

 1 package cn.no3.decorator.template;
 2 
 3 public class ConcreteDecoratorA extends Decorator {
 4 
 5     private String addedField;
 6     
 7     @Override
 8     public void operation() {
 9         // TODO Auto-generated method stub
10         super.operation();//第一行调用super,则从前往后包装.反之则从后往前包装
11         addedField = "新的装饰物A";
12         System.out.println("装饰了:"+addedField);
13     }
14 }
15 
16 public class ConcreteDecoratorB extends Decorator {
17     
18     @Override
19     public void operation() {
20         // TODO Auto-generated method stub
21         super.operation();
22         AddedBehavior();
23     }
24 
25     private void AddedBehavior() {
26         // TODO Auto-generated method stub
27         System.out.println("完成装饰,最后照个相");
28     }
29     
30 }

测试类测试:

 1 package cn.no3.decorator.template;
 2 
 3 public class _Test {
 4 
 5     public static void main(String[] args) {
 6         //新建装饰对象
 7         ConcreteComponent concreteComponent = new ConcreteComponent();
 8         ConcreteDecoratorA concreteDecoratorA = new ConcreteDecoratorA();
 9         ConcreteDecoratorB concreteDecoratorB = new ConcreteDecoratorB();
10         //逐层包装
11         //如果注掉下句,还是先调用A的super,发现没传component,于是A的super什么都不做
12         concreteDecoratorA.setComponent(concreteComponent);//A先调用cC,cC方法不再调用super.
13         concreteDecoratorB.setComponent(concreteDecoratorA);//B先调用A
14         //输出最终结果
15         concreteDecoratorB.operation();
16     }
17 }

把这个例子中的Component类换成接口也是一样的:

举个例子:

需求:

定义一个角色,让他实现IWearable接口,

再定义装备实现IWearable接口

人物装备装备.

上代码:

1 package cn.no3.decorator.instance;
2 
3 public abstract interface IWearable {
4 
5     public abstract void operation();
6 }
 1 package cn.no3.decorator.instance;
 2 
 3 public class Clothes implements IWearable {
 4 
 5     protected IWearable component;
 6     
 7     public void setComponent(IWearable component) {
 8         this.component = component;
 9     }
10 
11     @Override
12     public void operation() {
13         if (component != null) {
14             component.operation();
15         }
16 
17     }
18 
19 }
 1 package cn.no3.decorator.instance;
 2 
 3 //即使只有一双鞋也要定义父类,否则无法通过对象的super.operation对装饰进行传递
 4 public class Shoes implements IWearable {
 5 
 6     protected IWearable component;
 7     
 8     public void setComponent(IWearable component) {
 9         this.component = component;
10     }
11 
12     @Override
13     public void operation() {
14         if (component != null) {
15             component.operation();
16         }
17     }
18 
19 }
 1 package cn.no3.decorator.instance;
 2 
 3 public class Weapons implements IWearable {
 4 
 5     protected IWearable component;
 6     
 7     public void setComponent(IWearable component) {
 8         this.component = component;
 9     }
10 
11     @Override
12     public void operation() {
13         if (component != null) {
14             component.operation();
15         }
16 
17     }
18 
19 }

他们的子类都是重写父类operation()方法,最先调用(或者最后调用),super.operation();此处省略若干行

 1 package cn.no3.decorator.instance;
 2 
 3 public class WeaponA extends Weapons {
 4 
 5     @Override
 6     public void operation() {
 7         // TODO Auto-generated method stub
 8         super.operation();
 9         System.out.println("装备了:霜之哀伤");
10     }
11 }

角色类

 1 package cn.no3.decorator.instance;
 2 
 3 public class Character implements IWearable{
 4 
 5     @Override
 6     public void operation() {
 7         // TODO Auto-generated method stub
 8         System.out.println("对一个人物进行装备:");
 9     }
10 
11 }

测试类:

 1 package cn.no3.decorator.instance;
 2 
 3 public class _Test {
 4 
 5     public static void main(String[] args) {
 6         //新建装备对象
 7         Character concreteComponent = new Character();
 8         ClotheA fantasyKiller = new ClotheA();
 9         ClotheB bravingArmor = new ClotheB();
10         WeaponA frostmourne = new WeaponA();
11         WeaponB DoubleRoses = new WeaponB();
12         ShoesA shoes = new ShoesA();
13         //逐层包装
14         fantasyKiller.setComponent(concreteComponent);
15         bravingArmor.setComponent(fantasyKiller);
16         frostmourne.setComponent(bravingArmor);
17         DoubleRoses.setComponent(frostmourne);
18         shoes.setComponent(DoubleRoses);//shoes.setComponent(shoes)会陷入死循环
19         //输出最终结果
20         shoes.operation();
21     }
22 }

装饰模式是为已有功能动态地添加更多功能的一种方式

装饰模式把每个要装饰的功能放在单独的类中,并让这个类包装它所需要装饰的对象。因此,当需要执行特殊行为时,客户代码就可以在运行时根据需要有选择地、按顺序地使用装饰功能包装对象了。

装饰功能的核心是:把类中的装饰功能从类中搬出去。

posted @ 2017-05-13 15:20  Tomas曼  Views(245)  Comments(0Edit  收藏  举报