C#常见的设计模式-结构型模式

news2024/10/5 20:27:48

引言

设计模式是软件工程中用于解决常见问题的可复用解决方案。在C#编程中,常见的设计模式具有广泛的应用。本篇博客将重点介绍C#中常见的结构型设计模式,包括适配器模式、装饰器模式、代理模式、组合模式和享元模式。
在这里插入图片描述


目录

    • 引言
    • 1. 适配器模式(Adapter Pattern)
      • 示例代码
      • 解释
    • 2. 桥接模式(Bridge Pattern)
      • 示例代码
      • 解释
    • 3. 外观模式(Facade)
      • 示例代码
      • 解释
    • 4. 装饰器模式(Decorator Pattern)
      • 示例代码
      • 解释
    • 5. 代理模式(Proxy Pattern)
      • 示例代码
      • 解释
    • 6. 组合模式(Composite Pattern)
      • 示例代码
      • 解释
    • 7. 享元模式(Flyweight Pattern)
      • 示例代码
      • 解释
    • 结论


1. 适配器模式(Adapter Pattern)

适配器模式用于将一个类的接口转换成客户端所期望的另一个接口。这种模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。

示例代码

// 目标接口
interface ITarget
{
    void Request();
}

// 需要被适配的类
class Adaptee
{
    public void SpecificRequest()
    {
        Console.WriteLine("Adaptee's SpecificRequest");
    }
}

// 适配器类
class Adapter : ITarget
{
    private Adaptee _adaptee;

    public Adapter(Adaptee adaptee)
    {
        _adaptee = adaptee;
    }

    public void Request()
    {
        _adaptee.SpecificRequest();
    }
}

// 客户端代码
class Client
{
    static void Main(string[] args)
    {
        Adaptee adaptee = new Adaptee();
        ITarget target = new Adapter(adaptee);
        target.Request();
    }
}

解释

适配器模式中的目标接口(ITarget)定义了客户端所期望的方法。Adaptee类是需要被适配的类,其中包含了一个SpecificRequest方法。Adapter类则是适配器,持有一个Adaptee对象的引用,并实现了ITarget接口。在AdapterRequest方法中,调用了AdapteeSpecificRequest方法。在客户端代码中,创建了一个Adaptee对象和一个Adapter对象,然后通过Adapter对象去调用Request方法。

2. 桥接模式(Bridge Pattern)

桥接模式是一种结构型设计模式,用于将抽象与实现隔离开来,使它们能够独立变化。它通过组合的方式代替继承,从而降低了系统的耦合性。该模式适合在需要多个维度进行扩展时使用,例如在图形界面库中,将窗口与不同操作系统的窗口装饰风格进行分离。桥接模式的核心思想是将抽象部分与实现部分分离,使它们可以独立地变化和演化。

示例代码

// 实现部分接口
interface Implementor {
    void operationImpl();
}

// 具体实现类A
class ConcreteImplementorA implements Implementor {
    @Override
    public void operationImpl() {
        System.out.println("ConcreteImplementorA operation implementation");
    }
}

// 具体实现类B
class ConcreteImplementorB implements Implementor {
    @Override
    public void operationImpl() {
        System.out.println("ConcreteImplementorB operation implementation");
    }
}

// 抽象部分
abstract class Abstraction {
    protected Implementor implementor;

    public void setImplementor(Implementor implementor) {
        this.implementor = implementor;
    }

    public abstract void operation();
}

// 扩展抽象部分的具体类
class RefinedAbstraction extends Abstraction {
    @Override
    public void operation() {
        implementor.operationImpl();
    }
}

// 使用示例
public class BridgePatternExample {
    public static void main(String[] args) {
        Implementor implementorA = new ConcreteImplementorA();
        Implementor implementorB = new ConcreteImplementorB();

        Abstraction abstraction = new RefinedAbstraction();
        abstraction.setImplementor(implementorA);
        abstraction.operation();

        abstraction.setImplementor(implementorB);
        abstraction.operation();
    }
}

解释

在上述示例中,​Implementor​ 接口定义了实现部分的操作方法。​ConcreteImplementorA​ 和ConcreteImplementorB​ 是具体的实现类。​Abstraction​ 是抽象部分的定义,其中包含一个实现部分的通用接口,并有一个抽象方法 ​operation()​ 来定义具体的操作。​RefinedAbstraction​ 是具体的扩展抽象类,实现了抽象方法并通过组合关联了具体的实现类。

3. 外观模式(Facade)

外观模式是一种结构型设计模式,提供了一个统一的接口,用来访问子系统中的一群接口。外观模式定义了一个高层接口,让子系统更容易使用。。

