循环一个集合是一个单一的责任,我是否必须在自己的类中实现它?
这是一般问题的具体示例:我有一个带有方法的类,它循环遍历枚举并处理每个项目:
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;
}
}
}
我现在的问题是:由于循环,这个类是否违反了单一责任原则?
答案 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]
等方法可能合理。主要取决于您的整个代码库。如果您从未对单个元素进行操作,仅对枚举进行操作,则此权衡将满足您的需求。