我想问一下有经验的软件开发人员和架构师,有一天我在一些代码中发现了这个领域类。
public class User : Entity
{
public virtual string Firstname { get; set; }
public virtual string Lastname { get; set; }
public User(string firstName, string lastName, IUserRepository userRepository, IUserService userService)
{
Firstname = firstName;
Lastname = lastName
userRepository.Save(this);
userService.DoSomeStaff(this);
}
}你认为坚实的原则,特别是关于构造函数的原则?我认为这至少违反了单一责任原则,因为:
也许有一些项目架构推荐这种代码样式?
下面是涉及到的存储库和服务的定义:
public class UserRepository : IUserRepository
{
// some code of repository pattern with Nhibernate
public void Save(User user)
{
//here Session is Nhibernate.ISession
Session.SaveOrUpdate(user);
}
}
public class UserService : IUserService
{
private readonly ISomeName1Repository _someName1Repository;
private readonly ISomeName2Repository _someName2Repository;
public UserService(ISomeName1Repository someName1Repository, ISomeName2Repository someName2Repository)
{
_someName1Repository = someName1Repository;
_someName2Repository = someName2Repository;
}
public void DoSomeStaff(User user)
{
var foo = _someName1Repository.DoSomeStaff();
// some work here with user
}
}发布于 2017-11-18 13:41:18
你对坚实原则的看法
好吧,至少构造函数使用依赖注入,所以这里应用了来自SOLID的D,我猜?-)但是我假设您的问题是关于SRP的,而不是一般的SOLID。
因此,严肃地说,这个设计在我看来就像是有人想要在创建User对象时调用“回调”或“钩子”(可能是为了确保该对象也存在于存储库中,或者其他服务被告知对象的创建)。
实际上,我认为如果这真的违反了SRP,这是有争议的(因为它将很容易通过传递一个虚拟回购来取消像userRepository.Save这样的调用)。因此,这两个附加参数并不禁止在不需要回购和/或服务的情况下对该类进行单元测试或重用(这将是违反SRP的明显迹象)。
然而,我认为这违反了更基本的接吻原则。注入的接口使调用代码更加复杂。我们没有看到所有的周围代码,但是IMHO (几乎)总是能够让域对象完全清除任何回调或服务调用,并让周围的环境处理这些事情。根据我的经验,这将导致一个总体上更简单、更容易理解和更易于维护的系统。
发布于 2017-11-16 17:44:10
建筑工人是这里的灰色地带。我不会被它对周围对象所暗示的正确性所困扰。静态初始化器和静态工厂方法也是如此。转而关注对象的实例方法。
如果您担心膨胀会渗透到初始化器中,那么将代码移出,例如进入依赖注入框架。
发布于 2017-11-16 20:13:57
SRP的要点是不要在同一个类中实现多个责任。示例类本身只是一个名和名的容器,它没有更多的数据,也没有更多的逻辑/行为。它可能会调用其他对象来执行不同的任务,但是这些任务没有在用户类中实现,所以从SRP的角度来看,这是非常好的。
https://softwareengineering.stackexchange.com/questions/360847
复制相似问题