示例代码

// 子系统A
class SubsystemA {
    public void operationA() {
        System.out.println("SubsystemA operation");
    }
}

// 子系统B
class SubsystemB {
    public void operationB() {
        System.out.println("SubsystemB operation");
    }
}

// 子系统C
class SubsystemC {
    public void operationC() {
        System.out.println("SubsystemC operation");
    }
}

// 外观类
class Facade {
    private SubsystemA subsystemA;
    private SubsystemB subsystemB;
    private SubsystemC subsystemC;

    public Facade() {
        subsystemA = new SubsystemA();
        subsystemB = new SubsystemB();
        subsystemC = new SubsystemC();
    }

    public void operation() {
        subsystemA.operationA();
        subsystemB.operationB();
        subsystemC.operationC();
    }
}

// 使用示例
public class FacadePatternExample {
    public static void main(String[] args) {
        Facade facade = new Facade();
        facade.operation();
    }
}

解释

在上述示例中,​SubsystemA​、​SubsystemB​ 和 ​SubsystemC​ 是不同的子系统,它们分别提供了不同的操作。​Facade​ 是外观类,隐藏了子系统的复杂性,为客户端提供了一个简单的接口。在外观类的操作方法中,调用了多个子系统的操作。

4. 装饰器模式(Decorator Pattern)

装饰器模式允许向一个现有对象添加新功能,同时又不改变其结构。它是通过创建一个包装对象来包裹真实对象,从而对真实对象进行功能的扩展。

示例代码

// 抽象组件接口
interface IComponent
{
    void Operation();
}

// 具体组件类
class ConcreteComponent : IComponent
{
    public void Operation()
    {
        Console.WriteLine("ConcreteComponent's Operation");
    }
}

// 抽象装饰者类
abstract class Decorator : IComponent
{
    protected IComponent _component;

    public Decorator(IComponent component)
    {
        _component = component;
    }

    public virtual void Operation()
    {
        _component.Operation();
    }
}

// 具体装饰者类
class ConcreteDecoratorA : Decorator
{
    public ConcreteDecoratorA(IComponent component)
        : base(component)
    {
    }

    public override void Operation()
    {
        base.Operation();
        AddedBehavior();
    }

    private void AddedBehavior()
    {
        Console.WriteLine("ConcreteDecoratorA's AddedBehavior");
    }
}

class ConcreteDecoratorB : Decorator
{
    public ConcreteDecoratorB(IComponent component)
        : base(component)
    {
    }

    public override void Operation()
    {
        base.Operation();
        AddedBehavior();
    }

    private void AddedBehavior()
    {
        Console.WriteLine("ConcreteDecoratorB's AddedBehavior");
    }
}

// 客户端代码
class Client
{
    static void Main(string[] args)
    {
        IComponent component = new ConcreteComponent();
        component = new ConcreteDecoratorA(component);
        component = new ConcreteDecoratorB(component);
        component.Operation();
    }
}

解释

装饰器模式中的抽象组件接口(IComponent)定义了被装饰者和装饰者之间的公共方法。ConcreteComponent类是具体的组件类,实现了IComponent接口的Operation方法。Decorator类是抽象装饰者类,持有一个IComponent对象的引用,并实现了IComponent接口。ConcreteDecoratorAConcreteDecoratorB类分别是具体装饰者类,它们继承自Decorator类,并在调用父类Operation方法的同时添加了额外的行为。

在客户端代码中,首先创建了一个ConcreteComponent对象,然后通过多次进行装饰,分别使用ConcreteDecoratorAConcreteDecoratorB对其进行包装。最后调用component.Operation()方法时,实际上会调用被装饰者的Operation方法,并在其基础上添加了额外的行为。

5. 代理模式(Proxy Pattern)

代理模式为其他对象提供一种代理以控制对这个对象的访问。代理模式主要通过代理类来封装目标对象,控制客户端对目标对象的访问,并在必要的时候进行一些预处理或后处理操作。

示例代码

// 被代理接口
interface ISubject
{
    void Request();
}

// 真实对象类
class RealSubject : ISubject
{
    public void Request()
    {
        Console.WriteLine("RealSubject's Request");
    }
}

// 代理类
class Proxy : ISubject
{
    private RealSubject _realSubject;

    public void Request()
    {
        if (_realSubject == null)
        {
            _realSubject = new RealSubject();
        }

        PreProcess();
        _realSubject.Request();
        PostProcess();
    }

    private void PreProcess()
    {
        Console.WriteLine("Proxy's PreProcess");
    }

