代码之家  ›  专栏  ›  技术社区  ›  Marek

“被动”物体被认为是一种好的设计实践吗?

  •  3
  • Marek  · 技术社区  · 15 年前

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

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

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

    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
        }
    }
    

    这种“被动”物体被认为是一种好的设计实践吗?

    这种课程有更好的名字吗?

    5 回复  |  直到 15 年前
        1
  •  2
  •   Scott Langham    15 年前

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

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

    我相信名字还有其他的想法。

        2
  •  1
  •   Thomas    15 年前

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

        3
  •  1
  •   user151323    15 年前

    我不会调用对通知做出反应并完全被动更新其状态的对象。

    另一种想法是,如果对象只是调整它们的状态以反映外部世界的变化,而不提供它们自己的大部分内容,那么您可以将它们的“功能”切片,并将其放入其他更活跃的“组件”中。这些对象可能没有足够的理由存在。

    但是,如果这个组织使您的代码结构更好、更清晰和更易于维护,那么就使用它,不要担心它。

        4
  •  1
  •   Jason Baker    15 年前

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

    关于这个名字,我认为这可能是 Mediator pattern .

        5
  •  0
  •   BostonLogan    15 年前

    从概念上讲,这似乎是战略模式的一种实现。尽管在这个特定的案例中,推理不同于策略模式,但它仍然可以生成可读性很强、粒度很好的代码。去争取它。

    更新:为了更清楚地了解我的意思,我认为两个(或更多)类是从 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
    }
    

    然后根据运行时状态动态地决定使用哪一个…你实施一个战略。 正如我所说,您的解决方案在概念上类似于策略:您选择应用程序的一些行为方面,这些方面可以很好地抽象为策略,并将策略的实现转移到单独的类中,这些类不了解应用程序的其余部分,并且您的应用程序对策略的本质也不太了解。即使你不使用它的多态性,相似性的战略是明确的。