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


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

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

    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层的装饰者就行了。

    三、装饰者模式再理解

    优点:

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

    缺点:

    • 会出现更多的代码,更多的类,增加程序的复杂性。
    • 动态装饰时,多层装饰时会更复杂。
    • 装饰模式会产生比使用继承关系更多的对象。
  • 相关阅读:
    aircrack-ng 多网卡启动后环境清理
    Docker create image
    预加载(学习一)
    activity+fragment多次切换出现页面空白问题
    万能的Volley
    关于下拉刷新你是否真的非常理解还是只会搬砖?附 Android 实例子源代码文件下载地址380个合集
    如何将Java源代码文件的编码从GBK转为UTF-8?
    如何操作笔记本显得逼格很高?
    跑马灯源代码
    关于java、Android中Math的一些用法
  • 原文地址:https://www.cnblogs.com/xunxian/p/13741869.html
Copyright © 2020-2023  润新知