首页 > 其他分享 >【23种设计模式】装饰模式(九)

【23种设计模式】装饰模式(九)

时间:2023-09-12 09:56:25浏览次数:48  
标签:功能 23 house public 装饰 House 设计模式 Renovation

前言

装饰模式,英文名称:Decorator Pattern。我第一次看到这个名称想到的是另外一个词语“装修”,我就说说我对“装修”的理解吧,大家一定要看清楚,是“装修”,不是“装饰”。在房子装修的过程中,各种功能可以相互组合,来增加房子的功用。类似的,如果我们在软件系统中,要给某个类型或者对象增加功能,如果使用“继承”的方案来写代码,就会出现子类暴涨的情况。比如:IMarbleStyle是大理石风格的一个功能,IKeepWarm是保温的一个接口定义,IHouseSecurity是房子安全的一个接口,就三个接口来说,House是我们房子,我们的房子要什么功能就实现什么接口,如果房子要的是复合功能,接口不同的组合就有不同的结果,这样就导致我们子类膨胀严重,如果需要在增加功能,子类会成指数增长。

装饰模式的定义

上述的问题的根源在于我们“过度地使用了继承来扩展对象的功能”,由于继承为类型引入的静态特质,所谓静态特质,就是说如果想要某种功能,我们必须在编译的时候就要定义这个类,这也是强类型语言的特点。静态,就是指在编译的时候要确定的东西;动态,是指运行时确定的东西。使得这种扩展方式缺乏灵活性;并且随着子类的增多(扩展功能的增多),各种子类的组合(扩展功能的组合)会导致更多子类的膨胀(多继承)。如何使“对象功能的扩展”能够根据需要来动态(即运行时)地实现?同时避免“扩展功能的增多”带来的子类膨胀问题?从而使得任何“功能扩展变化”所导致的影响降为最低?装饰者模式解决此问题应运而生,动态地给一个对象增加一些额外的职责。

装饰模式的组成

  • 抽象构件角色(Component):给出一个抽象接口,以规范准备接收附加责任的对象。

  • 具体构件角色(Concrete Component):定义一个将要接收附加责任的类。

  • 装饰角色(Decorator):持有一个构件(Component)对象的实例,并实现一个与抽象构件接口一致的接口。

  • 具体装饰角色(Concrete Decorator):负责给构件对象添加上附加的责任。
    image

装饰模式的实现

以装修房子为例,完成装饰着模式的代码实现

房子定义
    /// <summary>
    /// 该抽象类就是房子抽象接口的定义,该类型就相当于是Component类型,是饺子馅,需要装饰的,需要包装的
    /// </summary>
    public abstract class House
    {
        /// <summary>
        /// 房子的装修方法--该操作相当于Component类型的Operation方法
        /// </summary>
        public abstract void Renovation();
    }
   /// <summary>
    /// MyHouse的房子,我要按我的要求做房子,相当于ConcreteComponent类型
    /// </summary>
    public sealed class MyHouse : House
    {
        public override void Renovation()
        {
            Console.WriteLine("装修我的房子");
        }
    }
装饰类的定义
 /// <summary>
    /// 该抽象类就是装饰接口的定义,该类型就相当于是Decorator类型,如果需要具体的功能,可以子类化该类型
    /// </summary>
    public abstract class DecorationStrategy : House //关键点之二,体现关系为Is-a,有了这个关系,装饰的类也可以继续装饰了
    {
        //通过组合方式引用Decorator类型,该类型实施具体功能的增加
        //这是关键点之一,包含关系,体现为Has-a
        protected House _house;

        //通过构造器注入,初始化平台实现
        protected DecorationStrategy(House house)
        {
            this._house = house;
        }

        //该方法就相当于Decorator类型的Operation方法
        public override void Renovation()
        {
            if (this._house != null)
            {
                this._house.Renovation();
            }
        }
    }

安全需求类装饰定义
/// <summary>
    /// 具有安全功能的设备,可以提供监视和报警功能,相当于ConcreteDecoratorA类型
    /// </summary>
    public sealed class HouseSecurityDecorator : DecorationStrategy
    {
        public HouseSecurityDecorator(House house) : base(house) { }

        public override void Renovation()
        {
            base.Renovation();
            Console.WriteLine("增加安全系统");
        }
    }
保暖需求类装饰定义
 /// <summary>
    /// 具有保温接口的材料,提供保温功能,相当于ConcreteDecoratorB类型
    /// </summary>
    public sealed class KeepWarmDecorator : DecorationStrategy
    {
        public KeepWarmDecorator(House house) : base(house) { }

        public override void Renovation()
        {
            base.Renovation();
            Console.WriteLine("增加保温的功能");
        }
    }
