我的职能是否违反了 SRP 或其他最佳实践?
Does my function violate SRP or other best practices?
我有以下这段代码,一个函数将获取对象列表(我称之为 Y 对象)并调用另一个方法将其转换为 X 对象。
public List<X> GetXObjects()
{
var yObjects= GetYObjects();
var transformer = new Transformer();
var xObjects = transformer.Transform(yObjects);
return xObjects;
}
当前的实现有效,但是,我觉得我的函数可能违反了 SRP 或其他最佳实践。是否可以重构代码以使其更好?
我会调用方法 TransformObjects
并添加转换器作为参数,这样就可以使用不同的转换器,并且每次调用该方法时转换器都不会初始化。 yObjects
也一样。所以该方法的唯一职责是转换您的对象。
public List<X> TransformObjects(List<Y> yObjects, Transformer transformer)
{
var xObjects = transformer.Transform(yObjects);
return xObjects;
}
调用方法:
var yObjects= _crmWrapper.GetActivitiesByOpportunities();
var transformer = new Transformer();
myTransformer.TransformObjects(yObjects, transformer);
如果你创建一个接口 ITransformer
接口,那么通过交换转换器来增强你的代码会更容易。
您的函数执行后续任务
- 加载活动
- 创建转换器实例
- 转换加载的对象
可以通过将其作为参数引入来移除活动负载
public List<X> GetXObjects(List<Y> yObjects)
{
var transformer = new Transformer();
return transformer.Transform(yObjects);
}
那么transformer的创建也可以移到外面
public List<X> GetXObjects(Trnasformer transformer, List<Y> yObjects)
{
return transformer.Transform(yObjects);
}
所以现在在代码中的某些地方你可以这样称呼它
var yObjects= _crmWrapper.GetActivitiesByOpportunities();
var transformer = new Transformer();
var xObjects = GetXObjects(yObjects, transformer);
但是点击意味着每一个你需要加载的地方XObjects
你需要知道如何加载YObjects
以及如何创建Transformer
所以我们可以把这个knowledge/logic封装成一个class
public class XObjectsProvider
{
}
此 class 应加载 YObjects
并将它们转换为 XObject。加载和创建 Transform 实例的实际实现不属于此 class - 因此我们将它们作为依赖项引入。
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
的代码的情况下更改它们 - 在 "Open/Close principle" 之后。
XObjectProvider
只有一个改变的理由——在获取 XObjects 时你需要 load/provide 一些其他信息。
我的两分钱...
我会以很少的成本使这段代码更加通用。扩展 ,为什么不继续简单地删除这个讨厌的转换器呢?任何知道如何将 Y
转换为 X
的东西都应该可以,对吗?
为什么接受和 return 一个 List
?让消费者决定他是否要急切消费枚举,除非必要,否则不要为他做决定。
public IEnumerable<TResult> TransformObjects<TResult, TSource>(
IEnumerable<TSource> source, Func<TSource, TResult> transformer)
=> source.Select(transformer);
现在你突然意识到;嘿!这只是一个普通的好旧 Enumerable.Select
,不是吗?那么,为什么要重新发明轮子?
var xObjects = GetYObjects().Select(transformer.Transform);
所以你的代码终于是 Enumerable.Select
!太好了,这里没有错误,我需要测试的方法少了一种,继续;)。
我有以下这段代码,一个函数将获取对象列表(我称之为 Y 对象)并调用另一个方法将其转换为 X 对象。
public List<X> GetXObjects()
{
var yObjects= GetYObjects();
var transformer = new Transformer();
var xObjects = transformer.Transform(yObjects);
return xObjects;
}
当前的实现有效,但是,我觉得我的函数可能违反了 SRP 或其他最佳实践。是否可以重构代码以使其更好?
我会调用方法 TransformObjects
并添加转换器作为参数,这样就可以使用不同的转换器,并且每次调用该方法时转换器都不会初始化。 yObjects
也一样。所以该方法的唯一职责是转换您的对象。
public List<X> TransformObjects(List<Y> yObjects, Transformer transformer)
{
var xObjects = transformer.Transform(yObjects);
return xObjects;
}
调用方法:
var yObjects= _crmWrapper.GetActivitiesByOpportunities();
var transformer = new Transformer();
myTransformer.TransformObjects(yObjects, transformer);
如果你创建一个接口 ITransformer
接口,那么通过交换转换器来增强你的代码会更容易。
您的函数执行后续任务
- 加载活动
- 创建转换器实例
- 转换加载的对象
可以通过将其作为参数引入来移除活动负载
public List<X> GetXObjects(List<Y> yObjects)
{
var transformer = new Transformer();
return transformer.Transform(yObjects);
}
那么transformer的创建也可以移到外面
public List<X> GetXObjects(Trnasformer transformer, List<Y> yObjects)
{
return transformer.Transform(yObjects);
}
所以现在在代码中的某些地方你可以这样称呼它
var yObjects= _crmWrapper.GetActivitiesByOpportunities();
var transformer = new Transformer();
var xObjects = GetXObjects(yObjects, transformer);
但是点击意味着每一个你需要加载的地方XObjects
你需要知道如何加载YObjects
以及如何创建Transformer
所以我们可以把这个knowledge/logic封装成一个class
public class XObjectsProvider
{
}
此 class 应加载 YObjects
并将它们转换为 XObject。加载和创建 Transform 实例的实际实现不属于此 class - 因此我们将它们作为依赖项引入。
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
的代码的情况下更改它们 - 在 "Open/Close principle" 之后。
XObjectProvider
只有一个改变的理由——在获取 XObjects 时你需要 load/provide 一些其他信息。
我的两分钱...
我会以很少的成本使这段代码更加通用。扩展 Y
转换为 X
的东西都应该可以,对吗?
为什么接受和 return 一个 List
?让消费者决定他是否要急切消费枚举,除非必要,否则不要为他做决定。
public IEnumerable<TResult> TransformObjects<TResult, TSource>(
IEnumerable<TSource> source, Func<TSource, TResult> transformer)
=> source.Select(transformer);
现在你突然意识到;嘿!这只是一个普通的好旧 Enumerable.Select
,不是吗?那么,为什么要重新发明轮子?
var xObjects = GetYObjects().Select(transformer.Transform);
所以你的代码终于是 Enumerable.Select
!太好了,这里没有错误,我需要测试的方法少了一种,继续;)。