【问题标题】:What design patterns are used throughout the .NET Framework?整个 .NET Framework 使用了哪些设计模式?
【发布时间】:2017-12-03 01:58:46
【问题描述】:

.NET Framework 中的哪些类实现了装饰器、工厂等各种设计模式?

【问题讨论】:

标签: .net design-patterns


【解决方案1】:

嗯,您所要求的可能是一个非常广泛的列表,因为设计模式在 .NET 平台上广泛使用。以下是一些我能想到的例子:

适配器

适配器模式是一种桥接系统和平台的通用机制,在 .NET 框架中以多种方式实现。 .NET 中最普遍的例子之一是运行时可调用包装器或 RCW。使用tlbimp.exe 程序生成的 RCW 提供了适配器,让 .NET 托管代码可以通过 .NET API 轻松调用旧版 COM 代码。

工厂方法

工厂方法模式可能是最著名的模式之一。它在整个 .NET 框架中非常普遍地实现,尤其是在原始时代,但在许多其他时代也是如此。框架中这种模式的一个很好的例子是 Convert 类,它提供了许多方法来从其他通用原语创建通用原语。

此外,这种模式的另一种普遍形式是在许多原始类型和基本类型中发现的 .Parse() 和 .TryParse() 方法。

迭代器

Iterator 模式是通过几个接口和一些语言结构实现的,例如 C# 中的 foreach 和 yeild 关键字。 IEnumerable 接口及其通用对应接口由 .NET 框架中的数十个集合实现,允许对各种数据集进行简单、动态的迭代:

IEnumerable<T>
IEnumerator<T>

foreach(var thing in someEnumerable)
{
   //
}

C# 中的yeild 关键字允许实现真正形式的迭代器,只有在需要迭代时才会产生通过循环处理迭代的成本:

IEnumerable<string> TokenizeMe(string complexString)
{
    string[] tokens = complexString.Split(' ');
    foreach (string token in toekens)
    {
        yield return token;
    }
}

建造者

Builder 模式在 .NET 框架中实现了几次。需要注意的是连接字符串构建器。连接字符串可能是一件很挑剔的事情,在运行时动态构建它们有时会很痛苦。 Connection String Builder 类理想地展示了构建器模式:

string connectionString = new SqlConnectionStringBuilder
{
    DataSource = "localhost",
    InitialCatalog = "MyDatabase",
    IntegratedSecurity = true,
    Pooling = false
}.ConnectionString;

整个 .NET 框架中的其他类,例如 UriBuilder,也实现了构建器模式。

观察者

observer 模式是一种常见的模式,它允许一个类观察另一个类的事件。从 .NET 4 开始,这种模式通过两种方式得到支持:通过语言集成的事件(紧密耦合的观察者),以及通过 IObservable/IObserver 接口(松散耦合的事件)。

经典语言events 使用委托 或强类型函数指针来跟踪事件 属性中的事件回调。事件被触发后,将依次执行每个跟踪的回调。像这样的事件在 .NET 框架中被广泛使用。

public class EventProvider
{
    public event EventHandler SomeEvent;

    protected virtual void OnSomeEvent(EventArgs args)
    {
        if (SomeEvent != null)
        {
            SomeEvent(this, args); // Trigger event
        }
    }
}

public class EventConsumer
{
    public EventConsumer(EventProvider provider)
    {
        provider.SomeEvent += someEventHandler; // Register as observer of event
    }

    private void someEventHandler(EventArgs args)
    {
        // handle event
    }
}

.NET 4 框架的新功能是松散耦合事件。这些是通过实现IObservable&lt;out T&gt;IObserver&lt;in T&gt; 接口来实现的,它们更直接地支持原始Observer 设计模式。虽然我所知道的任何 .NET 框架类型都没有直接实现,但该模式的核心基础架构是 .NET 4 不可或缺的一部分。

public class SomethingObservable: IObservable<SomethingObservable>
{
    private readonly List<IObserver<SomethingObservable>> m_observers;

    public IDisposable Subscribe(IObserver<SomethingObservable> observer)
    {
        if (!m_observers.Contains(observer))
        {
            m_observers.Add(observer);
        }
        var unsubscriber = new Unsubscriber(m_observers, observer)
        return unsubscriber;        
    }

    private class Unsubscriber: IDisposable
    {
        public Unsubscriber(IList<IObserver<SomethingObservable>> observers, IObserver<SomethingObservable> observer)
        {
            m_observers = observers;
            m_observer = observer;
        }

        private readonly IList<IObserver<SomethingObservable>>  m_observers;
        private readonly IObserver<SomethingObservable> m_observer;