调用
   public void RunTest()
        {
            //这就是我们需要装饰的房子
            House myselfHouse = new MyHouse();

            DecorationStrategy securityHouse = new HouseSecurityDecorator(myselfHouse);
            securityHouse.Renovation();

            /*
             * 此时房子就有了安全系统了.....
             */

            //【1】如果我既要安全系统又要保暖呢,继续装饰就行
            //DecorationStrategy securityAndWarmHouse = new KeepWarmDecorator(myselfHouse);
            //securityAndWarmHouse.Renovation();


            Console.WriteLine("\r\n*****************************\r\n");

            //【2】如果我既要安全系统又要保暖呢,继续装饰就行【和上边的进行运行比对】
            //【对运行结果难理解的话,打断点单步执行进行理解】

            DecorationStrategy securityAndWarmHouse1 = new KeepWarmDecorator(securityHouse);
            securityAndWarmHouse1.Renovation();
        }

image

装饰模式的优缺点

优点
  • 把抽象接口与其实现解耦。

  • 抽象和实现可以独立扩展,不会影响到对方。

  • 实现细节对客户透明,对用户隐藏了具体实现细节。

缺点
  • 增加了系统的复杂度

标签:功能,23,house,public,装饰,House,设计模式,Renovation
From: https://www.cnblogs.com/wml-it/p/17693849.html

相关文章

  • 【普通莫队】2023牛客多校5 A
    简介莫队算法是由莫涛提出的算法。在莫涛提出莫队算法之前,莫队算法已经在Codeforces的高手圈里小范围流传,但是莫涛是第一个对莫队算法进行详细归纳总结的人。莫涛提出莫队算法时,只分析了普通莫队算法,但是经过OIer和ACMer的集体智慧改造,莫队有了多种扩展版本。莫队算法可......
  • LeetCode523——连续的子数组和
    给你一个整数数组 nums 和一个整数 k ,编写一个函数来判断该数组是否含有同时满足下述条件的连续子数组:子数组大小 至少为2 ,且子数组元素总和为 k 的倍数。如果存在,返回 true ;否则,返回 false 。如果存在一个整数 n ,令整数 x 符合 x=n*k ,则称 x 是 ......
  • 2023-09-12
    1.早上被交警给逮了,走机动车道。还有车要上牌。2.随意刷了刷知乎。3.打板Smart-Plane和Smart-Telecontrol。生成Gerber文件发给了嘉立创,花了70大洋。https://www.zhihu.com/question/610456126/answer/31046711104.打开BOM表,到立创商城和淘宝买元器件。......
  • 2023年9月11日每日随笔
    今天,上了一些课,讲讲收获吧,首先,对于深度学习学不了一点;进行了zookeeper的配置:本地模式安装输入java-version验证是否有jdk拷贝apache-zookeeper-3.5.7-bin.tar.gz到/opt/software/中解压到opt/moduletar-zxvfapache-zookeeper-3.5.7-bin.tar.gz-C/opt/module/进入opt/......
  • 通过FPGA实现基于RS232串口的指令发送并控制显示器中目标位置
    1.算法理论概述       通过FPGA实现基于RS232串口的指令发送并控制显示器中目标位置是一种常见的应用场景,用于实现对显示器中目标位置的控制。该系统利用FPGA芯片作为主控制器,通过RS232串口与计算机或其他设备进行通信,接收指令并解析,然后控制显示器中目标位置的移动。该......
  • 2023.9.11
    今天是2023年9月11日,下午上了建民老师的java课,首先学习了把问题分解,大二学生首先需要解决的是把简单问题流程化,我们需要根据问题在脑海中形成流程图,高效的解决每一个细节问题。通过美国航天飞机爆炸的问题,我们更加的明白处理细节的重要性,越是简单越是不能松懈。然后就是学会分解问......
  • MoeCTF 2023
    0x01text64v1可以由用户操控,直接造成栈溢出。同时程序里存在分开的system函数和"/bin/sh"字符串,所以就是简单的ret2libc1。Exploit为frompwnimport*o=process("./pwn")bin_sh=0x404050system_plt=0x401090pop_rdi=0x4011BEret=0x4012A4o.sendline(b"200")......
  • kali官方博客 --- Kali Linux 2023.3 发布(内部基础架构与 Kali Autopilot) 2023 年 8
    今天,我们很高兴向大家介绍Kali的最新版本2023.3。这次的更新虽然没有在外观上增加很多新功能,但其中许多改进都是在系统内部进行的,这些改进对于开发团队来说非常有益处,同时也会以间接的方式对最终用户产生积极的影响。不言而喻,除了标准更新外,还有许多新软件包和工具。如果你想......
  • 2022-2023 ACM-ICPC German Collegiate Programming Contest (GCPC 2022)
    A.AlternativeArchitecture当倾斜放置时,一定可以构成直角三角形。枚举高用勾股定理算出底,然后在利用相似三角形即可算出另一条构成的直角三角形的边长,此时判断边是否都是整数即可。原图实际上点在格子上,一个常见的套路是边减一就可以转换成点在定点上。#include<bits/stdc+......
  • 2023.09.11
       今天上课通过看他人的代码,结合老师的讲解,看到了自己代码许多的重复部分完全可以用一个函数进行重复调用,这样既可以提高代码的运行效率,还能节省代码行数。通过自己重新编写代码,亲身感受到了其中的便捷性。    了解了其大道至简的编程思维  (代码编写的步骤) ......