重构为子类

时间:2012-01-16 15:34:26

标签: c# design-patterns inheritance refactoring subclass

public class ScheduleRatesController
    {
        protected CoreDataManager dataManager;

        public ScheduleRatesController()
        {
            dataManager = new CoreDataManager();
        }

        // testing
        public ScheduleRatesController(CoreDataManager manager)
        {
            dataManager = manager;
        }

        public virtual void GetTranQuotesToFillRatesAndPayments(ref List<int> ids)
        {
            ids.AddRange(new List<int>());
        }
    }

所以为了给你们一些背景知识,我们将一个数据库查询拆分成一堆不同的数据库,我们希望子类基本上每个都对他们的GetTranQuotesToFillRatesAndPayments()方法进行数据库调用,代表它的特定查询

您在上面看到的是我的基础课程。我制定了这两个方法virtual,因为我计划让子类覆盖它们以执行它们自己的东西。所以有人可能会这样:

public override void GetTranQuotesToFillRatesAndPayments(ref List<int> ids)
        {
            ids.AddRange(dataManager.GetLoanTranQuotes());
        }

等等。我的问题是,这是执行此类模式的最佳/最干净的方法吗?

调用它的代码将包含一个巨大的过滤id列表,它需要通过调用每个类调用GetTranQuotesToFillRatesAndPayments()来填充。如果这没有意义,请告诉我。由于我需要调用相同的方法(例如6次,每次在不同的类上),我有点被关闭了。我认为即使它的目标是让它变得干净,它本身也可能是混乱的。我不希望在呼叫方面有这样的事情:

List<int> ids = new List<int>();
ScheduleRatesController controller = new LoanController();
controller.GetTranQuotesToFillRatesAndPayments(ref ids);

controller = new TradeController();
controller.GetTranQuotesToFillRatesAndPayments(ref ids);

如果您需要更多背景信息或信息,请与我们联系。

感谢。

2 个答案:

答案 0 :(得分:2)

几个设计评论:

  1. 使用ref关键字通常表示设计问题,应避免使用。无需使用ref关键字传递参考值(任何List<T>始终通过引用传递)。如果没有它,您的程序将同样有效。

  2. 比将列表传递给方法更好的方法是从方法中返回您的数据,并允许调用者决定如何处理它。也许您只想在程序中的其他位置找到单个值,并且创建新列表是一种过度杀伤力。此外,您应该尝试为每个类添加尽可能少的功能(Single Responsibility Principle),您的类现在负责获取数据决定如何存储它。< / p>

  3. 命名:您的方法名称非常复杂。此外,名称“controller”通常不代表负责获取数据的对象。

  4. 另一方面,你有一个CoreDataManager类(btw, Manager is a bad suffix for any class),它似乎包含一堆返回各种数据的方法。那么ScheduleRatesController需要什么?是否只将其复制到列表中?

  5. 应将业务逻辑与数据访问层分开。您应该考虑使用Repository模式或类似模式(例如,检查this answer),以确保您的数据类仅从数据库中提取数据。

  6. 如果您有多个课程需要履行某个合同,请首先创建他们需要实施的界面。不要考虑在此时重用代码。例如,您的代码强制所有子类使用CoreDataManager,而有一天可能会发现某个“控制器”可能需要由不同的对象组成。

答案 1 :(得分:0)

使用List<Func<List<int>,List<int>>>。这基本上是具有以下类型签名的函数列表:

List<int> MyFunc(List<int> foo);

然后,您可以将函数列表传递给类似于以下内容的方法:

public List<int> GetAllIds(List<Func<List<int>,List<int>>> functionList) {
    var listOfIds = new List<int>();
    foreach(var f in functionList) {
        listOfIds = f(listOfIds);
    }
    return listOfIds;
}

您可以像使用lambdas一样撰写functionList

functionList.Add(list => {
   list.AddRange(dataManager.GetLoanTranQuotes());
   return list;
});

现在您不必依赖任何特定的继承层次结构。您可以使用函数组合来生成整个列表。