实现属性或实现子类
我有一个名为 List_Field
的类,顾名思义,它构建列表输入字段。这些列表输入字段允许用户为每个列表选择单个项目。
我希望能够构建允许用户在每个列表中选择多个项目的列表输入字段,因此我遇到了以下困境:
我是否应该通过在现有 中实现
属性,或者我应该实现 multiple_choice_allowed
属性来实现这一点List_FieldList_Field
类的 Multiple_Choice_List_Field
子类?
当遇到这样的困境时,我应该遵循什么工程原则?
I've got a class called List_Field
that, as the name suggests, builds list input fields. These list input fields allow users to select a single item per list.
I want to be able to build list input fields that would allow users to select multiple items per list, so I have the following dilemma:
Should I do that through implementing a multiple_choice_allowed
property into the existing List_Field
property, or should I implement a Multiple_Choice_List_Field
subclass of the List_Field
class?
What's the engineering principle that I should follow when confronted with dilemmas like this one?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
查看SOLID 原则。他们会帮助您进行设计。特别是,单一责任原则将告诉您不要将两个关注点混合在一个类中,而里氏替换原则将告诉您不要创建违反超类契约的子类,就像您所提议的那样。
那么您的情况的解决方案是什么?您可以创建一个与选择类型无关的抽象基类,然后创建 2 个子类,一个用于单项选择,另一个用于多项选择。
Take a look at the SOLID principles. They'll help you in your designs. In particular, the single responsibility principle will tell you not to mix the two concerns in one class, and the Liskov substitution principle will tell you not to create subclasses that break the contract of superclasses, like what you're also proposing.
So what would be the solution in your case? You could create an abstract base class that would be agnostic to the type of selection and then create 2 subclasses, one for single selection and another for multiple selection.
取决于对象演化的存在/缺乏 - 如果您想要特殊情况,子类化或注入(DI)“选择”行为(策略)是好的。
但如果您还希望允许 Field_List 动态更改其行为,那么属性或变异方法是唯一的方法。
示例:具有不同“计划”的注册屏幕 - 基本版(您只能选择一项)和高级版(您可以选择任意数量)。计划的更改将在下拉列表和多个复选框之间切换,同时仍然具有完全相同的对象(包括其内容)。
我会投票支持 property/mutate 方法。
Depends on presence/lack of object evolution - if you want special case, sub-classing or injecting (DI) "select" behaviour (strategy) is good.
But if you also want to allow Field_List to change its behaviour dynamically, then property or mutating method is the only way to go.
Example: Sign-up screen with different "plans" - basic, where you can only select one thing and premium, where you can select as much as you want. Change of plan will switch between drop-down and multiple checkboxes, while still having the very same object including its contents.
I would vote for property/mutate method.
就我个人而言,我会选择
Multiple_Choice_List_Field
方式。我认为没有严格的标准或工程原理可以让你以一种方式而不是另一种方式来做。这里更重要的是选择一种方法去做,并在遇到这种困境时遵循它。你应该保持一致,但走哪条路是你自己的选择。
我会选择子类,因为这样您就不必通过额外的检查和要求来膨胀您的
List_Field
类。当然还有其他考虑因素,例如如果您需要在运行时切换多选和单选,那么最好选择布尔属性(虽然子类也可以,但对我来说感觉不自然)。另一件事是,对于
List_Field
,您可能需要多个属性来处理多个选择,具体取决于您当前的实现。例如,一个新属性可返回所选项目的数组。只需按照您最舒服的方式进行构建和维护(并最终扩展)即可。
Personally I would go for the
Multiple_Choice_List_Field
way. I don't think there is a strict standard or an engineering principle that would make you to do it one way instead of another.The more important thing here is to choose one way to do it and follow it whenever you encounter such a dilemma. You should be consistent, but which way you go is your own choice.
I would choose the subclass because this way you won't have to bloat your
List_Field
class with additional checks and requirements. Of course there are other considerations such as if you need to switch the multiple choice and single choice at runtime it would be better to go for the boolean property (although subclass will work too, but doesn't feel natural to me).The other thing is for
List_Field
you might need more than a single property to handle multiple choices, depending on your current implementation. For example a new property to return an array of the selected items.Just do it the way it's most comfortable for you to build and maintain (and eventually extend).
如果你能做到这一点,我认为这是最好的解决方案,因为这样可以避免类扩散。
如果这样做会使 List_Field 类变得过于复杂,那么创建派生类可能会对代码的可维护性带来一些好处。
If you can do that, I think it's the best solution because this way you avoid class proliferation.
If in doing that you are complicating too much your List_Field class, maybe create a derived class can have some benefits regarding the maintainability of your code.
就我个人而言,我不会说:而是使用一个接受 multiple_choice_allowed 的构造函数,然后有一个属性将 ListFields 公开为一个集合(当只允许一个元素时,只有一个元素,当允许多个元素时,所有元素)。使其只读(这意味着每当您返回列表时都应该复制它)。
Personally, I would say neither: instead use a constructor that takes multiple_choice_allowed, and then have a property exposing ListFields as a collection (with just one element when only one is allowed, all of them when more than one is allowed). Make it readonly (which means that you should copy it whenever you return the list).