单一责任原则复合类

时间:2014-04-16 19:43:11

标签: oop domain-driven-design single-responsibility-principle

我有一个实体类

Public class Company
{
   public int Id {get;set;}
   public string Name {get;set;}
   .
   .
   .
   public List<Address> Addresses{get;set;}
   public List<Domain> Domains{get;set;}       
}

而且经理应该使用这个实体类

public class CompanyManager
{
   ctor
   {}
   public Company Get(int id)
   {
   }
   public List<Company> GetList()
   {
   }
   public int Add(Company company)
   {
   }
   public bool Delete(int id)
   {
   }
}

我很困惑,是否应该在公司经理中填写地址列表和域列表,还是应该使用外观层来填充这些属性。我的困惑是因为,地址和域名可以有经理类。另外,我不确定,这是否是好的做法。

2 个答案:

答案 0 :(得分:0)

首先,我高度怀疑公司只是一些公共制定者的DTO,它是由地址和域名的集合定义的。它们是否需要公司概念正确定义?您确定公司需要整个地址或域定义还是只需一个id就足够了?

您的CompanyManger与存储库类似。我不知道这是不是你想要的(数据访问管理器),还是它实际上是一个包含用例的服务。如果它是一个存储库,那么它有责任恢复(填充所有字段)对象。

答案 1 :(得分:0)

根据您上面的评论,我认为您可以使用一些一般的架构建议。这是我使用的方法,对我有用。我打电话给它&#34; CQRS-lite&#34;因为它不会使用事件来源或严格分开数据源,但它会解决您正在努力解决的SRP问题。

以下是我们如何阅读:

public class FooController {
    private IFooService _readService;

    public ActionResult List();
}

// runs DB queries, maps them to viewmodels
// If you're using EF, use one DB context per HTTP request
// and turn off change tracking
public interface IFooService  {
    FooList List();
}

// a viewmodel, only used by this controller 
// (and often only by one action/view)
public class FooList {
    public IEnumerable<FooListItem> Foos;
}

以下是我们写作的方法(这是同一个MVC控制器 - 我只是在读写之间打破了代码以便于阅读):

public class FooController {
    private IBus _bus;

    [HttpPost]
    public void Create(FooCreate model) { // could also return, e.g. RedirectToAction
        _bus.Send(new CreateFoo {
            Id = model.Id,
            // map the other properties
        })
    }
}

// e.g. NServiceBus in memory, or you can write your own
// it just finds the handler for the command via your 
// DI container
public interface IBus {
    void Send(params ICommand[] commands)
}

// A command tells the system to do something.
// It's basically a serializable remote procedure
// call, can be sync or async
public class CreateFoo : ICommand {
    public Guid Id;
    // etc
}

// A command handler.  DbContext should be scoped per-instance
// (not per HTTP request) or things get complicated.
// You can decorate Handle() with, e.g. _context.SaveChanges()
public class CreateFooHandler : IHandler<CreateFoo> {
    private IDbContext _context;

    public void Handle(CreateFoo message) {
        // write stuff to the DB
    }
}