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


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

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

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

    三、装饰者模式再理解

    优点:

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

    缺点:

    • 会出现更多的代码,更多的类,增加程序的复杂性。
    • 动态装饰时,多层装饰时会更复杂。
    • 装饰模式会产生比使用继承关系更多的对象。
  • 相关阅读:
    简单的倒计时 时间显示
    git submodule
    使用选择器语法来查找元素
    yo bootstrap mui 使用对比
    flexbox 兼容安卓4.3
    mac 下 php 安装 中的坑
    微信网页开发
    能发送http请求(get,post)的工具
    h5宣传页制作过程中遇到的问题
    功能模块图、业务流程图、处理流程图、ER图,数据库表图(概念模型和物理模型)画法
  • 原文地址:https://www.cnblogs.com/xunxian/p/13741869.html
Copyright © 2020-2023  润新知