重构:嵌套类还是单独的类?
我目前正在对我们的一些框架类进行一些重构(+添加新功能)。 情况是我们有一个(类似上帝的)类,它执行一堆我们想要拆分的逻辑。 该类表示类似财务代码验证规则的内容。 所以它会验证人的姓名、出生日期等。
我要做的是将其分成单个规则,基本上是一个根据财政代码验证人的名字的规则,另一个用于出生日期的规则,等等在。 对于最终的程序员来说,它看起来几乎是一样的。 他不会调用 FiscalCode 规则的庞大构造函数,而是执行类似 FiscalCode.GetRules(...)
的操作并在此处传递参数。 然后,GetRules(...)
将在内部构造单个规则并将它们作为数组传回。 这对我们来说是完全正确的。
关于你的背景就讲这么多。 现在我的问题如下。 FiscalCode 类(这是我们当前强大的神类)具有许多实用方法,我将要创建的更多单个“规则类”将需要这些方法。 我所知道的是,我仍然需要 FiscalCode 类来执行 GetRules(...)
事情(这对于程序员来说以某种方式保持不变,而不是他们必须完全执行新事物)。
我想到了两个选项:
- 创建我的新规则类并访问 FiscalCode 类的公共静态实用程序方法
- 创建我的新规则类作为 FiscalCode 类的内部嵌套类 我已经访问了实用程序方法(因此不需要暴露我的实用方法)
我已经有一个最喜欢的,但我想先听听你们中的一些人的意见。
谢谢
I'm currently doing some refactoring (+ adding new features) to some of our framework classes. The situation is that we have a single (god-like) class which does a bunch of logic we'd like to split up. The class represents something like a validation rule for fiscal codes. So it does validation of the names of the person, birthdate etc..
What I am going to do is to split it up in single rules, basically a rule which validates the person's firstname against the fiscal code, another one for the birthdate and so on. For the programmer at the end it looks nearly the same. Instead of invoking the huge constructor of the FiscalCode rule, he'll do something like FiscalCode.GetRules(...)
and pass the parameters here. The GetRules(...)
will then internally construct the single rules and pass them back as an array. That's perfectly fine and correct for us.
So much for your background. Now my question is the following. The FiscalCode class (which is our current mighty god-class) has a lot of utility methods which will be needed by more of the single "rule classes" I'm going to create. What I know is that I will somehow still need the FiscalCode class, for doing the GetRules(...)
thing (this is to remain constant somehow for the programmers, not that they have to do a completely new thing).
I have two options which come to my mind:
- Create my new rule classes and access the public static utility methods of the FiscalCode class
- Create my new rule classes as inner nested classes of the FiscalCode class s.t. I have already access the utility methods (and therefore no need for exposing my utility methods)
I have already a favorite, but I'd like to hear the opinion of some of you first.
Thx
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
这些实用程序方法对 FiscalCode 类或规则类有什么依赖性? 他们有保存状态吗?
如果没有任何依赖项,我建议将这些实用程序方法移至单独的类,并让 FiscalCode 类或规则类根据需要调用这些方法。
对于您提供的选项,1) 和 2) 之间的唯一区别是规则类对于不使用它们的类是否可见。 我认为这并不是一个真正重要的目标。 我以前在做c++的时候一直担心这个……那是浪费时间。
What dependencies do these utility methods have on the FiscalCode class or the rule classes? Is there state kept by them?
If there aren't any dependencies I'd suggest moving those utility methods to a seperate class, and have the FiscalCode class or rule class call into those methods as appropriate.
For the options you give, the only difference between 1) and 2) is whether the rule classes are visible to classes that don't use them. I don't think thats really an important objective. I used to worry about that all the time when I did c++... it was a waste of time.
当您的方法成为“实用方法”时,您需要将它们设为静态和公共,但可能您需要将 FiscalCode 重命名为 FiscalCodeUtil。 那么它包含什么样的方法就一目了然了。
As your methods became 'utility methods' you need to make them static and public, but probably you need to rename your FiscalCode to FiscalCodeUtil. So it will be obvious what kind of methods it contains.
我还建议查看规范模式,它为如何解决这个问题提供了一些指导问题类型。 这篇文章还提供了一些 C# 示例。
建议的规范模式将引导您选择选项#1。
I would also suggest a review of the Specification Pattern, which gives some direction on how to approach this type of problem. This post also gives some examples in C#.
The suggested Specification Pattern would steer you towards your option #1.
我会这样处理(我不太擅长 OOP,所以要持保留态度):
规则类(嵌套在 FiscalCode 中)实现一个 IRule 接口,公开规则方法(如 Validate()),具有任何返回类型使你的船漂浮)。 税控码
有一个 AddRule() 方法,它管理规则的内部集合并返回对 self 的引用,以便允许方法链接:
此外,FiscalCode 有一个 Validate() 方法,它迭代每个规则的 Validate() 并管理错误。
在我看来,这使用起来非常方便,并且仍然允许嵌套规则类访问 FiscalCode 的实用方法。
I would go with it like this (I'm not that good at OOP so take it with a grain of salt):
Rule classes (nested in FiscalCode) implement an IRule interface exposing rule methods (like Validate(), with whatever return type floats your boat). FiscalCode
has an AddRule() method which manages an internal collection of rules and returns a reference to self in order to permit method chaining:
Also, FiscalCode has a Validate() method which iterates through each rule's Validate() and manages errors.
IMO this is quite handy to use and still permits to nested rule classes access FiscalCode's utility methods.
如果该类不会在
FiscalCode
类之外使用,则将其嵌套。 重要的是从FiscalCode
中提取这个新类的职责; 那么它驻留在哪里就变成了一个简单的选择问题。 当新类获得更多依赖时,您可以将其设为外部类。If the class will not be used outside the
FiscalCode
class, then make it nested. The important thing is to pull the responsibility of this new class out ofFiscalCode
; where it resides then becomes a mere question of choice. When the new class gets more dependents, you could make it an outer class.在我看来,您应该选择第一个选项,因为这样您就可以将新创建的类公开给外界,并且可以编写可在其他地方重用的代码。 如果您选择第二个选项,您将创建非常专业的类。 您的外部代码甚至可能不知道它的存在,但这可能有利于封装。 尽管如此,在某些时候,您可能会决定使用较大类范围之外的专门规则,对于这种情况,您最好选择第一个选项。 你的选择是什么?
IMO you should go for the first option because that way, you can expose the newly created classes to outside world, and can write code that is reusable elsewhere as well. If you go with the second option, you are creating very specialized classes. Your outside code may not even know of its existence, but that might be good for encasulation. Still, at some point you may decide to use the specialized rules outside the scope of your larger class, and for that scenario, you are better served with the first option. What is your pick though?