如何更好地设计这门课程?

时间:2017-06-18 20:11:24

标签: c# design-patterns

我们有一个Web API库,它调用业务/服务库(我们的业务逻辑所在的位置),然后调用数据访问库(存储库)。

我们在所有地方都使用这种类型的数据传输对象。它有一个"付款人"我们可能必须过滤的属性(意思是,操纵它的值)。我已经开始实施这样的检查了,但是对我来说感觉很脏,因为我在整个地方都调用相同的功能。我考虑过:

  1. 使用属性过滤器来处理此问题或
  2. 使RequestData成为类的属性,并在构造函数中进行过滤。
  3. 可以更有效地设计任何其他想法或设计模式:

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

2 个答案:

答案 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。我实际上并没有建议为这样一个简单的案例安装另一个库,但强调一般可以检查这些类型的问题。)

相关问题