装饰者模式:
要点:装饰者与被装饰者拥有共同的超类,继承的目的是继承类型,而不是行为。
装饰者模式的的特点:可以在运行时动态,透明的为一个组件扩展功能,比继承更加灵活,具有弹性;缺点也很明显:它会导致设计中出现许多小对象,增加类的数目,如果过度使用,会让程序变得很复杂。
下面用“煮鱼”做饭为例,描述如何将一条清汤寡水的鱼,不断的装饰(添加葱姜蒜作料),变成一份可口的食物。
1.创建一个超类(抽象类或者借口),装饰者和被装饰对象都要继承,这样可以保证装饰后的对象和装饰前仍属于同一类型。
package com.sample.decorator;
public interface IFood {
public void cookMethod();
public String getDescription();
}
2.具体原始被装饰者。
package com.sample.decorator;
public class Fish implements IFood {
@Override
public void cookMethod() {
// TODO Auto-generated method stub
System.out.println("煮一条清汤鱼");
}
@Override
public String getDescription() {
// TODO Auto-generated method stub
return "清汤鱼";
}
}
3.抽象的装饰对象,实现所有具体装饰对象的共有属性。
package com.sample.decorator;
public abstract class Condiments implements IFood {
private IFood food;
public Condiments(IFood food){
this.food=food;
}
@Override
public void cookMethod() {
// TODO Auto-generated method stub
food.cookMethod();
}
@Override
public String getDescription() {
// TODO Auto-generated method stub
return food.getDescription();
}
}
4.具体的装饰对象,装饰对象可以在被装饰对象的接口的前后添加新的功能。
package com.sample.decorator;
//葱
public class Onion extends Condiments {
public Onion(IFood food) {
super(food);
// TODO Auto-generated constructor stub
}
@Override
public void cookMethod() {
// TODO Auto-generated method stub
super.cookMethod();
System.out.println("加点葱");
}
@Override
public String getDescription() {
// TODO Auto-generated method stub
return super.getDescription()+"/+葱";
}
}
package com.sample.decorator;
//姜
public class Ginger extends Condiments {
public Ginger(IFood food) {
super(food);
// TODO Auto-generated constructor stub
}
@Override
public void cookMethod() {
// TODO Auto-generated method stub
super.cookMethod();
System.out.println("加点姜");
}
@Override
public String getDescription() {
// TODO Auto-generated method stub
return super.getDescription()+"/+姜";
}
}
package com.sample.decorator;
//蒜
public class Garlic extends Condiments {
public Garlic(IFood food) {
super(food);
// TODO Auto-generated constructor stub
}
@Override
public void cookMethod() {
// TODO Auto-generated method stub
super.cookMethod();
System.out.println("加点大蒜");
}
@Override
public String getDescription() {
// TODO Auto-generated method stub
return super.getDescription()+"/+蒜";
}
}
5.测试用例
package com.sample.decorator;
public class CookTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
IFood food=new Fish();
food.cookMethod();
food.getDescription();
System.out.println("----------------------------------------分割线------原始");
Onion onionFish=new Onion(food);
onionFish.cookMethod();
onionFish.getDescription();
System.out.println("----------------------------------------分割线------加上葱了");
Ginger GingerFish=new Ginger(onionFish);
GingerFish.cookMethod();
GingerFish.getDescription();
System.out.println("----------------------------------------分割线------加上姜了");
Garlic GarlicFish=new Garlic(GingerFish);
GarlicFish.cookMethod();
GarlicFish.getDescription();
System.out.println("----------------------------------------分割线------加上姜了");
}
}
6.测试结果: