常见的设计模式及工业场景下应用(更新中)

目录:

一、前言

无论那种编程语言,特别是面向对象OOP(Object-Oriented Programming,简称 OOP)这种,在编写特定场景下,有对应编码方式有会对应的优势,这时候就需要用到设计模式。

"GoF"是软件设计里一个非常经典的缩写,指的是《Design Patterns: Elements of Reusable Object-Oriented Software》这本书的四位作者:

  • Erich Gamma
  • Richard Helm
  • Ralph Johnson
  • John Vlissides

他们被称为"Gang of Four(四人帮)",简称 GoF。这本书系统总结了 23 种经典设计模式,是面向对象设计的基石。

下面以C# 编程语言进行常见的GoF设计模式的编码样例、特点及应用场景!

二、常见的设计模式及应用

下面按工业或者实际开发用到较多进行排序并逐一介绍!

2.1单例模式(创建型)

定义:一个类在整个应用程序生命周期中只有一个实例并且只有一个全局访问点(全局访问点:只能通过一个固定的访问入口来获取对象,这个入口由单例类自己提供)。

特点:

  • 构造方法私有(private);
  • 类内部(private)维护一个静态实例引用字段;
  • 通过一个静态方法或属性来获取对应实例(对应私有字段),对应全局访问点;
  • 确保线程安全(多线程环境下只能产生一个实例);

应用场景:

  • 配置中心;
  • 日志类;
  • 全局缓存;
  • 数据库连接/HttpClient;

2.1.1静态构造函数

代码样例:

csharp 复制代码
/// <summary>
    /// 简单的单例模式类,天然线程安全
    /// </summary>
    public class Singleton
    {
        /// <summary>
        /// 私有的自身对象的字段
        /// </summary>
        private static  readonly Singleton singleton=new Singleton();
        /// <summary>
        /// 公开的自身类属性,全局访问点
        /// </summary>
        public static Singleton GetSingleton => singleton;
        /// <summary>
        /// 私有的实例方法
        /// </summary>
        private Singleton() { }
    }

2.1.2简单版本

csharp 复制代码
public class Singleton
{
    private static Singleton _instance;

    private Singleton() { }

    public static Singleton Instance
    {
        get
        {
            if (_instance == null)
                _instance = new Singleton();
            return _instance;
        }
    }
}

分析:基本使用,但是不加锁,线程不安全!

变样:可以增加lock锁,但是会获取对象时,有性能损耗!

2.1.3Lazy<T>版本

csharp 复制代码
public class Singleton
{
    private static readonly Lazy<Singleton> _instance =
        new Lazy<Singleton>(() => new Singleton());

    private Singleton() { }

    public static Singleton Instance => _instance.Value;
}

分析:延迟加载 + 线程安全 + 最简洁!

Lazy<T> 表示某个对象 直到第一次使用时才会真正创建。

Lazy:懒加载(Lazy Initialization), .NET 提供的一个泛型类,用来实现"按需创建对象"。

2.2简单工厂(创建型)

定义:通过一个工厂类来统一管理对象的创建(把创建对象的逻辑从使用者那里抽离出来,让工厂来决定创建哪一个具体产品)。

特点:

  • 抽象产品(接口/抽象类);
  • 具体产品(实现类,有抽象产品的规范和约定的行为方法);
  • 工厂类(负责创建对象);

应用场景:

  • 需要经常切换不同模式;
  • 客户端不想理解创建细节;

2.2.1基本样例

csharp 复制代码
/// <summary>
    /// 抽象产品
    /// </summary>
    public abstract class Product {
        public abstract void Use();
        public void Do() {
            Console.WriteLine("Do something!");
        }
    }
    /// <summary>
    /// 实际产品A
    /// </summary>
    public class ProductA :Product
    {
        public void UseA() { }
        public override void Use() { }
    }
    /// <summary>
    /// 实际产品B
    /// </summary>
    public class ProductB : Product
    {
        public override void Use() { }
    }
    public class ProductC : Product
    {
        public override void Use() { }
    }
    /// <summary>
    /// 工厂类
    /// </summary>
    public class FactoryMethod
    {
        public static Product Create(string type_) {
            Product dstProduct_ = null;
            switch (type_) {
                case "A":
                    dstProduct_ = new ProductA();
                    break;
                case "B":
                    dstProduct_ = new ProductB();
                    break;
                case "C":
                    dstProduct_ = new ProductC();
                    break;
                default:
                    throw new Exception();
            }
            return dstProduct_;
        }
    }

2.3抽象工厂(创建型)

定义:用于在不指定具体类的前提下,创建一族(Family)相关或互相依赖的对象(产品)。

特点:

  • 定义不同的产品接口,然后在不同产品上各自实现接口 ;
  • 定义抽象工厂接口,包含不同的产品接口 ;
  • 不同工厂生产不同产品族;

应用场景:

  • 操作系统相关 API 封装;
  • UI 库(Windows/Mac/Linux);

