问题 实用课程..好还是坏?
我一直在阅读通过在代码中使用静态类/单例来创建依赖项,是不好的形式,并产生问题,即。紧耦合和单元测试。
我有一种情况,我有一组url解析方法没有与它们相关的状态,并只使用方法的输入参数执行操作。我相信你熟悉这种方法。
在过去,我会继续创建一个类并添加这些方法,并直接从我的代码中调用它们,例如。
UrlParser.ParseUrl(url);
但是等一下,就是将依赖引入另一个类。我不确定这些“实用”类是否是坏的,因为它们是无状态的,这最小化了所述静态类和单例的一些问题。有人可以澄清一下吗?
我应该将方法移动到调用类,即只有调用类将使用该方法。这可能违反了“单一责任原则”。
11520
2017-11-04 01:48
起源
答案:
从理论设计的角度来看,我觉得在可能的情况下,实用工具类是可以避免的。它们基本上与静态类没什么不同(虽然稍微好一点,因为它们没有状态)。
然而,从实际的角度来看,我确实创造了这些,并鼓励他们使用 在适当的时候。试图避免实用程序类通常很麻烦,并导致代码维护较少。但是,我确实鼓励我的开发人员在可能的情况下在公共API中避免这些。
例如,在您的情况下,我觉得UrlParser.ParseUrl(...)可能更好地作为一个类处理。看着 的System.Uri 在BCL中 - 这为统一资源标识符提供了一个干净,易于使用的界面,该界面运行良好,并保持实际状态。我更喜欢这种方法来处理一个对字符串起作用的实用程序方法,并强制用户传递一个字符串,记得验证它,等等。
7
2017-11-04 01:55
实用程序类是可以的.....只要它们不违反设计原则。在使用核心框架类时,请愉快地使用它们。
这些类应该有良好的命名和逻辑。实际上,它们不是“实用”,而是本土课程不提供的新兴框架的一部分。
使用诸如扩展方法之类的东西也很有用,可以将功能与“正确”类对齐。但是,它们可能会引起一些混淆,因为扩展程序没有与它们通常扩展的类一起打包,这不是理想的,但仍然可以非常有用并产生更清晰的代码。
2
2017-11-04 01:53
您总是可以创建一个接口,并使用依赖注入与实现该接口而不是静态类的类的实例。
问题变成了,真的值得努力吗?在某些系统中,答案是肯定的,但在其他系统中,特别是较小的答案,答案可能是否定的。
2
2017-11-04 01:54
我同意这里的一些其他回应,它是经典的单例,它维护一个有状态对象的单个实例,这个实例是要避免的,而不一定是没有状态恶意的实用类。我也同意里德的意见,如果可能的话,将这些实用程序方法放在一个有意义的类中,并且逻辑上怀疑这样的方法会存在。我想补充一点,通常这些静态实用程序方法可能是扩展方法的良好候选者。
1
2017-11-04 01:59
我真的,真的试图避开它们,但是我们在开玩笑......它们会蔓延到每个系统中。然而,在给出的示例中,我将使用URL对象,然后该URL对象将公开URL的各种属性(协议,域,路径和查询字符串参数)。 几乎 每次我想创建静态实用程序类时,我都可以通过创建执行此类工作的对象来获得更多价值。
以类似的方式,我创建了许多自定义控件,这些控件已经内置了百分比,货币,电话号码等内容的验证。在这之前,我有一个Parser实用程序类,它具有所有这些规则,但它使得在已经知道基本规则的页面上删除控件变得更加清晰(因此只需要 商业逻辑 要添加的验证)。
我仍然保留解析器实用程序类和这些控件 隐藏 那个静态类,但是广泛使用它(将所有解析保存在一个容易找到的地方)。在这方面,我认为使用实用程序类是可以接受的,因为它允许我应用“不要重复自己”,而我通过控件或使用实用程序的其他对象获得实例类的好处。
1
2017-11-04 01:59
这实际上取决于背景以及我们如何使用它。
实用类本身也不错。但是,如果我们以糟糕的方式使用它会变得很糟糕。每个设计模式(特别是Singleton模式)都可以很容易地变成反模式,对于Utility类也是如此。
在软件设计中,我们需要在灵活性和简单性之间取得平衡。如果我们要创建一个只负责字符串操作的StringUtils:
- 它违反了SRP(单一责任原则)吗? - >不,这是开发人员对违反SRP的实用程序类承担过多责任。
- “它不能使用DI框架注入” - > StringUtils实现会有所不同吗?我们要在运行时切换它的实现吗?我们要嘲笑它吗?当然不是。
=>公用事业课,他们都不错。这是开发人员的错,使其变坏。
这一切都取决于具体情况。如果您要创建一个仅包含单一职责的实用程序类,并且仅在模块或层中私有使用。然后你仍然很好。
1
2017-10-30 17:19
只要你设计好它们就很好(也就是说,你不必经常改变它们的签名)。
这些实用方法通常不会改变,因为它们只做一件事。当你想要将更复杂的对象紧密到另一个时,问题就来了。如果其中一个需要更换或更换,如果你有高度耦合,那将更难。
由于这些实用方法不会改变,我常说这不是什么大问题。
我认为如果一遍又一遍地复制/粘贴相同的实用方法,那将是最糟糕的。
这个视频 如何设计一个好的API及其重要性作者Joshua Bloch解释了设计API时要记住的几个概念(这将是您的实用程序库)。虽然他是公认的Java架构师,但内容适用于所有编程语言。
0
2017-11-04 01:53
谨慎使用它们,您希望尽可能多地将逻辑放入类中,这样它们就不会成为数据容器。
但是,与此同时,你无法真正避免使用它们,有时它们是必需的。
在这种情况下,我认为这没关系。
仅供参考,有一个system.web.httputility类,它包含许多常见的http实用程序,您可能会觉得它们很有用。
0
2017-11-04 02:04