【发布时间】:2017-12-03 01:58:46
【问题描述】:
.NET Framework 中的哪些类实现了装饰器、工厂等各种设计模式?
【问题讨论】:
-
MSDN 上框架小抄表中的设计模式:msdn.microsoft.com/en-us/magazine/cc188707.aspx 希望对您有所帮助!
标签: .net design-patterns
.NET Framework 中的哪些类实现了装饰器、工厂等各种设计模式?
【问题讨论】:
标签: .net design-patterns
嗯,您所要求的可能是一个非常广泛的列表,因为设计模式在 .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<out T> 和IObserver<in T> 接口来实现的,它们更直接地支持原始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 中的所有流都提供相同的基本功能,但每个流的功能不同。
.NET 框架中使用了许多其他设计模式。 .NET 的几乎每个方面,从语言到框架再到基本的运行时概念,都基于通用设计模式。 .NET 框架的重要部分(例如 ASP.NET)本身就是模式。以 ASP.NET MVC 框架为例,它是 MVC 的 Web 变体的实现,或 Model-View-Controller。 WPF 和 Silverlight UI 框架直接支持称为 MVVM 或 Model-View-ViewModel 的模式。 ASP.NET 管道本身就是一组模式,包括拦截过滤器、页面控制器、路由器等。最后,最常用的模式,composition,在 .NET 框架中被广泛使用,它可能是整个框架中最基本的模式之一。
【讨论】:
在我的头顶上:
DbProviderFactory 类)DbConnectionStringBuilder、UriBuilder...)StringComparer、Encoding、Color 等的预定义实例(静态属性)是原型模式的变体可能还有更多例子,但我现在能想到的就这些了……
【讨论】:
另外,NullObject
【讨论】:
ExpressionVisitor 类(Syste.Linq.Expression 命名空间)中的访问者模式。System.Web.Abstractions 中的 适配器模式 - 以更可单元测试的方式封装各种 Web 类(HttpRequest、HttpResponse) - 即 HttpResponseBase。Activator.CreateInstance - 创建指定对象的实例。IEnumerable 的所有实现。【讨论】:
在 .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"); 来强制执行字符串实习。
【讨论】:
原型 - 使用原型实例指定要创建的对象类型,并通过复制此原型创建新对象。
ICloneable 接口与方法 Clone() 是原型的经典示例。
【讨论】:
提供者模式 - 用于MembershipProvider、RoleProvider、ProfileProvider。
【讨论】: