Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oop 为什么HelperClass是反模式的_Oop_Design Patterns - Fatal编程技术网

Oop 为什么HelperClass是反模式的

Oop 为什么HelperClass是反模式的,oop,design-patterns,Oop,Design Patterns,最近的一个例子让我重新思考了整个helper类是反模式的 asawyer指出了该问题评论中的几个链接: 虽然这些链接详细介绍了HelperClass如何与众所周知的oop原则相冲突,但有些事情我仍然不清楚 例如“不要重复你自己”。您如何在不创建某种帮助程序的情况下实现这一点? 我认为您可以派生某种类型并为其提供一些特性。 但我认为这并不总是可行的 让我们看看下面的例子, 请记住,我尽量不使用任何更高级的语言功能或“特定语言”的东西。所以这可能是丑陋的嵌套,而不是最佳的 //Check if t

最近的一个例子让我重新思考了整个helper类是反模式的

asawyer指出了该问题评论中的几个链接:

虽然这些链接详细介绍了HelperClass如何与众所周知的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;
        }
    }
}
让我们创建一个名为StringHelper的坏助手类,代码会变短:

bool isAllWhiteSpace = StringHelper.IsAllWhiteSpace(input);
既然这不是我们唯一需要检查的时候,我想“不要重复你自己”已经填好了

如果没有助手,我们怎么做?考虑到这段代码没有绑定到单个类

我们是否需要继承字符串并将其称为BetterString

bool allWhiteSpace = better.IsAllWhiteSpace;
还是我们要创建一个类?检线器

StringChecker checker = new StringChecker();

bool allWhiteSpace = checker.IsAllwhiteSpace(input);
那么我们如何做到这一点呢

有些语言(例如C#)允许使用ExtensionMethods。他们也算助手吗?我倾向于选择那些而不是助手类

免责声明:下面的答案是基于我自己的经验,我没有指出是非

依我看,助手类既不好也不坏,这完全取决于您的业务/领域逻辑和软件体系结构。 原因如下: 假设我们需要实现你提出的空白的想法,所以首先我会问我自己。 我什么时候需要检查空格? 因此,设想以下场景:一个包含用户、帖子和评论的博客系统。因此,我将有三门课:

Class User{}
Class Post{}
Class Comment{}
每个类都有一些字符串类型的字段。无论如何,我需要验证这些字段,以便创建如下内容:

Class UserValidator{}
Class PostValidator{}
Class CommentValidator{}
我将把我的验证策略放在这三个类中。但是,等等前面提到的所有类都需要检查null或所有空格?嗯。。。。 最好的解决方案是将其放在树的更高位置,并将其放入名为Validator的父类中:

Class Validator{
   //some code
   bool function is_all_whitespaces(){}
}
因此,如果您需要函数
是_all_whitespaces(){}
是抽象的(类验证器也是抽象的),或者将其转换为接口,这将是另一个问题,这主要取决于您的思维方式。 回到本例中的要点,我的类(为了给出一个示例)如下所示:

Class UserValidator inherits Validator{}
Class PostValidator inherits Validator{}
Class CommentValidator inherits Validator{}
在这种情况下,我真的根本不需要助手。但假设您有一个名为
multi-d\u-array\u-group\u by\u-key的函数

您在不同的位置使用它,但是您不喜欢将它放在OOP结构化的地方,您可以将它放在一些
阵列帮助器中,但是这样您就比完全面向对象落后了一步。

帮助器类是不好的,因为设计良好的OO系统将清楚地理解每个类的职责。例如,
列表
负责管理项目的有序列表。一些刚接触OOD的人发现类具有处理其数据的方法,有时会问“为什么
List
没有
dispayOnGUI
方法(或类似的方法)?”。答案是,
List
没有责任关注GUI

如果你把一个类称为“助手”,它实际上并没有说明这个类应该做什么

一个典型的场景是,会有一个类,有人认为它变得太大,并将它分成两个较小的类,其中一个是助手。通常并不清楚什么方法应该放在helper中,什么方法应该保留在原始类中:helper的职责没有定义

除非你对OOD有经验,否则很难解释,但让我用一个类比来说明。顺便说一下,我觉得这个比喻非常有力:

假设您有一个庞大的团队,其中有不同职位的成员:例如,前端开发人员、后端开发人员、测试人员、分析师、项目经理、支持工程师、集成专家等(如您所愿)

你可以把每一个角色看作是一个类:它都有一定的责任,而履行这些责任的人很有希望拥有执行这些责任所必需的知识。这些角色将以类似于类交互的方式进行交互

现在想象一下,后端开发人员发现他们的工作太复杂了。如果只是吞吐量问题,您可以雇佣更多员工,但问题可能是任务需要太多领域的知识。它决定通过创建一个新角色来拆分后端开发人员角色,并可能雇佣新的人员来填补这个角色

如果新的工作描述是“后端开发人员助手”,会有多大帮助?不太。。。申请者可能会被随机分配一组任务,他们可能会对自己应该做什么感到困惑,他们的同事可能不理解自己应该做什么

更严重的是,助手的知识可能必须与最初的开发人员完全相同,因为我们没有真正缩小实际的责任范围

所以“助手”并没有真正说明新角色的职责是什么。相反,最好分离角色的数据库部分,例如,“后端开发人员”分为“后端开发人员”和“数据库层开发人员”

调用类a助手也有同样的问题,解决方案也是相同的。你应该多想想新班级的职责是什么。理想情况下,它不应该只是剃掉头发