.net设计模式之装饰模式(Decorator)

当我们需要在不改变原有类的情况下对其进行新功能添加或修改时,装饰模式是一种适用的设计模式。它允许向一个现有对象添加新的功能,同时又不改变其结构。该模式是一种结构性模式。

装饰模式(Decorator)的基本结构

装饰模式有四个角色:

  • 抽象构建(Component):定义一个对象接口,可以给这些对象动态地添加职责。
  • 具体构建(ConcreteComponent):定义一个具体对象,实现抽象构建接口。
  • 装饰(Decorator):持有一个构件对象的实例,并定义一个与抽象构件接口一致的接口。
  • 具体装饰(ConcreteDecorator):向组件添加新的职责。

以大杯奶茶为例的装饰模式

下面我们来使用大杯奶茶为例进行装饰,这里我们定义一个抽象构建 - 饮料(Beverage),它有一个计算价格的方法。

public abstract class Beverage
{
    public abstract double Cost();
}

而具体构建是在抽象构建之上实现的,下面我们定义一种具体构建 - 大杯奶茶(LargeMilkTea),它通过继承饮料来实现其自身的功能:

public class LargeMilkTea : Beverage
{
    public override double Cost()
    {
        return 10.0;
    }
}

现在,如果我们需要给大杯奶茶添加一份珍珠的话,可以使用装饰模式来实现,我们定义一个装饰 - 珍珠(Pearl),它持有一个饮料对象,并且也实现了计算价格的方法,但是它还增加了一份珍珠的花费:

public class Pearl : Beverage
{
    public Beverage Beverage { get; set; }

    public Pearl(Beverage beverage)
    {
        Beverage = beverage;
    }

    public override double Cost()
    {
        return Beverage.Cost() + 3.0;
    }
}

最后,我们可以使用以下代码创建一个大杯奶茶并加上一份珍珠:

Beverage milkTea = new LargeMilkTea();
milkTea = new Pearl(milkTea);

Console.WriteLine("花费:" + milkTea.Cost().ToString());

以数字为例子的装饰模式

下面,我们再以数字为例进行一个装饰,我们定义一个抽象构建 - 数字(Number),它有一个获取数字值的方法。

public abstract class Number
{
    public abstract int GetValue();
}

而具体构建是在抽象构建之上实现的,下面我们定义一种具体构建 - 十进制数(DecimalNumber),它实现了数字的功能:

public class DecimalNumber : Number
{
    private int value;

    public DecimalNumber(int value)
    {
        this.value = value;
    }

    public override int GetValue()
    {
        return value;
    }
}

现在我们定义一个装饰 - 减一(MinusOne),它持有一个数字对象,并且也实现了获取数字值的方法,但是它返回的值减一:

public class MinusOne : Number
{
    public Number Number { get; set; }

    public MinusOne(Number number)
    {
        Number = number;
    }

    public override int GetValue()
    {
        return Number.GetValue() - 1;
    }
}

最后,我们可以使用以下代码创建一个数字对象并减一:

Number number = new DecimalNumber(10);
number = new MinusOne(number);

Console.WriteLine("值:" + number.GetValue().ToString());

以上两个例子均为装饰模式的经典示例,它们展示了装饰模式能如何在已有对象中添加新功能而不改变其结构。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:.net设计模式之装饰模式(Decorator) - Python技术站

(0)
上一篇 2023年6月3日
下一篇 2023年6月3日

相关文章

  • ASP.NET MVC实现单个图片上传、限制图片格式与大小并在服务端裁剪图片

    在ASP.NET MVC中实现单个图片上传、限制图片格式与大小并在服务端裁剪图片,可以按照以下步骤进行: 步骤1:创建MVC项目 在Visual Studio中创建一个新的ASP.NET MVC项目。 步骤2:上传图 在Views文件夹中创建一个名为Upload的文件夹,并在其中创建一个名为Index.cshtml的视图。在视图中添加以下HTML代码: @u…

    C# 2023年5月12日
    00
  • ASP.NET Core Web API 教程Project Configuration

    ASP.NET Core Web API 教程Project Configuration攻略 ASP.NET Core Web API是一种用于构建RESTful Web服务的框架。在本攻略中,我们将深入探讨如何配置ASP.NET Core Web API项目,并提供两个示例说明。 创建ASP.NET Core Web API项目 在开始之前,您需要创建一个…

    C# 2023年5月17日
    00
  • C#实现归并排序

    下面是“C#实现归并排序”的完整攻略。 什么是归并排序 归并排序是一种基于“分治”思想的排序算法。该算法将待排数组递归地分成两部分,分别进行排序,最后合并成有序序列。 归并排序的步骤 拆分:将待排数组递归地拆分成左右两个子数组,直到每个子数组只有一个元素。 排序:将左右子数组分别进行排序,排序完成后合并。 合并:合并左右两个有序子数组为一个有序数组。 C#实…

    C# 2023年6月7日
    00
  • asp.net+Ligerui实现grid导出Excel和Word的方法

    下面是“asp.net+Ligerui实现grid导出Excel和Word的方法”的完整攻略。 一、前置条件 在开始实现导出Excel和Word的方法前,需要确保已经安装了以下环境: Visual Studio以及.NET Framework Ligerui框架 二、实现导出Excel和Word的方法 1. 导出Excel 步骤一:添加NuGet包 在Vis…

    C# 2023年5月31日
    00
  • C# Quartzs定时器的使用教程

    C# Quartz定时器的使用教程 什么是Quartz定时器? Quartz是一个强大的开源企业级调度框架,主要用于执行任务、计划任务、调度和定时任务等等。C# Quartz定时器是基于Quartz开源调度框架在C#环境下进行开发、应用的框架,可以更容易地实现任务调度和自动化任务执行等功能。 C# Quartz定时器的主要特点包括: 支持多种任务调度模式 灵…

    C# 2023年6月1日
    00
  • linq中的转换操作符

    当我们需要对一个或多个集合进行筛选、排序、分组等操作时,Linq提供了一些转换操作符(也称为方法)来处理数据,例如Where、OrderBy、GroupBy等。以下是Linq中的转换操作符的详细攻略。 1. Where Where方法可以用于过滤出符合条件的元素。该方法的参数是返回布尔值的Lambda表达式,表示元素是否符合条件。可以通过使用链式编程(cha…

    C# 2023年6月1日
    00
  • C#匹配中文字符串的4种正则表达式分享

    当我们需要在C#中匹配中文字符串时,我们通常会使用正则表达式进行匹配。下面是匹配中文字符串的4种C#正则表达式。 1. 匹配中文字符的Unicode编码范围 string pattern = @"[\u4e00-\u9fa5]"; Regex regex = new Regex(pattern); MatchCollection matc…

    C# 2023年6月8日
    00
  • C#实现简单的字符串加密

    下面我给你详细讲解一下C#实现简单的字符串加密的完整攻略。 一、加密算法的选择 字符串加密可以采用多种算法,这里我们使用最简单的一种——Caesar密码算法。该算法原理是将字符串中的每个字符按照一定数目的偏移量加密,解密时再将字符按照相同的偏移量向相反的方向偏移即可。 二、编写加密函数 接下来我们来编写一个加密函数。假设加密偏移量为3,我们将该函数命名为En…

    C# 2023年6月6日
    00
合作推广
合作推广
分享本页
返回顶部