实现一个属性或实现一个子类
Posted
技术标签:
【中文标题】实现一个属性或实现一个子类【英文标题】:To implement a property or to implement a subclass 【发布时间】:2011-08-25 21:32:11 【问题描述】:我有一个名为List_Field
的类,顾名思义,它构建列表输入字段。这些列表输入字段允许用户为每个列表选择一个项目。
我希望能够构建允许用户在每个列表中选择多个项目的列表输入字段,所以我有以下两难选择:
我应该通过在现有的List_Field
属性中实现multiple_choice_allowed
属性来做到这一点,还是应该实现List_Field
类的Multiple_Choice_List_Field
子类?
面对这样的困境,我应该遵循什么工程原则?
【问题讨论】:
.NET 本身使用属性方法。 在 html 中,你得到了你的 【参考方案1】:看看SOLID principles。他们会在你的设计中帮助你。特别是,单一责任原则会告诉您不要将两个关注点混合在一个类中,而 Liskov 替换原则会告诉您不要创建违反超类契约的子类,就像您也提议的那样。
那么在您的情况下,解决方案是什么?您可以创建一个与选择类型无关的抽象基类,然后创建 2 个子类,一个用于单选,另一个用于多选。
【讨论】:
这是一个有趣的建议。是您通常避免扩展非抽象类,还是所讨论的类中有一些特定的东西使其成为抽象类方法的良好候选者? 我通常会尽量避免覆盖基类的具体行为。它使类层次结构更难理解。 +1 给 Jordão 以提及 SRP/SOLID 并链接到 Bob 叔叔 同时不遵循OCP(OCP开放封闭原则你应该能够扩展一个类的行为,而不需要修改它。)如果我错了,请纠正。【参考方案2】:取决于对象进化的存在/缺乏 - 如果您想要特殊情况,子类化或注入(DI)“选择”行为(策略)是好的。
但如果你还想让 Field_List 动态改变其行为,那么属性或变异方法是唯一可行的方法。
示例:具有不同“计划”的注册屏幕 - 基本版,您只能选择一项,而高级版,您可以随意选择。更改计划将在下拉和多个复选框之间切换,同时仍然具有相同的对象,包括其内容。
我会投票支持属性/变异方法。
【讨论】:
【参考方案3】:我个人会选择Multiple_Choice_List_Field
方式。我不认为有一个严格的标准或工程原则可以让你以一种方式而不是另一种方式去做。
这里更重要的是选择一种方式去做,并且在遇到这样的困境时遵循它。您应该始终如一,但走哪条路是您自己的选择。
我会选择子类,因为这样你就不必用额外的检查和要求来膨胀你的List_Field
类。当然还有其他考虑,比如如果你需要在运行时切换多选和单选,最好选择布尔属性(虽然子类也可以,但我觉得不自然)。
另一件事是对于List_Field
,您可能需要多个属性来处理多个选择,具体取决于您当前的实现。例如一个新的属性来返回一个选定项目的数组。
只需按照最适合您构建和维护(并最终扩展)的方式进行。
【讨论】:
-1 to Stormbreaker,这确实应该被贬低,但你没有这个心。没有“工程原理”?请参阅上面由 Jordão 提供的链接 是的,其中有很多,其中一半说的与另一半说的完全相反。 (我之前的评论应该是“但我没有勇气”而不是 U)。 @stormbreaker,您能否请我参考一个与 SRP、Liskov 等相矛盾的原则? (我不想在这里陷入燃烧的垃圾,但如果你能用一些证据来支持你的全面陈述,那就太好了)【参考方案4】:我是否应该通过实施来做到这一点 一个 multiple_choice_allowed 属性 到现有的 List_Field 属性中
如果你能做到这一点,我认为这是最好的解决方案,因为这样可以避免类扩散。 如果这样做会使 List_Field 类过于复杂,那么创建派生类可能会对代码的可维护性产生一些好处。
【讨论】:
事情就是这样——你怎么知道一个属性什么时候让一个类变得过于复杂? 这很主观。例如,如果您需要 List_Field 类中的大量 if 语句来处理不同的选择方法,并且在开发代码时它会增加以实现该目标,那么这可能不是正确的方法。【参考方案5】:就我个人而言,我不会说:而是使用一个接受 multiple_choice_allowed 的构造函数,然后有一个属性将 ListFields 公开为一个集合(当只允许一个元素时,只有一个元素,当允许多个元素时,所有元素)。将其设为只读(这意味着您应该在返回列表时复制它)。
【讨论】:
以上是关于实现一个属性或实现一个子类的主要内容,如果未能解决你的问题,请参考以下文章
实现一个名为Person的类和它的子类Employee, Manager是Employee的子类,设计一个接口Add用于涨工资,普通