    private void PostProcess()
    {
        Console.WriteLine("Proxy's PostProcess");
    }
}

// 客户端代码
class Client
{
    static void Main(string[] args)
    {
        ISubject proxy = new Proxy();
        proxy.Request();
    }
}

解释

代理模式中的被代理接口(ISubject)定义了代理对象和真实对象的公共方法。RealSubject类是真实对象类,实现了被代理接口的Request方法。Proxy类是代理类,持有一个RealSubject对象的引用,并实现了被代理接口的Request方法。在Proxy类的Request方法中,进行了预处理、调用真实对象的Request方法和后处理。

在客户端代码中,创建了一个代理对象Proxy,然后通过该对象调用Request方法。在调用过程中,会对真实对象进行实例化,并在方法执行前后进行相应的预处理和后处理。

6. 组合模式(Composite Pattern)

组合模式将对象组合成树形结构以表示"部分-整体"的层次结构。组合模式使得客户端对单个对象和组合对象的使用具有一致性。

示例代码

// 抽象组件类
abstract class Component
{
    protected string _name;

    public Component(string name)
    {
        _name = name;
    }

    public abstract void Display();
}

// 叶子节点类
class Leaf : Component
{
    public Leaf(string name)
        : base(name)
    {
    }

    public override void Display()
    {
        Console.WriteLine(_name);
    }
}

// 容器节点类
class Composite : Component
{
    private List<Component> _children = new List<Component>();

    public Composite(string name)
        : base(name)
    {
    }

    public void Add(Component component)
    {
        _children.Add(component);
    }

    public void Remove(Component component)
    {
        _children.Remove(component);
    }

    public override void Display()
    {
        Console.WriteLine(_name);
        foreach (Component component in _children)
        {
            component.Display();
        }
    }
}

// 客户端代码
class Client
{
    static void Main(string[] args)
    {
        Composite root = new Composite("root");
        Leaf leaf1 = new Leaf("leaf1");
        Leaf leaf2 = new Leaf("leaf2");
        Composite composite1 = new Composite("composite1");
        Composite composite2 = new Composite("composite2");

        root.Add(leaf1);
        root.Add(composite1);
        composite1.Add(leaf2);
        composite1.Add(composite2);

        root.Display();
    }
}

解释

组合模式中的抽象组件类(Component)定义了树状结构中所有对象的通用行为的接口。Leaf类是叶子节点类,它继承自Component类,并实现了Display方法。Composite类是容器节点类,它继承自Component类,并持有一组Component对象。在Composite类的Display方法中,首先输出自身信息,然后递归调用所有子节点的Display方法。

在客户端代码中,首先创建了一个根节点root和一些叶子节点和容器节点。通过调用容器节点的Add方法可以将其他节点添加到其内部。最后调用root.Display()方法,会递归地展示整个树状结构。

7. 享元模式(Flyweight Pattern)

享元模式是一种池技术,主要用于减少创建对象的数量,以减少内存占用和提高性能。享元模式通过共享已创建的对象,避免重复创建相同的对象。

示例代码

// 享元接口
interface IFlyweight
{
    void Operation();
}

// 具体享元类
class ConcreteFlyweight : IFlyweight
{
    private readonly string _intrinsicState;

    public ConcreteFlyweight(string intrinsicState)
    {
        _intrinsicState = intrinsicState;
    }

    public void Operation()
    {
        Console.WriteLine($"ConcreteFlyweight's Operation with {_intrinsicState}");
    }
}

// 享元工厂类
class FlyweightFactory
{
    private Dictionary<string, IFlyweight> _flyweights = new Dictionary<string, IFlyweight>();

    public IFlyweight GetFlyweight(string key)
    {
        if (_flyweights.ContainsKey(key))
        {
            return _flyweights[key];
        }
        else
        {
            IFlyweight flyweight = new ConcreteFlyweight(key);
            _flyweights.Add(key, flyweight);
            return flyweight;
        }
    }
}

// 客户端代码
class Client
{
    static void Main(string[] args)
    {
        FlyweightFactory factory = new FlyweightFactory();

        IFlyweight flyweight1 = factory.GetFlyweight("key1");
        flyweight1.Operation();

        IFlyweight flyweight2 = factory.GetFlyweight("key2");
        flyweight2.Operation();

        IFlyweight flyweight3 = factory.GetFlyweight("key1");
        flyweight3.Operation();
    }
}

解释

