C# 创建一个Catch All AppToolbox类-这是一个糟糕的做法吗?
永远不要确定在何处放置函数,如:C# 创建一个Catch All AppToolbox类-这是一个糟糕的做法吗?,c#,oop,C#,Oop,永远不要确定在何处放置函数,如: String PrettyPhone( String phoneNumber ) // return formatted (999) 999-9999 String EscapeInput( String inputString ) // gets rid of SQL-escapes like ' 我为每个应用程序创建一个Toolbox类,作为不适合另一个类的函数的存储库。我读到过这样的类是糟糕的编程实践,特别是糟糕的面向对象设计。然而,所说的参考资料似乎
String PrettyPhone( String phoneNumber ) // return formatted (999) 999-9999
String EscapeInput( String inputString ) // gets rid of SQL-escapes like '
我为每个应用程序创建一个
Toolbox
类,作为不适合另一个类的函数的存储库。我读到过这样的类是糟糕的编程实践,特别是糟糕的面向对象设计。然而,所说的参考资料似乎更多的是个人设计师和开发人员的意见,而不是一个总体共识。所以我的问题是,通用工具箱是一种糟糕的设计模式吗?如果是,为什么,还有什么选择?这没什么错。一件事是尝试将其分解为逻辑部分。通过这样做,你可以保持你的智能感知干净
MyCore.Extensions.Formatting.People
MyCore.Extensions.Formatting.Xml
MyCore.Extensions.Formatting.Html
我认为它不受欢迎的原因是因为“工具箱”可以增长,每次调用单个函数时,都会加载大量资源 将方法应用于实际类中的对象也更为优雅——只是更有意义而已
话虽如此,我个人并不认为这是个问题,但出于上述原因,我会避免它。好问题。我总是发现任何足够复杂的项目都需要“实用”类。我认为这仅仅是因为面向对象编程的本质迫使我们将事物放在一个结构整齐的层次分类法中,而这并不总是可行或合适的(例如,尝试为哺乳动物创建一个对象模型,然后挤压鸭嘴兽)。这就是促使工作进入(c.f.)的问题。通常,进入实用程序类的是交叉关注点 使用工具箱或实用程序类的一种替代方法是使用扩展方法为基元类型提供所需的附加功能。然而,对于这是否构成良好的软件设计,陪审团仍然没有定论
关于这个问题,我的最后一句话是:如果你需要,就去做吧,只是要确保你不是捷径更好的设计。当然,如果需要,您可以随时在以后重构 在这些示例中,我更倾向于扩展字符串:
class PhoneNumber extends String
{
public override string ToString()
{
// return (999) 999-9999
}
}
如果您写下所有需要这些函数的地方,您就可以找出实际使用它的地方,然后将它添加到适当的类中。这有时可能很困难,但仍然是你应该追求的目标
编辑:
正如下面指出的,您不能重写C#中的字符串。我想说的一点是,这个操作是在一个电话号码上进行的,所以这个功能就属于这个号码:
interface PhoneNumber
{
string Formatted();
}
如果您有不同的格式,您可以交换PhoneNumber的实现,而不会将代码与If语句混在一起,例如
而不是:
if(country == Countries.UK) output = Toolbox.PhoneNumberUK(phoneNumber);
else ph = Toolbox.PhoneNumberUS(phoneNumber);
您只需使用:
output = phoneNumber.Formatted();
我认为首先想到的是静态助手类。这是如此普遍,一些人甚至将其称为面向对象设计的一部分。然而,helper类的最大问题是它们往往会变成一个大转储。我想我在参与的一些大型项目中看到了这种情况。您正在处理一个类,但不知道将这个函数和那个函数放在何处,所以您将它放在了helper类中。在这一点上,你的助手不能很好地沟通他们所做的事情。类名中的名称“helper”或“util”本身没有任何意义。我认为几乎所有的OO大师都反对helper,因为如果你充分考虑的话,你可以很容易地用更具描述性的类来代替它们。我倾向于同意这种做法,因为我认为帮手违反了单一责任原则。老实说,把这件事放在心上吧。我对OOP有点固执己见:)我的经验是,实用功能很少单独出现。如果您需要一种格式化电话号码的方法,那么您还需要一种验证电话号码和解析电话号码的方法。遵循YAGNI原则,在实际需要这些东西之前,您肯定不会想编写这些东西,但我认为继续编写并将这些功能划分为单独的类是很有帮助的。随着时间的推移,这些类将从单一的方法增长为次要的子系统。我发现这是长期保持代码组织、可理解和可维护性的最简单方法。当我创建应用程序时,我通常创建一个静态类,其中包含静态方法和属性,我不知道将它们放在哪里 这不是一个特别好的设计,但这就是重点:它给了我一个地方来定位我还并没有想到的一整类设计决策。一般来说,随着应用程序的增长和重构的完善,这些方法和属性实际上应该驻留在何处变得更加清晰。幸运的是,重构工具的状态是这样的,这些更改通常不会特别痛苦 我尝试过用另一种方法,但另一种方法基本上是在我对我的应用程序有足够的了解以正确设计对象模型之前实现一个对象模型。如果我这样做,我会花大量的时间和精力想出一个平庸的解决方案,我必须在未来的某个时候重新审视和重建。好吧,如果我知道我要重构这段代码,那我跳过设计和构建不必要的复杂类的步骤,这些类实际上不起作用,怎么样 例如,我构建了一个被多个客户使用的应用程序。我很早就发现,我需要找到一种方法来区分需要为不同客户提供不同工作方式的方法。我构建了一个静态实用程序方法,我可以在程序中需要调用自定义方法的任何时候调用它,并将其固定在我的静态类中 这几个月来效果不错。但到了一个地步,它才刚刚开始显得丑陋。所以我决定重构它