装饰者模式-C#实现

news2024/11/13 13:00:08

可以使用装饰者模式来动态地给一个对象添加额外的职责。

装饰者模式以对客户透明的方式动态地给一个对象附加上更多的责任,装饰者模式相比生成子类可以更灵活地增加功能。

在装饰者模式中各个角色有:
抽象构件(Phone)角色:给出一个抽象接口,以规范准备接受附加责任的对象。
具体构件(AppPhone)角色:定义一个将要接收附加责任的类。
装饰(Dicorator)角色:持有一个构件(Component)对象的实例,并定义一个与抽象构件接口一致的接口。
具体装饰(Sticker和Accessories)角色:负责给构件对象 ”贴上“附加的责任。

优点:
装饰这模式和继承的目的都是扩展对象的功能,但装饰者模式比继承更灵活
通过使用不同的具体装饰类以及这些类的排列组合,设计师可以创造出很多不同行为的组合
装饰者模式有很好地可扩展性

缺点:装饰者模式会导致设计中出现许多小对象,如果过度使用,会让程序变的更复杂。


意图:动态地给一个对象添加一些额外的职责。就增加功能来说,装饰器模式相比生成子类更为灵活。
主要解决:一般的,我们为了扩展一个类经常使用继承方式实现,由于继承为类引入静态特征,并且随着扩展功能的增多,子类会很膨胀。
何时使用:在不想增加很多子类的情况下扩展类。
如何解决:将具体功能职责划分,同时继承装饰者模式。
关键代码: 1、Component 类充当抽象角色,不应该具体实现。 2、修饰类引用和继承 Component 类,具体扩展类重写父类方法。

该实例基于WPF实现,直接上代码,下面为三层架构的代码。

