【问题标题】:How many parameters is optimal for constructor? [closed]构造函数有多少参数是最优的? [关闭]
【发布时间】:2015-02-22 10:54:24
【问题描述】:

我有一个需要重构的 C# 项目。项目使用 WPF+MVVM Light 工具包。我找到了接收大约 50 个参数(工厂接口)的 MainViewModel(...) 构造函数。我想不是。我对吗?我很感兴趣,因为我想改进我的 OOP 思维。谢谢。

附:对不起我的语法。如果您发现错误,请检查我。

【问题讨论】:

  • 50 个参数太多了。关注Single responsibility principle,你根本不会有这个问题。顺便说一句,您的问题是主观的,因此不适合 stackoverflow。
  • 你想有人告诉你“哦,N个参数很好,但是N+1太多了”?我认为这是非常基于意见的。
  • @Andy Korneyev 这不仅仅是我或其他人的意见。我需要知道干净的 OOP 代码的“规则”。

标签: c# .net wpf oop mvvm-light


【解决方案1】:

您可能会考虑使用像 Unity 这样的依赖注入器。在 Unity 容器中注册您需要的所有服务、工厂和关联类,然后您的 ViewModel 构造函数只需要一个参数,即 Unity 容器。

构造函数的 50 个参数对我来说似乎很疯狂......

【讨论】:

  • 但这是否意味着他需要解析构造函数中的工厂(或在需要时),从而对观察者(查看构造函数签名的人)隐藏依赖关系?
  • 这就是服务定位器反模式。这些类永远不必知道 DI 容器。这里的问题是如何摆脱 50 个依赖项,而不是将它们硬编码为构造函数中的 DI 调用
  • 不看他的代码,我们根本不知道如何解决问题。就我们所知,这个 ViewModel 正在他的构造函数中获取东西并将它们传递给其他 ViewModel 构造函数。使用 DI 容器至少可以让您在修复混乱时拥有可管理的构造函数参数...
  • DI 容器是的。将容器本身传递给对象 - 不。这只是掩盖了问题并引入了另一个依赖项。这就是为什么服务定位器被认为是一种反模式。无论如何,DI 解决了一个不同的问题。 parameter object refactoring 解决了这个特殊问题(参数太多)
  • 问题在于将其称为 DI“容器”,这让人认为它是一个包含许多不同对象的盒子——实际上只能用作服务定位器。你需要的是一个注射器。使用自省来提供对象需求on-build.
【解决方案2】:

Clean Code: A Handbook of Agile Software Craftsmanship,第 40 页,声明...

函数的理想参数数量为零(niladic)。接下来是一个(单子),紧随其后的是两个(二元)。应尽可能避免使用三个参数(三元)。超过三个(多元)需要非常特殊的理由 - 无论如何都不应该使用。

将这本书视为软件设计指南,因此,在考虑您的代码结构时提供建议。

【讨论】:

    【解决方案3】:

    50 个工厂接口意味着您的 ViewModel 太大,并且试图同时做太多事情。您应该将其分解为单独的 ViewModel,这些 ViewModel 将作为属性显示在主视图模型上。

    WPF 允许组合,并且任何首先允许 ViewModel 的框架(即除 PRISM 之外的任何框架)都将从它遇到的 ViewModel 组合相应的视图。我不确定 MVVM Light,但对于 Caliburn.Micro,这几乎不是问题。

    如果 MVVM Light 不能自动执行此操作,则您必须将包含特定子模型视图的 WPF 控件绑定到主视图模型上的子模型属性。

    另一种选择是将多个工厂接口捆绑到参数对象中并将它们传递给构造函数,从而将参数数量从 50 个变为 4-5 个。这就是 Introduce Parameter Object 重构。 ReSharper 等一些工具为这种重构提供了自动化支持。

    如果将其与 DI 容器结合使用,参数对象可以通过注册各个接口自动初始化。

    最好的解决方案是将主模型分解为子模型

    【讨论】:

      猜你喜欢
      • 2020-04-10
      • 1970-01-01
      • 1970-01-01
      • 2014-01-19
      • 1970-01-01
      • 2020-01-23
      • 1970-01-01
      • 1970-01-01
      • 2013-08-26
      相关资源
      最近更新 更多