享元模式中的享元接口(IFlyweight)定义了享元类的公共方法。ConcreteFlyweight类是具体享元类,它实现了IFlyweight接口,并持有一个内部状态(_intrinsicState)。FlyweightFactory类是享元工厂类,用于创建和管理享元对象。

在客户端代码中,首先创建了一个FlyweightFactory对象。通过调用工厂的GetFlyweight方法可以获取享元对象,如果对象已经存在,则直接返回已有对象;如果对象不存在,则创建新的享元对象并将其缓存起来。最后调用享元对象的Operation方法时,会输出其内部状态。

在这里插入图片描述


结论

结构型设计模式在C#编程中具有广泛的应用。适配器模式用于解决不兼容接口的问题,装饰器模式用于动态地扩展对象的功能,代理模式用于控制对对象的访问,组合模式用于处理树状结构数据,享元模式用于减少对象创建的数量。合理使用这些结构型设计模式可以提高代码的可读性、可维护性和可扩展性。

参考资料:

  • Design Patterns in C#

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

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

相关文章

便利高效双赢:无人机油气管道巡检全面升级

我国庞大的油气管道网络&#xff0c;包括原油、成品和天然气管道&#xff0c;因为地理区域广泛、建设年代久远、安全事故频发等现实因素&#xff0c;对管道的安全巡护与管理提出了更高的需求。在这一背景下&#xff0c;传统的人工巡护方式显然已经难以满足对高、精、准的要求。…

【受体 + 二系统 】

GPCR A级超家族家庭成员/基因评论胺受体受体的六个亚家族总共包括45个基因&#xff08;其中4个是假基因&#xff09;;这六个亚家族是5-羟色胺&#xff08;5-HT&#xff0c;血清素&#xff09;受体&#xff08;13个基因&#xff09;&#xff0c;多巴胺受体&#xff08;5个基…

瑞数五代ast反混淆笔记一

第一部分 瑞数五代ast反混淆笔记一 文章目录 前言一、分析第一层js文件二、转换为switch-case三、效果图总结 前言 瑞数五代的反混淆做了很久了&#xff0c;当时写的很复杂&#xff0c;也没有记笔记&#xff0c;现在看代码都看不懂了&#xff0c;重新归顺下逻辑思路 一、分析第…

Bitcoin SV 和 Bitcoin Core 之间首次跨链原子交换

我们已经执行了 Bitcoin SV 和 Bitcoin Core 之间的首次原子交换。 这一成就代表了比特币 SV 的重大进步&#xff0c;以去信任的方式促进了与其他区块链的无缝互操作性。 图片源自Gemini 在上一篇文章中&#xff0c;我们解释了原子交换的高级理论。 我们深入研究了使用哈希时间…

供配电系统智能化监控

供配电系统智能化监控是指利用先进的监测技术、自动化控制技术、计算机网络技术等&#xff0c;对供配电系统进行实时、全方位的监测和控制&#xff0c;以实现供配电系统的安全、稳定、高效运行。 供配电系统智能化监控的主要功能包括&#xff1a; 实时数据采集&#xff1a;通过…

C语言WFC绘制矩形

代码实现&#xff1a; void CCGDrawingView::Rectangle(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4, COLORREF color,CDC* pDC) {CPen redPen(PS_SOLID, 1, color);CBrush redBursh(color);CPen* pOldPen pDC->SelectObject(&redPen);CBrush* p…

十八数字文化受邀参加版博会“区块链+版权”创新应用试点研讨会

2023年11月23日至25日&#xff0c;以“版权新时代 赋能新发展”为主题的第九届中国国际版权博览会在成都市中国西部国际博览城和天府国际会议中心举办。版博会是我国版权领域唯一的综合性、国际性、国家级版权专业博览会&#xff0c;本届版博会由国家版权局主办&#xff0c;四川…

双十一备战与复盘

如何组织备战 重要节点 从大促启动会开始后我就开始计划我们本次备战的整体节奏。 挑战在哪 以上内容介绍了CDP平台有多么重要&#xff0c;那么画像系统备战的核心挑战在“如何保障在大流量高并发情况下系统稳定提供高性能服务”&#xff0c;主要表现在&#xff1a;稳定性、…

【GO】k8s 管理系统项目16[前端部分--项目初始化]-学习记录

学习链接 https://blog.csdn.net/qq_29974229/article/details/129119279?spm1001.2014.3001.5502 nvm use v16.15.0 npm install vue -g npm install -g vue/clivue create k8s-plantform-fe选择 Default cd k8s-plantform-fe npm run servecd ./src mkdir views mkdir r…

ESXi 6.7 升级 7.0

