• 装饰模式~


    个人理解:装饰模式的内核是叠加,即在某个功能的基础上,增加这个功能的行为,使得这个功能能够实现更多的事情。
    装饰模式定义:动态的给一个对象添加一些额外的职责,就增加功能来说,装饰模式比生成子类更为灵活。
    从定义我们可以看出:装饰模式的作用类似于继承,我们子类继承自某个父类,也能达到扩展父类功能的效果,但是就像它说的,不够灵活,装饰模式给我们提供了一种能在代码中动态添加功能的方法。这样的优点尤其在某些职责复用次数特别多,但是又不是每个类都要用到的时候,优势特别明显,因为如果我们要创建能实现所有功能的子类,那就需要排列组合n次,会创建出特别多冗余的类,而使用装饰模式不会
    装饰的过程:类似于unity组件式开发的思路,一个空的对象(可能只带有transform位置信息),给它加上text组件,它就具有text的职责,然后还可以继续在已经添加了text组件的对象上继续添加描边、阴影等组件。

    1️⃣ 要实现装饰模式,首先需要保证各个组件都继承自同一个基类,且最终调用同一个方法,这里定义虚基类用作组件继承

    abstract class Component
    {
    	public abstract void Operation();
    	//抽象函数,子类一定要实现
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    2️⃣ 接下来可以定义可以被装饰的空对象,这个对象也可以实现Operation,具有自己的行为:

    class ConcreteObject : Component
    {
    	public override void Operation()
    	{
    		Console.WriteLine("可以自定义的操作");
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    3️⃣ 下一步定义装饰对象的功能基类,这也是装饰模式的根本。

    class ConcreteComponent : Component
    {
    	private Component com;
    	public void SetComponent(Component com)
    	{
    		this.com = com;
    	}
    	
    	public override void Operation()
    	{
    		if(this.com != null)
    		{
    			this.com.Operation();
    		}
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    装饰基类的Operation,需要具有执行被装饰对象Operation的功能。

    4️⃣ 定义两个具体功能类

    class Outline : ConcreteComponent
    {
    	public override void Operation()
    	{
    		base.Operation(); // 先执行原组件的Operation
    		Console.WriteLine("添加了描边组件");
    	}
    }
    
    class Shadow : ConcreteComponent
    {
    	public override void Operation()
    	{
    		base.Operation(); // 先执行原组件的Operation
    		Console.WriteLine("添加了阴影组件");
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    被装饰后的对象,如果执行Operation,先执行被他装饰的对象的Operation。
    5️⃣ 客户端代码如下:

    static void Main(String[] args)
    {
    	//先定义被装饰的对象
    	Component obj = new ConcreteObject();
    	//定义装饰功能对象
    	Component outline = new Outline();
    	Component shadow = new Shadow();
    	//装饰过程
    	outline.SetComponent(obj);  
    	//将Outline装饰到obj上,outline就是被装饰后的对象
    	shadow.SetComponent(outline);
    	//对上一层装饰后的对象进行二次装饰,shadow就是二次装饰后的对象
    
    	//最后应该调用最后一次装饰得到的对象的Operation
    	shadow.Operation();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    扩展部分

    有一个游戏角色,我们需要给他装备上各种装备,比如说武器,铠甲,足具等等,每种装备都可以提升属性,也可以改变人物装饰。这时候可以使用装饰模式,将获取人物各种属性的函数以及获取人物装扮的函数抽象出来,在具体的装备装饰器中重写这些函数,获取时做一些数值或文本修改:
    int override GetHp() { return this.character.GetHp() + 50; }
    上面的例子都是写一个单独的函数进行装饰,这里可以考虑在构造函数里面进行装饰:
    void Kaijia(Character cha) { this.character = cha; }

  • 相关阅读:
    Python--随机出拳(random)--if判断--综合案例练习:石头剪刀布
    2022杭电多校八 1008-Orgrimmar(树形DP)
    [附源码]Python计算机毕业设计Django公共台账管理系统
    阿里云Elasticsearch搜索
    SIMULIA-Simpack 2022x新功能介绍
    BLE错误码全面解析&连接失败原因错误码解析&BLE Disconnect Reason
    【论文精读】Fast R-CNN
    Midjourney视觉垫图
    LeetCode题练习与总结:组合-77
    XXL-JOB定时任务框架(Oracle定制版)
  • 原文地址:https://blog.csdn.net/aidwao/article/details/134313398