2.3.1基本样例

设计代码:

csharp 复制代码
 #region 抽象产品
    /// <summary>
    /// 抽象产品A
    /// </summary>
    public interface IButton
    {
        void Click();
    }
    /// <summary>
    /// 抽象产品B
    /// </summary>
    public interface ITextBox
    {
        void Display();
    }
    #endregion
    #region 具体实现的产品分类
    /// <summary>
    /// 第1类的A
    /// </summary>
    public class WindowsButton : IButton
    {
        public void Click() => Console.WriteLine("Windows Button clicked");
    }
    /// <summary>
    /// 第1类的B
    /// </summary>
    public class WindowsTextBox : ITextBox
    {
        public void Display() => Console.WriteLine("Windows TextBox displayed");
    }
    /// <summary>
    /// 第2类的A
    /// </summary>
    public class MacButton : IButton
    {
        public void Click() => Console.WriteLine("Mac Button clicked");
    }
    /// <summary>
    /// 第2类的B
    /// </summary>
    public class MacTextBox : ITextBox
    {
        public void Display() => Console.WriteLine("Mac TextBox displayed");
    }
    #endregion
    #region 抽象工厂实现
    /// <summary>
    /// 抽象工厂
    /// </summary>
    public interface IUIFactory
    {
        IButton CreateButton();
        ITextBox CreateTextBox();
    }
    /// <summary>
    /// 第一类的工厂
    /// </summary>
    public class WindowsUIFactory : IUIFactory
    {
        public IButton CreateButton() => new WindowsButton();
        public ITextBox CreateTextBox() => new WindowsTextBox();
    }
    /// <summary>
    /// 第二类的工厂
    /// </summary>
    public class MacUIFactory : IUIFactory
    {
        public IButton CreateButton() => new MacButton();
        public ITextBox CreateTextBox() => new MacTextBox();
    }
    #endregion

调用代码:

csharp 复制代码
IUIFactory factory = new WindowsUIFactory();  // 或 MacUIFactory
IButton button = factory.CreateButton();
ITextBox textBox = factory.CreateTextBox();
 button.Click();
 textBox.Display();

分析:客户端完全不依赖具体产品类。

2.4代理模式(结构型)

定义:让一个对象(代理对象)控制对另一个对象(真实对象)的访问。给真实对象"加一层壳",增强功能但不改变其核心逻辑。

特点:

  • 定义抽象接口;
  • 真实对象和代理对象实现对应接口;
  • 代理对象增加真实对象功能;

应用场景:

  • 权限校验;
  • 缓存结果,提高性能;
  • 延迟初始化(懒加载);
  • 远程访问(RMI、WebService 等);
  • 监控访问次数、日志记录;
  • 为对象创建前后添加 AOP 行为;

2.4.1基本样例

设计代码:

csharp 复制代码
// <summary>
    /// 抽象接口
    /// </summary>
    public interface ISubject
    {
        void DoWork();
    }
    /// <summary>
    /// 真实对象
    /// </summary>
    public class RealSubject : ISubject
    {
        public void DoWork()
        {
            Console.WriteLine("RealSubject: 正在执行核心业务逻辑...");
        }
    }
    /// <summary>
    /// 代理对象
    /// </summary>
    public class Proxy : ISubject
    {
        private RealSubject _realSubject;

        public Proxy()
        {
            _realSubject = new RealSubject();
        }

        public void DoWork()
        {
            Console.WriteLine("Proxy: 开始前置处理(例如日志记录)...");
            _realSubject.DoWork();
            Console.WriteLine("Proxy: 后置处理(例如监控、统计)...");
        }
    }

调用代码:

csharp 复制代码
ISubject subject = new Proxy();
subject.DoWork();

四、参考资料


以上文章仅做参考学习,如有不足,敬请批评指正!

相关推荐
ximu_polaris7 小时前
设计模式(C++)-行为型模式-状态模式
c++·设计模式·状态模式
ximu_polaris7 小时前
设计模式(C++)-行为型模式-迭代器模式
c++·设计模式·迭代器模式
weixin_5206498716 小时前
WinForm数据展示组件ListView
c#
程序设计实验室21 小时前
Spark.NET:一个试图把 Django / Rails 式开发体验带回 .NET 世界的全栈 Web 框架。
c#
huzhongqiang21 小时前
Python 单例模式的几种实现方式:朴素才是王道
设计模式
byoass1 天前
智巢AI知识库深度解析:企业文档管理从大海捞针到精准狙击的进化之路
开发语言·网络·人工智能·安全·c#·云计算
一只叫煤球的猫1 天前
ThreadForge 1.2.0 发布:让 Java 并发代码更好写,这次补齐了高阶编排、示例与观测能力
java·设计模式·设计
njsgcs1 天前
solidworks自动标注折弯4 无向图 c#
开发语言·c#·solidworks
我是唐青枫1 天前
C#.NET ThreadLocal 深入解析:线程独享数据、性能收益与实战边界
c#·.net