方式一&#xff1a;esxcli方式 1.登陆exsi web界面。 启用控制台shell 2.存储-datastore-数据存储浏览器&#xff0c;上载 ESXI-7.0.0-depot.zip升级文件。记住此datastore的位置 ssh连接ESXI主机 vmware -vl 查看当前版本 查看升级包中对应的版本信息&#xff1a; es…

长沙市中小学入学报名流程及上传证件照电子版制作方法

长沙市中小学入学报名是家长和学生迈向教育之门的第一步。通常&#xff0c;报名过程分为线上和线下两个阶段。首先&#xff0c;家长需在规定时间内登录报名系统&#xff0c;填写详细的入学信息等。长沙市注重教育公平&#xff0c;为确保每个孩子都有平等的入学机会&#xff0c;…

(六)上市企业实施IPD成功案例分享之——中兴通讯

在通信业&#xff0c;项目交付的质量和效率&#xff0c;很大程度上影响着运营商的竞争力&#xff0c;先进的项目管理理念、数字化的项目管理工具及丰富的实践经验&#xff0c;是运营商选择合作伙伴的主要维度。在中国&#xff0c;IPD之所以名气这么大&#xff0c;最大的原因就是…

【全新升级】:Word、Excel和PPT批量转PDF - PyQt设计

文章目录 ✨前言✨脚本使用教程&#x1f4da;资源领取&#xff08;含源代码&#xff09; ✨前言 最近花了十几天的时间学习了PyQt的使用&#xff0c;发现PyQt具有丰富的特性和功能&#xff0c;可以创建出漂亮、交互性强的GUI应用程序&#xff0c;而且还可通过CSS样式表来设计界…

C语言:编程实现1!+2!+3!+4!+……+n!

分析&#xff1a; #include<stdio.h>//这是一个预处理指令&#xff0c;将stdio.h头文件包含到程序中&#xff0c;以便使用输入输出函数。 int main()//这是程序的主函数&#xff0c;是程序执行的入口点。 int i, a 1, t 0, n;//定义了整型变量i、a、t和n。其中&#x…

viple模拟器使用(二):Web 2D模拟器中实现沿右墙迷宫算法

沿右墙迷宫算法原理 默认直行&#xff1b;右侧有路&#xff0c;则右转&#xff1b;前方无路&#xff0c;则左转。 使用了2个传感器&#xff0c;分别是&#xff1a;机器人右侧的距离传感器 、前方的触觉传感器。 按照逻辑&#xff0c;程序中需要左转&#xff08;Left90&#xf…

ESXi 添加新网络 配置ubuntu虚拟机双网卡

基本概念 在ESXi的虚拟机之间确保正常通信的基础是网络服务&#xff0c;通常在物理网络中需要使用不同的物理设备进行连接才能组建出高效的网络服务&#xff0c;而在虚拟网络中&#xff0c;需要不同的虚拟设备为其提供服务。 ESXi的网络类型&#xff1a; 1、物理网络&#xf…

(七)上市企业实施IPD成功案例分享之——波音

有数据统计&#xff0c;早在疫情前的2019年&#xff0c;全球民用航空运输的旅客数量就已经达到了45亿人的峰值。其中&#xff0c;中国民航总计运输6.6亿人次。而只要出行坐飞机&#xff0c;就会发现机型大都是波音。事实上&#xff0c;波音公司垄断了全球几近一半的民航大飞机&…

Sass 安装

文章目录 前言SASS的系统要求安装Ruby例子后言 前言 hello world欢迎来到前端的新世界 &#x1f61c;当前文章系列专栏&#xff1a;Sass和Less &#x1f431;‍&#x1f453;博主在前端领域还有很多知识和技术需要掌握&#xff0c;正在不断努力填补技术短板。(如果出现错误&…

排序篇(六)----排序小结(不用三连,混流量券)

排序篇(六)----排序小结 排序算法复杂度及稳定性分析 直接插入排序的算法复杂度&#xff1a; 最好情况下&#xff0c;当数组已经有序时&#xff0c;直接插入排序的时间复杂度为O(n)&#xff0c;其中n是数组的大小。最坏情况下&#xff0c;当数组逆序排列时&#xff0c;直接插…

有哪些可信的SSL证书颁发机构?

目前市面上所显示的SSL证书颁发机构可所谓不计其数&#xff0c;类型也是多样&#xff0c;就好比我们同样是买一件T恤&#xff0c;却有百家不同类型的店铺一个道理。根据CA里面看似很多&#xff0c;但能拿到99%浏览器及设备信任度的寥寥无几&#xff0c;下面小编整理出几家靠谱可…