设计模式之装饰者模式

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();
	}

}

最后打印结果如下:

我想吃饭了...
买菜去...
买回牛肉
买回胡萝卜
买回青椒 
做饭...

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值