一 Model

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 设计模式练习.Model.装饰者模式
{
    //装饰抽象类:要让装饰完全取代抽象组件,所以必须继承Car
    public abstract class AbstructCar : Car
    {
        public string Result { get; set; }
        private Car car;

        protected AbstructCar(Car car)
        {
            this.car = car;
        }

        public override void Print()
        {
            if (this.car != null)
            {
                this.car.Print();
            }
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 设计模式练习.Model.装饰者模式
{
    //奥迪车:装修者模式中的具体组件类
    public class ADCar : Car
    {
        public string Result { get; set; }

        //重写基类方法
        public override void Print()
        {
            Result = "开始执行具体的对象-奥迪汽车";
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 设计模式练习.Model.装饰者模式
{
    public class BigLight : AbstructCar
    {

        public BigLight(Car car) : base(car)
        {
        }

        public override void Print()
        {
            base.Print();
            //添加新的行为
            addBigLight();
        }

        private void addBigLight()
        {
            Result = "现在奥迪车加装了炫酷的大灯了。。。"; 
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 设计模式练习.Model.装饰者模式
{
    //汽车抽象类:装饰者模式中的抽象组件类
    public abstract class Car
    {
        public abstract void Print();
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 设计模式练习.Model.装饰者模式
{
    internal class Navigation : AbstructCar
    {
        public Navigation(Car car) : base(car)
        {
        }

        public override void Print()
        {
            base.Print();
            //增加新的行为
            addNav();
        }

        private void addNav()
        {
            Result = "奥迪车新增了一个导航,太牛了";
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 设计模式练习.Model.装饰者模式
{
    //汽车贴膜:具体装饰者
    public class Sticker : AbstructCar
    {
        

        public Sticker(Car car) : base(car)
        {
        }

        public override void Print()
        {
            base.Print();
            //添加新的行为
            addSticker();
        }

        private void addSticker()
        {
            Result = "奥迪车已经贴膜了";
        }
    }
}

二 View

<Window x:Class="设计模式练习.View.装饰者模式.Decorators"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:设计模式练习.View.装饰者模式"
        mc:Ignorable="d"
        Title="Decorators" Height="450" Width="800">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>

        <Label Grid.Row="0" Grid.Column="0" Content="{Binding Res1}"/>
        <Label Grid.Row="1" Grid.Column="0" Content="{Binding Res2}"/>
        <Label Grid.Row="2" Grid.Column="0" Content="{Binding Res3}"/>

        <Button Grid.Row="0" Grid.Column="1" Content="增加大灯" Command="{Binding add1Command}"/>
        <Button Grid.Row="1" Grid.Column="1" Content="增加贴膜" Command="{Binding add2Command}"/>
        <Button Grid.Row="2" Grid.Column="1" Content="增加全球导航" Command="{Binding add3Command}"/>
    </Grid>
</Window>

三 ViewModel

using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using 设计模式练习.Model.装饰者模式;

namespace 设计模式练习.ViewModel.装饰者模式
{
    partial class Combination_ViewModel : ObservableObject
    {
        //购买了一款奥迪车
        Car car=new ADCar();

        [ObservableProperty]
        private string res1;

        [ObservableProperty]
        private string res2;

        [ObservableProperty]
        private string res3;

        [RelayCommand]
        private void add2()
        {
            //汽车加装贴膜
            AbstructCar abstructCar = new Sticker(car);
            //正式加装贴膜
            abstructCar.Print();

            Res1 = abstructCar.Result; 
        }

        [RelayCommand]
        private void add1()
        {
            //汽车加装大灯
            AbstructCar abstructCar = new BigLight(car);
            //正式加装大灯
            abstructCar.Print();

            Res2 = abstructCar.Result;
        }

        [RelayCommand]
        private void add3()
        {
            //汽车加装导航
            AbstructCar abstructCar = new Navigation(car);
            //正式加装导航
            abstructCar.Print();

            Res3 = abstructCar.Result;
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1512972.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【NR 定位】3GPP NR Positioning 5G定位标准解读(十三)-DL-AoD定位

前言 3GPP NR Positioning 5G定位标准&#xff1a;3GPP TS 38.305 V18 3GPP 标准网址&#xff1a;Directory Listing /ftp/ 【NR 定位】3GPP NR Positioning 5G定位标准解读&#xff08;一&#xff09;-CSDN博客 【NR 定位】3GPP NR Positioning 5G定位标准解读&#xff08;…

STM32点亮LED灯与蜂鸣器发声

STM32之GPIO GPIO在输出模式时可以控制端口输出高低电平&#xff0c;用以驱动Led蜂鸣器等外设&#xff0c;以及模拟通信协议输出时序等。 输入模式时可以读取端口的高低电平或电压&#xff0c;用于读取按键输入&#xff0c;外接模块电平信号输入&#xff0c;ADC电压采集灯 GP…

EM算法详解

EM(Expectation-Maximum)算法也称期望最大化算法,曾入选“数据挖掘十大算法”中,可见EM算法在机器学习、数据挖掘中的影响力。EM算法是最常见的隐变量估计方法,在机器学习中有极为广泛的用途,例如常被用来学习高斯混合模型(Gaussian mixture model,简称GMM)的参数;隐…

3D产品配置器帮助您更快进入市场的 5 种方式

如果您的电子商务商店可以从产品配置器的使用中受益&#xff08;而且大多数都可以&#xff09;&#xff0c;您还应该知道&#xff0c;此功能还可以帮助您的公司采用更具创新性的产品开发姿态。 更简单地说&#xff1a;它可以帮助您更快地构建更好的产品。 继续阅读以了解3D 产…

FPGA Vivado环境下实现D触发器

题目要求&#xff1a;使用Verilog HDL语言设计一个D触发器。请提交程序源代码和Word格式的作业文档&#xff0c;作业文档中应给出程序源代码及RTL分析原理图。 D触发器的工作原理&#xff1a; 初始状态下&#xff0c;触发器处于复位状态&#xff0c;输出为复位信号的稳定状态…

springboot266基于Web的农产品直卖平台的设计与实现

农产品直卖平台的设计与实现 摘 要 计算机网络发展到现在已经好几十年了&#xff0c;在理论上面已经有了很丰富的基础&#xff0c;并且在现实生活中也到处都在使用&#xff0c;可以说&#xff0c;经过几十年的发展&#xff0c;互联网技术已经把地域信息的隔阂给消除了&#x…

2024 前端javaScript+ES6

JavaScript 基础 1、基本数据类型&#xff1a; 1.1 基本数据类型&#xff1a; Number&#xff08;数值&#xff09;&#xff1a;表示数字&#xff0c;包括整数和浮点数。例如&#xff1a;5、3.14。 String&#xff08;字符串&#xff09;&#xff1a;表示文本数据&#xff…

Docker容器化技术(互联机制实现便捷互访)

容器的互联是一种让多个容器中的应用进行快速交互的方式。它会在源和接收容器之间创建连接关系&#xff0c;接收容器可以通过容器名快速访问到源容器&#xff0c;而不用指定具体的IP地址。 1.自定义容器命名 连接系统依据容器的名称来执行。因此&#xff0c;首先需要自定义一…

【数据挖掘】实验2:R入门2

实验2&#xff1a;R入门2 一&#xff1a;实验目的与要求 1&#xff1a;熟悉和掌握R数据类型。 2&#xff1a;熟悉和掌握R语言的数据读写。 二&#xff1a;实验内容 1&#xff1a;R数据类型 【基本赋值】 Eg.1代码&#xff1a; x <- 8 x Eg.2代码&#xff1a; a city …

谷歌破解 OpenAI 模型关键信息;微软更改默认浏览器,不再主推 Edge 丨 RTE 开发者日报 Vol.163

开发者朋友们大家好&#xff1a; 这里是 「RTE 开发者日报」 &#xff0c;每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE &#xff08;Real Time Engagement&#xff09; 领域内「有话题的 新闻 」、「有态度的 观点 」、「有意思的 数据 」、「有思考的 文…

fate隐私求交案例

intersect组件是解决纵向联邦学习中的隐私求交问题 fate隐私求交的方式有三种&#xff1a;raw,rsa,dh。raw方式不安全&#xff0c;rsa和dh方式是安全的&#xff0c;dh是基于对称加密的安全交集 rsa是基于RSA(非对称加密)的安全交集&#xff0c;&#xff0c;dh方法也用于安全的…

Uni-app跟学笔记(一):新建项目、运行、tabbar、全局配置

文章目录 1&#xff09;新建项目2&#xff09;项目运行3&#xff09;项目结构4&#xff09;开发规范5&#xff09;globalStyle全局外观配置6&#xff09;pages页面配置7&#xff09;tabbar8&#xff09;Condition 本博客为 uni-app 此门课的跟学笔记&#xff0c;目的是便于个人…

如何在安卓端的SAP里配置打印机

1、转到 SPAD 事务&#xff08;“假脱机管理”屏幕&#xff09;。单击“设备/服务器”选项卡&#xff0c;输入输出设备的名称&#xff0c;然后点击显示按钮。 2、如果打印机已配置&#xff0c;它将显示设备属性、输出设备属性和纸盒信息的所有详细信息。如果输入新的打印机名称…

基于ssm的志愿者招募系统的设计与实现(程序+文档+数据库)

** &#x1f345;点赞收藏关注 → 私信领取本源代码、数据库&#x1f345; 本人在Java毕业设计领域有多年的经验&#xff0c;陆续会更新更多优质的Java实战项目&#xff0c;希望你能有所收获&#xff0c;少走一些弯路。&#x1f345;关注我不迷路&#x1f345;** 一、研究背景…

Java学习笔记------常用API(二)

Object 无有参构造 public Object() 空参构造 成员方法&#xff1a; public String toString() 返回对象的字符串表示 public boolean equals(object obj) 比较两个对象是否相等 Object默认用号比较地址值&#xff0c;需要重写才能比较属性值 protected O…

基于java+springboot+vue实现的自习室管理和预约系统(文末源码+Lw)23-177

摘 要 传统办法管理信息首先需要花费的时间比较多&#xff0c;其次数据出错率比较高&#xff0c;而且对错误的数据进行更改也比较困难&#xff0c;最后&#xff0c;检索数据费事费力。因此&#xff0c;在计算机上安装自习室管理和预约系统软件来发挥其高效地信息处理的作用&a…

vue脚手架创建项目失败,报错淘宝镜像地址证书过期问题解决

场景&#xff1a; 使用vue-cli脚手架创建vue新项目时&#xff0c;控制台报错&#xff0c;创建失败 控制台报错&#xff1a;ERROR Failed to get response from https://registry.npm.taobao.org/binary-mirror-config 尝试过的方式&#xff1a; 清除npm缓存或删除npm-cache文…

YashanDB亮相2024年中国石油石化信息通信技术交流大会

3月6日-8日&#xff0c;2024年中国石油石化信息通信技术交流大会在成都举办。YashanDB携智慧油气化数据管理解决方案亮相本次展会&#xff0c;展示最新的研发成果和场景应用。 当前&#xff0c;石油石化行业数字化转型不断深化&#xff0c;随之而来的是海量数据的计算与交互&a…

代码随想录算法训练营第day41|背包理论基础、416. 分割等和子集

目录 a.背包理论基础——01背包 1.二维数组的01背包表示 2.一维滚动数组表示 b. 416. 分割等和子集 - 力扣&#xff08;LeetCode&#xff09; a.背包理论基础——01背包 背包问题分类&#xff1a; 对于面试的话&#xff0c;其实掌握01背包&#xff0c;和完全背包&#xff…

Vulkan 围炉夜话

系列文章目录 OpenGL 围炉夜话 Vulkan 围炉夜话 文章目录 系列文章目录Vulkan参考书教程学习摘要VkImage 、VkBufferVkImage 相关VkBuffer 相关VkDeviceMemory 映射 理解代码流线渲染通道理解渲染通道创建渲染通道 VkFramebuffer 帧缓存流水线创建流水线缓冲对象&#xff08;PC…