.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日

相关文章

  • C#中判断本地系统的网络连接状态的方法

    C#中判断本地系统的网络连接状态有多种方法,以下是其中两种方法的详细讲解。 方法一:使用.NET Framework提供的System.Net.NetworkInformation命名空间中的NetworkInterface类。 步骤如下: 引用System.Net.NetworkInformation命名空间。 使用NetworkInterface类的Ge…

    C# 2023年6月7日
    00
  • C# Linq的Distinct()方法 – 返回序列中不同的元素

    当我们需要在C#中从一个集合中筛选出不同的元素,Linq的Distinct()方法就非常适用了。在这里,我将为您提供C#Linq的Distinct()方法的完整攻略,包括定义、返回值、语法、使用方法和示例。 定义 Distinct()方法是Linq用于从集合中返回不同元素的方法之一。该方法基于对象的值,比较并取消重复出现的元素。不同于其他返回元素的方法,Di…

    C# 2023年4月19日
    00
  • 记一次 .NET 某手术室行为信息系统 内存泄露分析

    一:背景 1. 讲故事 昨天有位朋友找到我,说他的程序内存存在泄露导致系统特别卡,大地址也开了,让我帮忙看一下怎么回事?今天上午看了下dump,感觉挺有意思,在我的分析之旅中此类问题也蛮少见,算是完善一下体系吧。 二:WinDbg 分析 1. 到底是哪里的泄露 在.NET高级调试训练营中,我多次告诉学员们,在分析此类问题时一定要搞清楚是托管还是非托管的问题,…

    C# 2023年4月18日
    00
  • 基于Dapper实现分页效果 支持筛选、排序、结果集总数等

    下面是 “基于Dapper实现分页效果 支持筛选、排序、结果集总数等” 的完整攻略。 思路 实现分页的关键是计算结果集并将结果划分为多个位置。Dapper是一个轻量级的ORM工具,它可以通过SQL轻松实现分页。Dapper分页需要提供三个参数: 页码 每页显示的行数 排序方式 同时也要考虑到关键字搜索等一些额外的筛选条件。 实现步骤 第一步:构建SQL查询语…

    C# 2023年6月3日
    00
  • 浅谈C# async await 死锁问题总结

    下面是针对“浅谈C#asyncawait死锁问题总结”的完整攻略: 什么是async/await死锁问题 async/await 是 C# 中一种使异步编程更加便捷的方式。但是在某些情况下,使用不当会引发死锁问题。 在使用 async/await 时,我们往往会使用到 Task.Wait() 或 Task.Result 这些阻塞方法来获取异步操作的结果。 但…

    C# 2023年5月15日
    00
  • Go遍历struct,map,slice的实现

    首先,可以通过for-range语句遍历切片和映射。for-range语句让代码更清晰易懂。 遍历slice 下面是遍历slice的示例: package main import "fmt" func main() { // 声明一个字符串切片 fruits := []string{"apple", "ban…

    C# 2023年5月31日
    00
  • C#中Convert.ToString和ToString的区别分析

    下面是“C#中Convert.ToString和ToString的区别分析”的完整攻略。 什么是 Convert.ToString 和 ToString 在 C# 中,基本数据类型、数据类型的变量、对象都提供了 ToString 方法,用于将其转换为字符串表示形式。Convert.ToString 方法也可以将一个对象转换为字符串。 Convert.ToSt…

    C# 2023年5月15日
    00
  • unity scrollRect实现按页码翻页效果

    下面是Unity中ScrollRect实现按页码翻页效果的攻略: 1. 需求分析 首先,我们需要明确我们的需求:利用ScrollRect制作一个翻页效果,实现按页码进行翻页操作。这意味着我们需要按照固定的大小拆分显示内容,每个页面的大小应该相同,并且在翻页时应该有一个平滑的过渡动画。 2. 设置ScrollRect参数 首先,我们需要在Unity中创建一个S…

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