CSh*_*pie 7 oop design-patterns
最近的一个问题让我重新思考这整个辅助类是反模式的东西.
asawyer在评论中指出了一些关于这个问题的链接: Helper 类 是一种 反模式.
虽然这些链接详细说明了辅助类如何与众所周知的oop原则相冲突,但有些事情仍然不清楚.
例如"不要重复自己".如何在不创造某种帮助的情况下取得成功呢?我认为你可以派生出某种类型并为它提供一些功能.但我觉得这并不是一直很实用.
让我们看一下下面的例子,请记住我尽量不使用任何更高级的语言功能,也不使用"特定于语言"的东西.所以这可能是丑陋的嵌套而不是最佳......
//Check if the string is full of whitepsaces
bool allWhiteSpace = true;
if(input == null || input.Length == 0)
allWhiteSpace = false;
else
{
foreach(char c in input)
{
if( c != ' ')
{
allWhiteSpace = false;
break;
}
}
}
Run Code Online (Sandbox Code Playgroud)
让我们创建一个名为StringHelper的错误辅助类,代码变得更短:
bool isAllWhiteSpace = StringHelper.IsAllWhiteSpace(input);
Run Code Online (Sandbox Code Playgroud)
所以,因为这不是我们唯一需要检查的时间,我想这里是"不要重复自己".
我们如何在没有帮助的情况下取得成功?考虑到这段代码不受单个类的约束?
我们需要继承字符串并将其称为BetterString吗?
bool allWhiteSpace = better.IsAllWhiteSpace;
Run Code Online (Sandbox Code Playgroud)
还是我们创建一个类?StringChecker
StringChecker checker = new StringChecker();
bool allWhiteSpace = checker.IsAllwhiteSpace(input);
Run Code Online (Sandbox Code Playgroud)
那我们怎么做到这一点呢?
某些语言(例如C#)允许使用ExtensionMethods.他们算作助手吗?我倾向于喜欢那些超过辅助课程的人.
rgh*_*ome 10
辅助类很糟糕,因为设计良好的面向对象系统将清楚地了解每个类的职责。例如,aList负责管理项目的有序列表。有些人新OOD谁发现一个类有方法做的东西与它的数据有时会问:“为什么不List有一个dispayOnGUI方法(或类似这样的事情)?”。答案是List关注 GUI不是我们的责任。
如果你称一个类为“Helper”,它实际上并没有说明该类应该做什么。
一个典型的场景是,会有一些类,有人认为它变得太大,并将其分成两个较小的类,其中一个是助手。通常并不清楚哪些方法应该放在帮助器中以及哪些方法应该保留在原始类中:帮助器的职责没有定义。
除非您对 OOD 有经验,否则很难解释,但让我打个比方。顺便说一下,我觉得这个比喻非常有力:
想象一下,您有一个大型团队,其中有不同工作职位的成员:例如,前端开发人员、后端开发人员、测试人员、分析师、项目经理、支持工程师、集成专家等(如您所愿)。
您可以将每个角色视为一个类:它有一定的责任,而履行这些责任的人希望拥有执行这些责任的必要知识。这些角色将以类似于类交互的方式进行交互。
现在想象一下,后端开发人员发现他们的工作太复杂了。如果仅仅是吞吐量问题,您可以雇用更多人,但问题可能在于该任务需要跨越太多领域的太多知识。决定通过创建一个新角色来拆分后端开发人员角色,并可能聘请新人来填补它。
如果新的职位描述是“后端开发助手”,会有多大帮助?不太... 申请者很可能会被分配一组杂乱无章的任务,他们可能会对他们应该做什么感到困惑,他们的同事可能不明白他们应该做什么。
更严重的是,助手的知识可能必须与原始开发人员完全相同,因为我们没有真正缩小实际职责范围。
因此,“帮助者”在定义新角色的职责方面并没有真正说什么。相反,最好将其拆分,例如角色的数据库部分,因此将“后端开发人员”拆分为“后端开发人员”和“数据库层开发人员”。
将类称为助手具有相同的问题,解决方案是相同的解决方案。您应该更多地考虑新类的职责应该是什么。理想情况下,它不应该只是削减一些方法,还应该带走一些它负责管理的数据,从而创建一个比原始大类更易于理解的解决方案,而不是简单地放置同样复杂的逻辑在两个不同的地方。
我发现在某些情况下,助手类设计得很好,但它所缺乏的只是一个好名字。在这种情况下,将其称为“Builder”或“Formatter”或“Context”而不是“Helper”会立即使解决方案更容易理解。
免责声明:以下答案是基于我自己的经验而我没有说明是非.
恕我直言,帮助程序既不好也不坏,这一切都取决于您的业务/域逻辑和您的软件架构.这就是为什么:让我们说我们需要实现你提出的白色空间的概念,所以首先我会问自己.我什么时候需要检查白色空格?因此,想象一下以下场景:一个包含用户,帖子,评论的博客系统.因此,我将有三个类:
Class User{}
Class Post{}
Class Comment{}
Run Code Online (Sandbox Code Playgroud)
每个类都有一些字符串类型的字段.无论如何,我需要验证这些字段,所以我会创建类似的东西:
Class UserValidator{}
Class PostValidator{}
Class CommentValidator{}
Run Code Online (Sandbox Code Playgroud)
我会将验证政策放在这三个类中.但等待!所有上述类都需要检查null或所有空格?嗯....最好的解决方案是在树中把它放得更高并把它放在一个名为Validator的父类中:
Class Validator{
//some code
bool function is_all_whitespaces(){}
}
Run Code Online (Sandbox Code Playgroud)
所以,如果你需要这个函数is_all_whitespaces(){}是抽象的(类验证器也是抽象的),或者把它变成一个接口,这将是另一个问题,它主要取决于你的思维方式.回到这一点,我会让我的课程(为了给出一个例子)看起来像:
Class UserValidator inherits Validator{}
Class PostValidator inherits Validator{}
Class CommentValidator inherits Validator{}
Run Code Online (Sandbox Code Playgroud)
在这种情况下,我真的根本不需要助手.但是让我们说你有一个被调用的函数multiD_array_group_by_key
,你在不同的位置使用它,但你不喜欢在一些OOP结构化的地方,你可以拥有它,ArrayHelper但是你是完全面向对象的一步之后.