Loading...

初识设计模式之装饰者模式

一、为什么要用装饰者模式

我们来看一个例子,比如现在有一家餐巾纸工厂,用来生产抽纸和卷纸。如下代码所示:

interface TissueFactory{
	public void produce();
}

class Rolltissu implements TissueFactory{
	public void produce() {
		System.out.println("生产卷纸");
	}
}

class Removabletissu implements TissueFactory{
	public void produce() {
		System.out.println("生产抽纸");
	}
}

运营了一段时间后,工厂决定对抽纸和卷纸的生产策略进行升级,对二者都进行3层纸和4层纸的生产。一般情况下,我们想到用继承去实现:

interface TissueFactory{
	public void produce();
}

class Rolltissu implements TissueFactory{
	public void produce() {
		System.out.println("生产卷纸");
	}
}

class Removabletissu implements TissueFactory{
	public void produce() {
		System.out.println("生产抽纸");
	}
}

class ThreeRolltissu extends Rolltissu{
	@Override
	public void produce() {
		System.out.println("生产三层的卷纸");
	}
}

class FourRolltissu extends Rolltissu{
	@Override
	public void produce() {
		System.out.println("生产四层的卷纸");
	}
}

class ThreeRemovabletissu extends Removabletissu{
	@Override
	public void produce() {
		System.out.println("生产三层的抽纸");
	}
}

class FourRemovabletissu extends Removabletissu{
	@Override
	public void produce() {
		System.out.println("生产四层的抽纸");
	}
}

这样一来,需求不就决解了吗?再后来,工厂又进行升级,要生产2层纸和5层纸厚的卷纸和抽纸,这样一来,类的数量增加地非常快。于是,装饰者模式登场了。

二、怎么用装饰者模式

接着上面的第二段,即回到工厂刚进行生产策略升级的部分。此时工厂的卷纸和抽纸都分别要生产三层、四层纸厚的纸,此时我们用装饰者模式进行设计:

interface TissueFactory{
	public void produce();
}

class Rolltissu implements TissueFactory{
	public void produce() {
		System.out.println("生产卷纸");
	}
}

class Removabletissu implements TissueFactory{
	public void produce() {
		System.out.println("生产抽纸");
	}
}

//装饰的是TissueFactory
abstract class TissueDecorator implements TissueFactory{
	protected TissueFactory tissueFactory;
	public TissueDecorator(TissueFactory tissueFactory){
		this.tissueFactory = tissueFactory;
	}
}

class ThreeTissue extends TissueDecorator{
	public ThreeTissue(TissueFactory tissueFactory) {
		super(tissueFactory);
	}
	public void produce() {
		System.out.print("使用三层纸工艺:");
		tissueFactory.produce();
	}
}

class FourTissue extends TissueDecorator{
	public FourTissue(TissueFactory tissueFactory) {
		super(tissueFactory);
	}
	public void produce() {
		System.out.print("使用四层纸工艺:");
		tissueFactory.produce();
	}
}
 
public class Run {
	public static void main(String[] args) {
		System.out.println("在生产策略不变时:");
		TissueFactory rollTf = new Rolltissu();
		TissueFactory removableTf = new Removabletissu();
		rollTf.produce();
		removableTf.produce();
		System.out.println("在生产策略改变时:");
		//对原来的工艺流程进行装饰,需要一个被装饰的对象
		TissueFactory threeRoll = new ThreeTissue(rollTf);
		TissueFactory FourRoll = new FourTissue(rollTf);
		TissueFactory threeRemovable = new ThreeTissue(removableTf);
		TissueFactory FourRemovable = new FourTissue(removableTf);
		threeRoll.produce();
		FourRoll.produce();
		threeRemovable.produce();
		FourRemovable.produce();
	}
}

如此一来,当我们又进行产业升级时,如新增2层和5层工艺时,我们只需要加上2层和5层的装饰者就行了。

三、装饰者模式再理解

优点:

  • 继承的有力补充,比继承灵活,不改变原有对象的情况下给一个对象扩展功能。
  • 通过使用不同装饰类以及这些类的排列组合,可以实现不同的效果。
  • 符合开闭原则

缺点:

  • 会出现更多的代码,更多的类,增加程序的复杂性。
  • 动态装饰时,多层装饰时会更复杂。
  • 装饰模式会产生比使用继承关系更多的对象。
posted @ 2020-09-27 21:14  _轻舟  阅读(124)  评论(0编辑  收藏  举报