1,什么是装饰者设计模式
我们先来说说什么是装饰,在写字台上面,摆上一个卡通玩偶,这个玩偶就起到了装饰写字台的作用,动态的给一个类添加职责,就添加功能而言,比继承子类要灵活.
2,为什么要使用装饰者设计模式
装饰对象可以在转发这些请求以前或以后增加一些附加功能。这样就确保了在运行时,不用修改给定对象的结构就可以在外部增加附加的功能。在面向对象的设计中,通常是通过继承来实现对给定类的功能扩展。所以,如果我们想要增加一个类的功能(可能这些功能与这个类的内容不匹配),却又不想修改这个类的内容,这个时候就可以用装饰者设计模式.
3,怎么使用装饰者设计模式
这里给个实例来说明.如下
比如有这样一个过程:我们要想吃饭,首先得去菜市场买菜,然后买完菜后回家开始做饭.
如果我们现在已经有Dining.class了,然后想扩展买菜和做饭的功能,在写一个class继承它去扩展似乎可以实现,但是这样做违背了单一职责原则.所以我们这里得考虑用到装饰模式去设计这个功能.先给出UML再细说!
该流程按照装饰模式设计,所有类都实现Component interface.然后每个类中把持一个被装饰者的引用(在吃饭.class中,由于它是被装饰者,所以它自己的被装饰者引用可有无.)
在这个流程中吃饭被买菜装饰,买菜被菜品装饰,菜品被具体的菜类所装饰,最后做饭去装饰具体的菜品.这样在没有改变吃饭类的同时,增加了买菜,做饭等一系列新的功能.
具体有几个细节在这个说明:
1,Component interface在这里起到什么作用?
Component interface主要起到了职责方法申明,职责方法就是被装饰者提供给装饰者访问的方法,比如这里的showCurrentProcess()(方法作用是显示显示当前执行操作),它使得
买菜类得以访问到吃饭类的showCurrentProcess(),从而提供新添加的功能给吃饭类.那如果我们又要添加一种方法,去装饰被装饰的对象,例如showCurrentTime(),我们就得在
Component interface声明了。
2,在类中的Component实例有何作用?
Component实例就是被修饰对象的实例.
3,刚才说装饰,那具体装饰过程是怎样的?
具体装饰过程就是装饰对象调用decorator(Component component)然后把被装饰者引用给类中Component实例,通过调用Component interface声明的方法去实现功能的添加.
具体代码如下:
吃饭.class
public class Dining implements Component{
private Component component;
@Override
public void showCurrentProcess() {
// TODO Auto-generated method stub
//note that:you must let decorator object frist running.
if(component != null){
component.showCurrentProcess();
}
System.out.println("我想吃饭了...");
}
public void decorator(Component component){
this.component = component;
}
}
买菜.class
public class BuyFood implements Component{
private Component component;
@Override
public void showCurrentProcess() {
// TODO Auto-generated method stub
if(component != null){
component.showCurrentProcess();
}
System.out.println("买菜去...");
}
public void decorator(Component component){
this.component = component;
}
}
菜品.class
public class FoodType implements Component{
private Component component = null;
@Override
public void showCurrentProcess() {
// TODO Auto-generated method stub
if(component != null){
component.showCurrentProcess();
}
}
public void decorator(Component component){
this.component = component;
}
}
做饭.class
public class Cook implements Component{
private Component component;
@Override
public void showCurrentProcess() {
// TODO Auto-generated method stub
if(component != null){
component.showCurrentProcess();
}
System.out.println("做饭...");
}
public void decorator(Component component){
this.component = component;
}
}
牛肉.class
public class Beef extends FoodType{
@Override
public void showCurrentProcess() {
// TODO Auto-generated method stub
super.showCurrentProcess();
System.out.println("买回牛肉 ");
}
}
胡萝卜.class
public class Carrot extends FoodType{
@Override
public void showCurrentProcess() {
// TODO Auto-generated method stub
super.showCurrentProcess();
System.out.println("买回胡萝卜 ");
}
}
青椒.class
public class Greenpepper extends FoodType{
@Override
public void showCurrentProcess() {
// TODO Auto-generated method stub
super.showCurrentProcess();
System.out.println("买回青椒 ");
}
}
Main.class
public class Main {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Dining dining = new Dining();
Cook cook = new Cook();
Beef beef = new Beef();
Carrot carrot = new Carrot();
Greenpepper greenpepper = new Greenpepper();
BuyFood buyFood = new BuyFood();
buyFood.decorator(dining);
beef.decorator(buyFood);
carrot.decorator(beef);
greenpepper.decorator(carrot);
cook.decorator(greenpepper);
cook.showCurrentProcess();
}
}
最后打印结果如下:
我想吃饭了...
买菜去...
买回牛肉
买回胡萝卜
买回青椒
做饭...