在IEnumerable中创建元素而不是向其添加现有元素

时间:2017-04-27 11:07:58

标签: c# oop design-patterns domain-driven-design ienumerable

使用这种方法将新项目添加到自定义集合中会很好吗?不是要添加现有元素,而是在集合中创建新元素?方法名称“添加”适用于这种情况? (目的是隐藏存储库。)谢谢。

public class MyObject
{
    public int ID { get; }
    public Value1 { get; }
    public Value2 { get; }
}

public interface ICustomCollection : IEnumerable<MyObject>
{
    MyObject Add(value1, value2);
}

public class CustomCollection : ICustomCollection
{
    MyObjectFactory factory;
    MyObjectRepository repository;

    public IEnumerator<MyObject> GetEnumerator()
    {
        return repository.GetAllObjects();
    }

    public MyObject Add(value1, value2)
    {
        var newItem = factory.Create(value1, value2);
        repository.AddObject(newItem);
        return newItem;
    }

    //...
}

2 个答案:

答案 0 :(得分:0)

我认为您不需要IEnumerable<T>的实施。没有它就足以引入存储库接口。

public interface IMyObjectRepostory
{
    IEnumerable<MyObject> GetAll();
    MyObject Add(value1, value2);
}

public class MyObjectRepostory
{
    public IEnumerable<MyObject> GetAll()
    {
        _repository.GetAllObjects();
    }

    MyObject Add(value1, value2)
    {
        var newItem = factory.Create(value1, value2);
        repository.AddObject(newItem);
        return newItem;
    }
}

只有困扰我的事情,那就是您的存储库依赖于工厂。存储库是数据库抽象,数据库的主要职责是读写数据。您不应该在数据库操作中使用某些“业务”逻辑。

但是如果你删除工厂责任,那么最终会得到简单的存储库接口

public interface IMyObjectRepostory
{
    IEnumerable<MyObject> GetAll();
    void Add(newMyObject);
}

并使用它

IMyObjectRepository repository = new MyObjectRepository();
var allobjects = repository.GetAllObjects();

var newObject = factory.Create(value1, value2);
repository.Add(newObject);

您可以考虑再使用一层抽象来封装创建和保存。

public class MyObjectChooseBetterName
{
    private readonly IMyObjectRepository _repository;
    private readonly MyObjectFactory _factory;

    public MyObjectChooseBetterName(IMyObjectRepository repository,
                                    MyObjectFactory factory)
    {
        _repository = repository;
        _factory = factory;
    }

    public MyObject CreateAndSave(object value1, object value2)
    {
        var newObject = _factory.Create(value1, value2);
        _repository.Add(newObject);
        return newObject;
    }
}

并使用它

var manager = new MyObjectChooseBetterName(repository, factory);
var newObject = manager.CreateAndSave(value1, value2);

答案 1 :(得分:0)

您不需要集合来隐藏您的存储库,因为存储库已经充当外部世界的集合。

  

对于需要全局访问的每种类型的对象,创建一个可以提供内存幻觉的对象   该类型的所有对象的集合

来自弗农的Implementing DDD,p.401,引用埃文斯的original DDD book关于存储库。

此外,内聚集合通常不会创建对象。它们处理现有对象(或原始值)。