我们有一个Web API库,它调用业务/服务库(我们的业务逻辑所在的位置),然后调用数据访问库(存储库)。
我们在所有地方都使用这种类型的数据传输对象。它有一个"付款人"我们可能必须过滤的属性(意思是,操纵它的值)。我已经开始实施这样的检查了,但是对我来说感觉很脏,因为我在整个地方都调用相同的功能。我考虑过:
可以更有效地设计任何其他想法或设计模式:
public class Example
{
private MyRepository _repo = new MyRepository();
private void FilterRequestData(RequestData data)
{
//will call into another class that may or may not alter RequestData.Payers
}
public List<ReturnData> GetMyDataExample1(RequestData data)
{
FilterRequestData(RequestData data);
return _repo.GetMyDataExample1(data);
}
public List<ReturnData> GetMyDataExample2(RequestData data)
{
FilterRequestData(RequestData data);
return _repo.GetMyDataExample2(data);
}
public List<ReturnData> GetMyDataExample3(RequestData data)
{
FilterRequestData(RequestData data);
return _repo.GetMyDataExample3(data);
}
}
public class RequestData
{
List<string> Payers {get;set;}
}
答案 0 :(得分:0)
处理重复代码的一种方法是使用带有Func的策略模式(可能还有一些泛型,具体取决于您的具体情况)。您可以将它重构为单独的类,除了基本思想之外的所有内容都是这样的:
public class MyRepository
{
internal List<ReturnData> GetMyDataExample1(RequestData arg) { return new List<ReturnData>(); }
internal List<ReturnData> GetMyDataExample2(RequestData arg) { return new List<ReturnData>(); }
internal List<ReturnData> GetMyDataExample3(RequestData arg) { return new List<ReturnData>(); }
}
public class ReturnData { }
public class Example
{
private MyRepository _repo = new MyRepository();
private List<ReturnData> FilterRequestDataAndExecute(RequestData data, Func<RequestData, List<ReturnData>> action)
{
// call into another class that may or may not alter RequestData.Payers
// and then execute the actual code, potentially with some standardized exception management around it
// or logging or anything else really that would otherwise be repeated
return action(data);
}
public List<ReturnData> GetMyDataExample1(RequestData data)
{
// call the shared filtering/logging/exception mgmt/whatever code and pass some additional code to execute
return FilterRequestDataAndExecute(data, _repo.GetMyDataExample1);
}
public List<ReturnData> GetMyDataExample2(RequestData data)
{
// call the shared filtering/logging/exception mgmt/whatever code and pass some additional code to execute
return FilterRequestDataAndExecute(data, _repo.GetMyDataExample2);
}
public List<ReturnData> GetMyDataExample3(RequestData data)
{
// call the shared filtering/logging/exception mgmt/whatever code and pass some additional code to execute
return FilterRequestDataAndExecute(data, _repo.GetMyDataExample3);
}
}
public class RequestData
{
List<string> Payers { get; set; }
}
答案 1 :(得分:0)
这种想法自然导致aspect oriented programming。 它专门用于处理横切问题(例如,此处,您的过滤功能会跨越您的查询逻辑。)
正如@dnickless建议的那样,您可以通过重构调用来删除重复的代码,以临时方式执行此操作。
存在更多通用解决方案,例如PostSharp,它为您提供了一种更简洁的方法来构建代码。它是专有的,但我相信免费套餐足以调查这样的例子。至少看看它在PostSharp中的外观是否有趣,以及你是否认为它会改善它! (它充分利用了属性,这扩展了第一个建议。)
(N.B。我实际上并没有建议为这样一个简单的案例安装另一个库,但强调一般可以检查这些类型的问题。)