|
|
1
9
我不得不说“是的”,但你必须做好你的srp。如果同一个操作只应用于一个类,那么它就属于那个类,不是吗?如果同一个操作应用于多个类呢?在这种情况下,如果你想遵循把数据和行为结合起来的oo模型,你应该把操作放到一个基类中,不是吗? 我怀疑从你的描述来看,你最终得到的类基本上是操作包,所以你基本上重新创建了c风格的编码:结构和模块。 来自链接的SRP文件: “ SRP是最简单的原则之一,也是最难纠正的原则之一。 “ |
|
|
2
13
富域模型(rdm)和单一责任原则(srp)并不一定矛盾。rdm与一个非常专业的srp子类(提倡“数据bean+控制器类中的所有业务逻辑”的模型(dbablicc))更不一致。 如果你读马丁的 SRP chapter ,你会看到他的 调制解调 示例完全在域层中,但将数据通道和连接概念抽象为单独的类。他将调制解调器本身作为包装器保存,因为这对客户机代码是有用的抽象。更重要的是 (再)保理 比单纯 分层 . 衔接和耦合仍然是设计的基本原则。 最后,有三个问题:
|
|
|
3
6
SRP论文中的引用是非常正确的;SRP很难得到正确的答案。这一点和ocp是solid的两个元素,为了实际完成一个项目,这两个元素必须放松到至少某种程度。过分热心地应用两者都会很快产生馄饨代码。 如果“改变的原因”过于具体,SRP确实可以被视为荒谬的长度。即使一个POCO / POJO“数据包”可以被认为是违反SRP,如果你认为一个字段的类型改变为“改变”。您可能认为常识会告诉您,字段的类型更改是“更改”所必需的允许,但我见过为内置值类型使用包装器的域层;一个让adm看起来像乌托邦的地狱。 基于可读性或期望的内聚水平,用一些现实的目标为自己打下基础通常是好的。当你说“我想让这个班做一件事”的时候,它应该没有比做这件事所必需的更多或更少的东西。你至少可以用这个基本哲学来保持程序衔接。”我希望这个类维护发票的所有数据“通常允许一些业务逻辑,甚至汇总小计或计算销售税,基于对象的责任,知道如何为它包含的任何字段提供准确、内部一致的值。 我个人对“轻量级”域没有大问题。只需扮演“数据专家”的角色,域对象就可以成为与类相关的每个字段/属性以及所有计算字段逻辑、任何显式/隐式数据类型转换以及更简单的验证规则(即必需字段、值限制,如果允许,会在内部中断实例的内容)。如果一个计算算法,可能是一个加权平均值或滚动平均值,可能会发生变化,那么将该算法封装起来,并在计算字段中引用它(这只是一个好的ocp/pv)。 我不认为这样的领域对象是“贫血”。我对这个术语的理解是一个“数据包”,它是一个字段集合,除了包含这些字段之外,它对外部世界甚至其字段之间的关系都没有任何概念。我也看到过,跟踪对象状态中的不一致并不有趣,因为对象从来不知道这是一个问题。过分热心的srp会导致这种情况,因为它声明一个数据对象不负责任何业务逻辑,但常识通常会首先介入,并说该对象作为数据专家必须负责维护一致的内部状态。 再说一次,个人观点,比起活动记录,我更喜欢存储库模式。一个对象,有一个职责,而且在这个层之上的系统中几乎没有任何东西需要知道它是如何工作的。活动记录要求域层至少知道有关持久化方法或框架的一些特定细节(无论是用于读/写每个类的存储过程的名称、特定于框架的对象引用,还是用orm信息修饰字段的属性)。因此在默认情况下,将第二个原因注入到每个域类中。 我的0.02美元。 |
|
|
4
4
我发现遵循这些坚实的原则确实让我远离了ddd的富域模型,最后,我发现我并不在乎。更重要的是,我发现域模型的逻辑概念和任何语言的类都不是1:1映射的,除非我们讨论的是某种门面。 我不会说这完全是一种C风格的编程,你有结构和模块,但你可能会以更实用的方式结束,我意识到风格是相似的,但细节有很大的不同。我发现我的类实例最终的行为类似于高阶函数、部分函数应用程序、延迟计算的函数或以上的一些组合。这对我来说有点难以形容,但这就是我从遵循tdd+solid编写代码中得到的感觉,它最终表现为一种混合的oo/函数风格。 至于继承是一个不好的词,我认为这更多的是因为继承在Java和C语言中没有足够的细粒度。在其他语言中,它不那么重要,而且更有用。 |
|
|
5
1
我喜欢SRP的定义是: “一个类只有一个业务原因需要更改” 因此,只要行为可以被归类为单一的“商业原因”,那么就没有理由让他们不在同一个阶级共存。当然,什么定义了“业务原因”值得商榷(所有利益相关者都应该商榷)。 |
|
|
6
1
在我开始咆哮之前,我的观点是:在某个地方,所有的事情都必须走到一起…然后一条河流过。 我被编码困扰着。 不受欢迎的= 贫血数据模型和我…嗯,我们经常在一起。也许这只是中小型应用程序的本质,其中很少内置业务逻辑。也许我只是有点“油腻”。 不过,这是我的2美分: 你就不能把实体中的代码分解出来并把它绑定到一个接口上吗?
这是否违反了srp的原则? 此外,除了消耗性代码之外,没有任何东西将一堆类绑定在一起,这难道不是对srp的一个更大的违反,而是推高了一层吗? 想象一下,编写客户机代码的人坐在那里试图找出如何做与object1相关的事情。如果他必须使用您的模型,他将使用object1、数据包和一系列“服务”,每个服务都有一个单一的职责。他的工作就是确保所有这些东西都能正常互动。所以现在他的代码变成了一个事务脚本,该脚本本身将包含正确完成特定事务(或工作单元)所需的所有职责。 此外,您可以说,“没有brah,他需要做的只是访问服务层。就像object1service.doActionX(object1)。小菜一碟。“那么,现在的逻辑在哪里呢?所有这些都是一种方法?你仍然只是在推送代码,不管怎样,你最终都会得到数据和逻辑的分离。 所以在这个场景中,为什么不向客户机代码公开特定的object1服务,让它的doActionX()基本上只是域模型的另一个钩子?我的意思是:
您仍然从object1中分解出了action1的实际代码,但是出于所有密集目的,都有一个非贫血的object1。 假设您需要action1来表示2个(或更多)不同的操作,您希望这些操作是原子的,并被分离到它们自己的类中。只需为每个原子操作创建一个接口,并将其连接到doaction1内部。 这就是我处理这种情况的方法。但再说一遍,我真的不知道srp是什么意思。 |
|
|
7
0
将纯域对象转换为 ActiveRecord 对所有域对象使用公共基类的模式。将公共行为放在基类中,并在必要时重写派生类中的行为,或者在需要时定义新行为。 |