7

目前我正在阅读 head first 设计模式,虽然这本书很棒,但我也想看看这些设计模式是如何在现实世界中实际使用的。

如果你知道设计模式使用的一个很好的例子(最好是在 OSS 程序中,这样我们可以看看 :) 那么请在下面列出。

4

10 回答 10

3

对于观察者模式,对我来说,一个啊哈时刻是意识到它与事件的密切相关。考虑一个需要在两个窗体之间实现松散通信的 Windows 程序。这可以通过观察者模式轻松实现。

下面的代码显示了 Form2 如何触发事件以及注册为观察者的任何其他类如何获取其数据。

请参阅此链接以获取出色的模式资源:http: //sourcemaking.com/design-patterns-and-tips

Form1的代码:

namespace PublishSubscribe
{
    public partial class Form1 : Form
    {
        Form2 f2 = new Form2();

        public Form1()
        {
            InitializeComponent();

            f2.PublishData += new PublishDataEventHander( DataReceived );
            f2.Show();
        }

        private void DataReceived( object sender, Form2EventArgs e )
        {
            MessageBox.Show( e.OtherData );            
        }
    }
}

Form2的代码

namespace PublishSubscribe
{

    public delegate void PublishDataEventHander( object sender, Form2EventArgs e );

    public partial class Form2 : Form
    {
        public event PublishDataEventHander PublishData;

        public Form2()
        {
            InitializeComponent();
        }

        private void button1_Click( object sender, EventArgs e )
        {
            PublishData( this, new Form2EventArgs( "data from form2" ) );    
        }
    }

    public class Form2EventArgs : System.EventArgs
    {
        public string OtherData;

        public Form2EventArgs( string OtherData )        
        {
            this.OtherData = OtherData;
        }
    }
}
于 2008-08-30T17:17:25.913 回答
3

我使用被动视图(Model View Presenter模式的一种风格)和任何 Web 表单(如开发 (.NET))来提高可测试性/可维护性/等

例如,您的代码隐藏文件可能看起来像这样

Partial Public Class _Default
    Inherits System.Web.UI.Page
    Implements IProductView

    Private presenter As ProductPresenter

    Protected Overrides Sub OnInit(ByVal e As System.EventArgs)
        MyBase.OnInit(e)
        presenter = New ProductPresenter(Me)
    End Sub

    Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
        presenter.OnViewLoad()
    End Sub

    Private ReadOnly Property PageIsPostBack() As Boolean Implements IProductView.PageIsPostBack
        Get
            Return Page.IsPostBack
        End Get
    End Property

    Public Property Products() As System.Collections.Generic.List(Of Product) Implements Library.IProductView.Products
        Get
            Return DirectCast(gridProducts.DataSource(), List(Of Product))
        End Get
        Set(ByVal value As System.Collections.Generic.List(Of Product))
            gridProducts.DataSource = value
            gridProducts.DataBind()
        End Set
    End Property
End Class

后面的代码充当了一个非常薄的视图,逻辑为零。而是将此逻辑推入可以进行单元测试的演示者类中。

Public Class ProductPresenter
    Private mView As IProductView
    Private mProductService As IProductService

    Public Sub New(ByVal View As IProductView)
        Me.New(View, New ProductService())
    End Sub

    Public Sub New(ByVal View As IProductView, ByVal ProductService As IProductService)
        mView = View
        mProductService = ProductService
    End Sub

    Public Sub OnViewLoad()
        If mView.PageIsPostBack = False Then
            PopulateProductsList()
        End If
    End Sub

    Public Sub PopulateProductsList()
        Try
            Dim ProductList As List(Of Product) = mProductService.GetProducts()
            mView.Products = ProductList
        Catch ex As Exception
            Throw ex
        End Try
    End Sub
End Class
于 2008-08-30T17:43:12.090 回答
3

使用 code.google.com

例如,“工厂”的搜索结果将为您提供很多实现工厂模式的案例。

于 2008-08-30T19:31:46.650 回答
3

责任链模式是在处理 DOM 事件时实现的。例如,(并稍微简化)当一个元素被单击时,该元素首先获得处理事件的机会,然后每个祖先都在 tern 中,直到到达顶级文档或其中一个显式停止事件“冒泡”任何进一步。

于 2008-08-30T20:01:58.497 回答
1

C#、Java 和 Python 都有迭代器模式的标准实现。在 C# 和 Python 中,这已集成到语言中,因此您可以只使用 yield return 语句。

于 2008-08-31T00:55:12.240 回答
1

模板模式常用于 dotnet 事件的实现,用于设置前置条件和响应后置条件。退化的情况是

void FireMyEvent(object sender, EventArgs e) 
{
  if (_myevent != null) _myEvent(sender, e);
}

在其中检查前提条件。在这种情况下,前提是只有在至少绑定了一个时才能调用处理程序。(请不要告诉我我应该异步调用处理程序。我知道。我在说明模板模式,而不是异步编程技术。)

更复杂的前提条件可能涉及检查控制事件触发的属性。

模板模式也常用于实现钩子,例如

public virtual void BeforeOpenFile(string filepath)
{
  //stub
}
public virtual void AfterOpenFile(string filepath)
{
  //stub
}
public sealed void OpenFile(string filepath) 
{
  BeforeOpenFile(filepath); //do user customisable pre-open bits
  //do standard bits here
  AfterOpenFile(filepath); //do user customisable post-open bits
}
于 2008-09-22T05:53:22.640 回答
1

如果您熟悉 Python,请查看 Twisted 框架。 http://twistedmatrix.com/trac/

于 2008-09-22T12:14:28.183 回答
1

正如Head First Design Patterns中所指出的,也许一个很好的例子是实现观察者模式的JAVA Swing API。更具体地说,JButton(或超类 AbstractButton)是 Observable 类,并提供添加和删除“观察者”或“侦听器”的方法,因为它们在 Swing 中被调用。

于 2009-09-13T20:59:30.487 回答
0

Composite 在 UI 中被广泛使用。组件可以是叶组件(例如按钮和标签)或复合组件(例如面板),它们可以包含其他叶组件或复合组件。从客户端的角度来看,所有组件都被一视同仁,大大简化了客户端代码。

于 2008-09-07T09:27:37.067 回答
0

命令模式在您有撤消功能的任何地方都使用。

于 2008-09-22T12:06:41.523 回答