面向对象的设计 - 第一类集合/封装集合应该实现集合/ IEnumerable接口吗?

时间:2013-10-17 16:23:35

标签: c# .net oop encapsulation

我是Jeff Bay的Object Calisthenics练习的粉丝:

http://www.xpteam.com/jeff/writings/objectcalisthenics.rtf

我通过创建对象来封装集合的实现以及对对象集合的迭代,从而实现了第一类集合的良好结果。

这意味着我有一个EmployeeList对象而不是List。

通常当我创建这些对象时,我没有实现任何集合接口,因此外部用户无法枚举内部集合,因为我认为这是重点。然而,一位同事提出了相反的建议 - 实施ICollect界面,使其更加灵活。

这个重构网站似乎是朝着同一个方向,虽然它没有完全删除对内部集合的访问:http://sourcemaking.com/refactoring/encapsulate-collection

    // Foreach method
    foreach (var employee in employees)
    {
        if (employee.IsManager)
        {
            managers.Add(employee);
        }
    }

    // Linq method
    managers = employees.Where(e => e.IsManager);


    // Encapsulated iteration method
    managers = employees.GetAllManagers();

    public IEnumerable<Employee> GetAllManagers() // Inside Employees class
    {
        return employees.Where(e => e.IsManager);
    }

我是否正确地说最后一种方法是有利的?你什么时候想通过实现IEnumerable来公开你的内部集合?

1 个答案:

答案 0 :(得分:0)

IEnumerable可能是个不错的选择。您可以拥有Employee对象的私有列表,并将其公开为IEnumerable,以便人们在循环,LINQ等中使用它。

由于IEnumerable不允许您修改正在迭代的集合,因此您不必担心EmployeeList更改内部的消费者。

提供迭代方法并不理想,因为它会中断POLA,并且需要花费一些精力来消费API以找到他想要调用的方法。考虑一下,你在.NET中永远不会有如下代码。

var list = new List<T>;
foreach (var item in list.GetAllItems())
{
    // Whut? 
}