循环遍历枚举是一个单一的责任吗?

时间:2016-07-14 08:02:35

标签: c# oop single-responsibility-principle

循环一个集合是一个单一的责任,我是否必须在自己的类中实现它?

这是一般问题的具体示例:我有一个带有方法的类,它循环遍历枚举并处理每个项目:

internal class StorageRestorer
{
    #region log4net

    private static log4net.ILog _log = log4net.LogManager.GetLogger(typeof(StorageRestorer<TEntity>));

    #endregion log4net

    private ServiceController _serviceController;

    /// <summary>
    /// Creates a new instance of the StorageRestorer class.
    /// </summary>
    /// <param name="serviceController">Service controller, where to resore the storage.</param>
    public StorageRestorer(ServiceController serviceController)
    {
        _serviceController = serviceController;
    }

    /// <summary>
    /// Restores the given storage items into the service controller.
    /// </summary>
    /// <param name="items">Storage items to be restored.</param>
    public void Restore(IEnumerable<StorageItem> items)
    {
        foreach (var item in items)
            Restore(item);
    }

    private void Restore(StorageItem item)
    {
        if (item.Status == EntityStates.Added)
        {
            _serviceController.AddObject(item.Entity);
            return;
        }

        _serviceController.AttachObject(item.Entity);
        switch (item.Status)
        {
            case EntityStates.Deleted:
                _serviceController.DeleteObject(item.Entity);
                break;
            case EntityStates.Modified:
                _serviceController.UpdateObject(item.Entity);
                break;
        }
    }
}

我现在的问题是:由于循环,这个类是否违反了单一责任原则?

2 个答案:

答案 0 :(得分:0)

我知道您不希望对您的代码进行同行评审,因此我会坚持这些问题。我不认为你的班级违反了SRP。你的类是一个“存储恢复器”,这就是这个类的功能。实际上,实际操作(添加,附加,删除和更新)是在另一个符合执行原子操作职责的类中实现的。代码易于阅读且易于理解,因此没有问题。也许有些人可能认为代码可以改为:

public void Restore(IEnumerable<StorageItem> items)
{
    foreach (var item in items)
        item.Restore(_serviceController);
}

并将单个项目恢复的责任发送到存储项目本身,但我认为该课程没有问题。

关于一般性问题,循环只是实现您想要实现的目标的一种手段,而不是一种责任本身。有时为了实现责任所需,你需要编写几个循环,如果条件,嵌套开关,这并不意味着你需要为你编写的每个结构编写一个类。也许编写私有函数来帮助读取代码是个好主意,只要私有函数可以帮助你实现类真正需要做的事情,而不是其他事情(完成它所承担的责任)。

答案 1 :(得分:0)

您班级的唯一责任是通过Status派遣实体。所以,没有违规行为。更重要的是,您的类看起来像Repository模式的截断版本。但我想这不是你的问题。

我唯一要注意的是制作

void Restore(StorageItem item) // [1]

方法public。您将扩展StorageRestorer的界面而不会有任何违规行为。方法

void Restore(IEnumerable<StorageItem> items) // [2]

只不过是一个小帮手。在您的情况下,方法[2]可以很容易地丢弃。没有任何理由让方法[1]private。如果您现在不使用它,并不意味着您以后不会使用它。如果您可以对集合中的元素执行某些操作,不是集合本身,则可以使用单个元素执行这些操作。

否则,这样的事情可能会在以后出现:

resporer.Restore(new [] { item }); // OMG, who wrote that API? o.O

此外,不是在您的特定情况下,此类帮助程序可以应用一些内部优化。例如,这就是List<T>.AddRange实际上做的事情。

所以,回到你的任务。没有任何实际的违规行为,但它也不是最好的设计选择。使用[2]等方法可能合理。主要取决于您的整个代码库。如果您从未对单个元素进行操作,仅对枚举进行操作,则此权衡将满足您的需求。