循环枚举是否为单个责任

本文关键字:单个 责任 是否 枚举 循环 | 更新日期: 2023-09-27 17:56:49

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

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

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;
        }
    }
}

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

循环枚举是否为单个责任

我知道

你不希望你的代码被同行评审,所以我会坚持这些问题。我不认为你的课程违反了SRP。您的类是一个"存储还原器",这正是该类所做的。实际上,实际操作(添加、附加、删除和更新)是在另一个符合执行原子操作责任的类中实现的。代码易于阅读且非常易于理解,因此没有问题。也许有些人可能会争辩说代码可以更改为:

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

并将单个项目恢复的责任发送给存储项目本身,但我认为该类可以按原样进行。

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

你的类的唯一职责是按它的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] 这样的方法是合理的。主要取决于您的整个代码库。如果您从不对单个元素进行操作,只对枚举进行操作,则此权衡将满足您的需求。