在我开始咆哮之前,简而言之,这是我的观点:在某个地方,一切都必须融合在一起……然后一条河流穿过它。
我被编码所困扰。
=======
贫血的数据模型和我……嗯,我们经常交朋友。也许这只是中小型应用程序的本质,其中内置的业务逻辑很少。也许我只是有点'迟到了。
但是,这是我的 2 美分:
难道你不能把实体中的代码分解出来并绑定到一个接口上吗?
public class Object1
{
public string Property1 { get; set; }
public string Property2 { get; set; }
private IAction1 action1;
public Object1(IAction1 action1)
{
this.action1 = action1;
}
public void DoAction1()
{
action1.Do(Property1);
}
}
public interface IAction1
{
void Do(string input1);
}
这是否以某种方式违反了 SRP 的原则?
此外,除了消耗代码之外,没有其他任何东西相互联系的一堆类是否实际上是对 SRP 的更大违反,而是推高了一层?
想象一下,编写客户端代码的人坐在那里试图弄清楚如何做与 Object1 相关的事情。如果他必须使用您的模型,他将使用 Object1、数据包和一堆“服务”,每个服务都有一个职责。他的工作是确保所有这些东西都能正常交互。所以现在他的代码变成了一个事务脚本,这个脚本本身将包含正确完成该特定事务(或工作单元)所需的所有职责。
此外,您可以说,“不,他需要做的就是访问服务层。这就像 Object1Service.DoActionX(Object1)。小菜一碟。” 那么,现在的逻辑在哪里?都在一种方法中?您仍然只是在推动代码,无论如何,您最终都会将数据和逻辑分开。
所以在这种情况下,为什么不向客户端代码公开特定的 Object1Service 并让它的 DoActionX() 基本上只是你的域模型的另一个钩子?我的意思是:
public class Object1Service
{
private Object1Repository repository;
public Object1Service(Object1Repository repository)
{
this.repository = repository;
}
// Tie in your Unit of Work Aspect'ing stuff or whatever if need be
public void DoAction1(Object1DTO object1DTO)
{
Object1 object1 = repository.GetById(object1DTO.Id);
object1.DoAction1();
repository.Save(object1);
}
}
您仍然从 Object1 中提取出 Action1 的实际代码,但出于所有密集目的,有一个非贫血的 Object1。
假设您需要 Action1 来表示 2 个(或更多)不同的操作,您希望这些操作具有原子性并分离到它们自己的类中。只需为每个原子操作创建一个接口并将其连接到 DoAction1 中。
这就是我可能会处理这种情况的方式。但话又说回来,我真的不知道 SRP 是什么。