• 【设计模式】 - 结构型模式 - 装饰者模式


    前言

    结构型模式描述如何将类或对象按某种布局组成更大的结构。它分为类结构型模式和对象结构型模式,前者采用继承机制来组织接口和类,后者釆用组合或聚合来组合对象。
    由于组合关系或聚合关系比继承关系耦合度低,满足“合成复用原则”,所以对象结构型模式比类结构型模式具有更大的灵活性。

    结构型模式分为以下 7 种:

    1. 代理模式
    2. 适配器模式
    3. 装饰者模式
    4. 桥接模式
    5. 外观模式
    6. 组合模式
    7. 享元模式

    装饰者模式

    在这里插入图片描述

    装饰者模式

    概述

    指在不改变现有对象结构的情况下,动态地给该对象增加一些职责(即增加其额外功能)的模式。
    装饰者与被装饰者拥有共同的超类,继承的目的是继承类型,而不是行为

    结构

    被装饰的原始对象(Component):可以是接口或者是抽象类。
    被装饰的具体对象(ConcreteComponent):组件具体实现类。Component的具体实现【即包含原有功能的对象】。
    抽象装饰者(Decorator):新增装饰类,用来扩展原有Component类的功能,对于Component来说无须知道Decorator的存在,所以在它的属性中必然有一个private变量指向Component抽象组件。
    装饰者的具体实现类(ConcreteDecorator):
    在这里插入图片描述

    实现

    被装饰的原始对象
    我们先定义一个人的抽象类,里面有运动的抽象方法

    public abstract class Person {
    	/**
    	 * Person 人有可以运动的抽象方法
     	 */
    	public abstract void sport();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    被装饰的具体对象
    这里是具体的一个普通人,作为一个普通人他当然会运动,当然在未被装饰的情况下他只会走路。

    public class CommonPerson extends Person {
    	@Override
    	public void sport() {
    		System.out.println("普通人运动只会走路");
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    抽象装饰者
    抽象装饰者保证了一个对抽象组件的引用,方便调用被装饰对象中的方法。在这里运动大师需要持有人(Person)的引用,方便教授他其他运动,最终成为运动健将。

    public abstract class Master extends Person {
    
    	private Person mPerson;
    	
    	public Master(Person person) {
    		mPerson = person;
    	}
    	
    	@Override
    	public void sport() {
    		mPerson.sport();
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    装饰者具体实现类
    这里有两个装饰者具体实现类,分别是宁泽涛跟邹市明,他们(装饰者)负责向普通人(被装饰者)教授游泳跟拳击。

    public class Ningzetao extends Master {
    	public Ningzetao(Person person){
    		super(person);
    	}
    	@Override
    	public void sport() {
    		super.sport();
    		teachSwimming();
    	}
    	public void teachSwimming(){
    		System.out.println("宁泽涛教普通人游泳");
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    public class Zoushiming extends Master {
    	public Zoushiming(Person person){
    		super(person)
    	}
    	@Override
    	public void sport() {
    		super.sport();
    		teachBoxing();
    	}
    	public void teachBoxing(){
    		System.out.println("邹市明教普通人拳击");
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    客户端调用

    public class Client {
    	public static void main (String[] args) {
    		//创建普通人,只会走路
    		CommonPerson mCommonPerson = new CommonPerson();
    		
    		//宁泽涛教普通人学游泳,普通人学会了游泳
    		Ningzetao mNingzetao = new Ningzetao(mCommonPerson);
    		mNingzetao.sport();
    		
    		//邹市明教普通人学拳击,普通人学会了拳击
    		Zoushiming mZoushiming = new Zoushiming(mCommonPerson);
    		mZoushiming.sport();
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    优点

    装饰者模式比继承更具良好的扩展性,完美的遵循开闭原则,继承是静态的附加责任,装饰者则是动态的附加责任。
    装饰类和被装饰类可以独立发展,不会相互耦合,装饰模式是继承的一个替代模式,装饰模式可以动态扩展一个实现类的功能。

    应用场景

    1. 当不能采用继承的方式对系统进行扩充或者采用继承不利于系统扩展和维护时。
      不能采用继承的情况主要有两类:
      第一类是系统中存在大量独立的扩展,为支持每一种组合将产生大量的子类,使得子类数目呈爆炸性增长;
      第二类是因为类定义不能继承(如final类)
    2. 在不影响其他对象的情况下,以动态、透明的方式给单个对象添加职责。
    3. 当对象的功能要求可以动态地添加,也可以再动态地撤销时。

    参考链接:https://blog.csdn.net/jason0539/article/details/22713711
    https://blog.csdn.net/u012440207/article/details/111070772
    帮助理解的好文章:https://zhuanlan.zhihu.com/p/421998141

  • 相关阅读:
    快速使用vscode写python
    MYSQL经典面试题
    改进乌鸦算法求解单目标优化问题
    【进程管理】认识系统调用函数fork
    SSM学习
    ES6--》一文搞懂JS中的Promise
    Canal 实现MySQL与Elasticsearch7数据同步
    ARM-A架构入门基础(三)MMU
    C国演义 [第十二章]
    平衡树相关知识:
  • 原文地址:https://blog.csdn.net/yzx3105/article/details/127985848