C# 我的职能是否违反SRP或其他最佳实践?

C# 我的职能是否违反SRP或其他最佳实践?,c#,refactoring,single-responsibility-principle,C#,Refactoring,Single Responsibility Principle,我有下面这段代码,一个函数将获得一个对象列表(我称之为Y对象),并调用另一个方法将其转换为X对象 public List<X> GetXObjects() { var yObjects= GetYObjects(); var transformer = new Transformer(); var xObjects = transformer.Transform(yObjects); return xObjects; } public List Ge

我有下面这段代码,一个函数将获得一个对象列表(我称之为Y对象),并调用另一个方法将其转换为X对象

public List<X> GetXObjects()
{
    var yObjects= GetYObjects();
    var transformer = new Transformer();
    var xObjects = transformer.Transform(yObjects);
    return xObjects;
}
public List GetXObjects()
{
var yObjects=GetYObjects();
无功变压器=新变压器();
var xObjects=变压器。变换(yObjects);
返回XObject;
}

当前的实现是有效的,但是,我觉得我的功能可能会违反SRP或其他最佳实践。是否可以将代码重构得更好?

我将调用方法
TransformObjects
,并将transformer添加为参数,这样就可以使用不同的transformer,并且每次调用该方法时都不会初始化transformer。对于
yObjects
也一样。因此,该方法的唯一职责是变换对象

public List<X> TransformObjects(List<Y> yObjects, Transformer transformer)
{
    var xObjects = transformer.Transform(yObjects);
    return xObjects;
}

如果您创建一个接口
ITransformer
接口,则通过交换转换器来增强代码会更容易。

您的功能将执行下一个任务

  • 负荷活动
  • 创建transformer的实例
  • 变换加载的对象
通过将其作为参数引入,可以删除活动负载

public List<X> GetXObjects(List<Y> yObjects)
{
    var transformer = new Transformer();
    return transformer.Transform(yObjects);
}
但是点击意味着你需要加载
XObjects
的每个地方,你需要知道如何加载
YObjects
以及如何创建
Transformer

因此,我们可以将这些知识/逻辑封装在一个类中

public class XObjectsProvider
{

}
此类应加载
yoobjects
,并将其转换为XObject。加载和创建转换实例的实际实现不是此类的责任,因此我们将它们作为依赖项引入

public class XObjectsProvider
{
    private Loader _loader;
    private Transformer _transformer;

    public XObjectsProvider(Loader loader, Transformer transformer)
    {
        _loader = loader;
        _transformer = transformer;
    }

    public XObjects Get()
    {
        var yObjects = _loader.GetYObjects();
        return transformer.Transform(yObjects);
    }
}
Loader
Transformer
可以作为抽象引入,这样您就可以在不更改
XObjectProvider
的代码的情况下更改它们-遵循“打开/关闭原则”。
XObjectProvider
只有一个原因需要更改-获取xobject时,您需要加载/提供其他信息。

我的两分钱

我会以很少的成本使这段代码更加通用。继续往下说,为什么不干脆拆下这个讨厌的变压器呢?任何知道如何将
Y
转换为
X
的东西都可以,对吗

为什么要接受并返回
列表
?让消费者决定他是否想急切地消费枚举,除非必要,否则不要为他做出决定

public IEnumerable<TResult> TransformObjects<TResult, TSource>(
    IEnumerable<TSource> source, Func<TSource, TResult> transformer)
    => source.Select(transformer);

因此,您的代码最终是可枚举的。请选择!很好,这里没有bug,我只需要少测试一个方法,继续;)

答案很好,但是,如果你沿着这条路走下去,为什么要重新发明轮子呢?不需要
TransformObjects
可枚举。选择
已经完成了这项工作(有关详细信息,请参阅我的答案)。@in这是一个非常好的提示!我想解释如何在一般情况下实现SRP->而不是使用
Enumerable.Select
public class XObjectsProvider
{

}
public class XObjectsProvider
{
    private Loader _loader;
    private Transformer _transformer;

    public XObjectsProvider(Loader loader, Transformer transformer)
    {
        _loader = loader;
        _transformer = transformer;
    }

    public XObjects Get()
    {
        var yObjects = _loader.GetYObjects();
        return transformer.Transform(yObjects);
    }
}
public IEnumerable<TResult> TransformObjects<TResult, TSource>(
    IEnumerable<TSource> source, Func<TSource, TResult> transformer)
    => source.Select(transformer);
var xObjects = GetYObjects().Select(transformer.Transform);