这是否违反了SOLID原则?

3

我在我的项目中有类似这样的东西,这个项目已经基本完成了(它能够正常工作)。我只是想知道是否符合SOLID原则。

static public class Tools
{
    static public GetProduct(this id){...}

    static public GetProductCategory(this id){...}

    static public GetUser(this id){...}

    // I also have here methods like IsStringNull ...
    // IsNull IsFalse, lots of stuff, everything static
}

使用方法如下:

var UserThatCreatedCategoryForThisProduct = 
      prodId.GetProduct().CategoryId.GetProductCategory().Creator.GetUser();

我知道这显然违反了SRP原则,但是这个类是静态的,它包含了相互独立的静态方法。如果我为每个方法创建一个静态类,那么本质上就是一样的。

2
这些是扩展方法吗?语法看起来有些不对。 - peterchen
@peterchen:使用示例表明这绝对是计划中的,发现得好(我读了它,甚至没有注意到 - 这真是个糟糕的主意!) - Ruben Bartelink
1
对于一个好问题点赞:是的,这违反了SRP原则。 - Prisoner ZERO
3个回答

8
据我所见,这里存在许多SOLID原则的违规情况!
单一职责原则的违规情况 - 首先,你为几个类编写了数据访问方法,其次,你将帮助方法(IsStringNull、IsNull等)与它们交织在一起。
接口隔离原则的违规情况(如Ruben所述) - 如果我只关心产品,为什么我需要暴露获取用户的方法?
我相信还有其他问题,但这些是最明显的。
更新:现在有人评论说,上面的代码看起来像某种形式的扩展方法滥用。
例如,我不认为数据访问应该被归类为扩展方法,或者更糟糕的是,被归类为名为“Tools”的类。
可能更有意义的做法是拥有一个基类(在完全不同的命名空间和/或程序集中),抽象出你的数据访问通用性,然后为每个唯一的域对象继承一个数据访问类(例如UserDAO、ProductDAO等)。请注意,我在这里的假设是,通过GetProduct或GetUser,你实际上是指从数据库中获取。
其余的帮助方法属于扩展方法,所以没问题。

实际上我有这些DAO类,它们被用在Tools类的方法中。 - Omu
1
再次提到SRP(单一职责原则)。你的Tool类正在做太多的事情。如果你有DAO类,可以将它们分组放在UserManager或ProductManager类中,其中包含所有CRUD和其他功能。扩展方法应该在不干扰现有类的情况下添加功能,而不是隐藏其真实位置的现有功能。 - Jon Limjap

2
根据你的例子,至少存在ISP和SRP,可能存在迪米特法则(不是SOLID但...)的违规。
在我看来,你最好阅读关于SOLID的文章(或购买罗伯特·C·马丁和米卡·马丁的《C#敏捷原则、模式和实践》这本书非常优秀,在近年来我所读过的书籍中非常有用),而不是在互联网上寻求零碎的建议。
如果你想要一个捷径(其实你不需要——这些书籍和PDF都有很好的解释示例!),这些与Uncle Bob合作的Hanselminutes播客非常好。

编辑:从 Jon Limjapppiotrowicz 那里学到了 SRP。


有什么替代方案吗?肯定不是将“UserThatCreatedCategoryForThisProduct”作为ProductID的属性/扩展方法! - peterchen
1
Peterchen,这实际上是一个非常深入的话题,需要大量的培训和/或实践才能掌握。从软件开发中的功能/过程思维跳转到真正的面向对象思维方式是一个巨大的鸿沟,不幸的是需要克服。 - Jon Limjap
@Jon - 好的,我理解。但对我来说,访问模式似乎是由数据结构所强加的,而数据结构通常比处理代码更加稳定(请原谅双关语)。 - peterchen

0

这个程序在很多方面都违反了SOLID原则。

  • 它没有遵循单一职责原则,因为它至少做了三件不同的事情(返回产品、返回客户、字符串操作?)
  • 它违反了开闭原则,因为它不具备扩展性。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接