【问题标题】:Are "passive" objects considered a good design practice?“被动”对象被认为是一种好的设计实践吗?
【发布时间】:2010-12-16 05:41:10
【问题描述】:

我发现自己经常创建一个没有公共方法且自包含的对象。它通常在其私有方法中处理传递给其构造函数的参数事件,并且不会引发任何事件或公开任何公共方法。

我称这种类型的对象为“被动”对象——没有定义任何公共方法的对象。所有交互都发生在它们内部的私有方法和构造函数中传递的参数事件中。

通常它是一些实用程序类,例如确保两个表单粘在一起的类:

public class StickyForm : IDisposable
{
    private readonly Form form;
    private readonly Form parentForm;

    public StickyForm(Form form, Form parentForm)
    {
        this.form = form;
        this.form.StartPosition = FormStartPosition.Manual;
        this.parentForm = parentForm;

        this.parentForm.LocationChanged += new EventHandler(parent_LocationChanged);
        this.parentForm.SizeChanged += new EventHandler(parent_SizeChanged);

        SetLocation();
    }

    void parent_SizeChanged(object sender, EventArgs e)
    {
        SetLocation();
    }

    void parent_LocationChanged(object sender, EventArgs e)
    {
        SetLocation();
    }

    private void SetLocation()
    {
        //compute location of form based on parent form 
    }

    public void Dispose()
    {
        this.parentForm.SizeChanged -= parent_SizeChanged;
        this.parentForm.LocationChanged -= parent_LocationChanged;
    }
}

但有时它也是某种控制器,提供两个视图之间的交互:

public class BrowseController
{
    private IBrowserView view;
    private IFolderBrowser folderBrowser;

    public BrowseController(IFolderBrowser folderBrowser, IBrowserView view)
    {
        this.view = view;
        this.folderBrowser = folderBrowser;

        this.folderBrowser.NodeOpened += folderBrowser_NodeOpened;
    }

    private void folderBrowser_NodeOpened(object sender, Core.Util.TEventArgs<IPictureList> e)
    {
        this.Browse(e.Value);
    }

    public void Browse(IPictureList content)
    {
        //stripped some code
        AddItemsToView(content);
    }

    private void AddItemsToView(IPictureList browser)
    {
        //call methods on view
    }
}

这样的“被动”对象是否被认为是一种好的设计实践?

这种类有更好的名字吗?

【问题讨论】:

    标签: model-view-controller oop architecture


    【解决方案1】:

    对我来说似乎是很好的设计。我不确定被动这个名字。这些课程看起来确实很活跃。他们对事件做出反应并做事。如果你必须调用它的方法来让它做一些事情,我认为一个类会更被动,但通常它不会做任何事情,除非被戳。

    “控制器”这个名字怎么样。 “控制器”是 UI 中用于导致视图和数据之间交互的类的更常用名称,它们通常不需要公共方法。

    我敢肯定还有其他关于名称的想法。

    【讨论】:

      【解决方案2】:

      我看不出有什么问题。如果它产生干净、可读的代码,那就去吧!

      【讨论】:

        【解决方案3】:

        我不会将响应通知并更新其状态的对象称为完全被动的。

        另一种想法,如果对象只是简单地调整它们的状态以反映外部世界的变化而不提供它们自己的太多东西,你可以将它们的“功能”分割并放入其他更活跃的“组件”中。这些对象可能没有足够的理由存在。

        如果这个组织让你的代码结构更好、更清晰、更易于维护,那么请使用它,不要担心。

        【讨论】:

          【解决方案4】:

          我认为这个设计需要满足一个重要的标准:你能测试它吗?您的设计似乎是可测试的,但您可能需要小心,因为我可以看到这会导致一些相当不可测试的代码。

          关于名字,我想这可能是Mediator pattern的一个例子。

          【讨论】:

            【解决方案5】:

            从概念上讲,这似乎是一种策略模式的实现。尽管在这种特殊情况下,推理与策略模式不同,但它仍然会产生非常易读且粒度很好的代码。去吧。

            更新:为了更清楚地说明我的意思,请考虑从StickyForm 派生的两个(或更多)类

            public class VeryStickyForm : StickyForm
            {
            //some implementation here
            //but interface is completely inherited from StickyForm
            }
            public class SomewhatStickyForm : StickyForm
            {
            //some implementation here
            //but interface is completely inherited from StickyForm
            }
            

            然后您根据运行时状态决定动态使用哪一个……您实施一种策略。 正如我所说,您的解决方案在概念上类似于策略:您选择可以很好地抽象为策略的应用程序的某些行为方面,并将策略的实现移动到单独的类中,该类不知道应用程序的其余部分,并且您的应用程序对政策的内容了解不多。即使您不以多态方式使用它,它与策略的相似之处也很明显。

            【讨论】:

            • 对不起,我在这种方法中看不到任何策略模式的迹象。你能详细说明一下吗?
            • 这绝对不是一个策略—— 1. 只有一种形式的粘性是可能的 2. 算法在运行时不切换。鉴于您的方法,我们可以将您可以(可能)子类化的所有内容称为策略 :)
            猜你喜欢
            • 2010-10-07
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-10-29
            • 1970-01-01
            • 2021-05-04
            • 2012-08-29
            • 1970-01-01
            相关资源
            最近更新 更多