        public void Dispose()
        {
            if (m_observer == null) return;
            if (m_observers.Contains(m_observer))
            {
                m_observers.Remove(m_observer);
            }
        }
    }
}

装饰器

decorator 模式是一种通过单一基本类型提供行为的替代表示或形式的方法。很多时候,需要一组通用的功能,但该功能的实际实现需要更改。 .NET 框架中的一个很好的例子是 Stream 类及其派生类。 .NET 中的所有流都提供相同的基本功能,但每个流的功能不同。

    • 内存流
    • 缓冲流
    • 文件流
      • IsolatedStorageFileStream
    • 管道流
      • AnonymousPipeClientStream
      • 匿名管道服务器流
      • NamedPipeClientStream
      • NamedPipeServerStream
    • 加密流
    • GZipStream

.NET 框架中使用了许多其他设计模式。 .NET 的几乎每个方面,从语言到框架再到基本的运行时概念,都基于通用设计模式。 .NET 框架的重要部分(例如 ASP.NET)本身就是模式。以 ASP.NET MVC 框架为例,它是 MVC 的 Web 变体的实现,或 Model-View-Controller。 WPF 和 Silverlight UI 框架直接支持称为 MVVM 或 Model-View-ViewModel 的模式。 ASP.NET 管道本身就是一组模式,包括拦截过滤器页面控制器路由器等。最后,最常用的模式,composition,在 .NET 框架中被广泛使用,它可能是整个框架中最基本的模式之一。

【讨论】:

  • 知道在哪里使用外观模式吗?
  • @AnilPurswani - zejuel 添加了一个 answer 谈论外观模式。
【解决方案2】:

在我的头顶上:

  • Abstract Factory 模式用于 ADO.NET 2.0 基础架构(DbProviderFactory 类)
  • 模板方法模式用于框架的许多部分(WinForms、WPF...)
  • Builder 模式也经常使用(DbConnectionStringBuilderUriBuilder...)
  • 我认为StringComparerEncodingColor 等的预定义实例(静态属性)是原型模式的变体
  • 使用 .NET 远程处理时,代理模式无处不在
  • 事件是观察者模式的变体
  • Iterator 模式用于集合中
  • Strategy 模式用于,例如,在密码学类中

可能还有更多例子,但我现在能想到的就这些了……

【讨论】:

    【解决方案3】:

    另外,NullObject

    • String.Empty;
    • EventArgs.Empty;

    【讨论】:

    • 最简洁的设计模式和精确的观察:)
    【解决方案4】:
    • ExpressionVisitor 类(Syste.Linq.Expression 命名空间)中的访问者模式
    • System.Web.Abstractions 中的 适配器模式 - 以更可单元测试的方式封装各种 Web 类(HttpRequestHttpResponse) - 即 HttpResponseBase
    • 工厂方法 - Activator.CreateInstance - 创建指定对象的实例。
    • 迭代器模式 - IEnumerable 的所有实现。

    【讨论】:

    • Facade 模式并不是为了提供抽象......它是多个子系统的单一入口点
    【解决方案5】:

    在 .Net 框架中实现的更多 GoF 设计模式:

    外观 - 子系​​统中一组接口的高级接口

    MessageBox (System.Windows.Forms) - 为某些 Windows 窗体接口提供可重用的高级接口,而不是编写大量代码来呈现一个对话框,您只需调用MessageBox.Show("Hello world");

    Steven John Metsker 在 Design Patterns in C# 中也提到了这一点:

    MessageBox 类是 FCL 中为数不多的外观示例之一。它具有生产价值、可配置性和可重用性。最重要的是,MessageBox 类通过提供一个易于显示对话框的简单界面来实现 FACADE 模式的意图。

    如果您想了解更多信息,请查看the source code for MessageBox

    享元 - 使用共享有效地支持大量细粒度对象。

    .Net 框架使用字符串实习来节省相同字符串的内存,这是享元模式的一种实现。 This video by Curtis Lassam 在解释字符串实习方面做得很好。

    您也可以通过调用String.Intern("Hello world"); 来强制执行字符串实习。

    【讨论】:

      【解决方案6】:

      原型 - 使用原型实例指定要创建的对象类型,并通过复制此原型创建新对象。

      ICloneable 接口与方法 Clone() 是原型的经典示例。

      【讨论】:

        【解决方案7】:

        提供者模式 - 用于MembershipProviderRoleProviderProfileProvider

        【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-02-26
        • 1970-01-01
        • 2012-09-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多