Рефакторинг на подклассы - PullRequest
2 голосов
/ 16 января 2012
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() метода, который представляет его специфичноquery.

То, что вы видите выше, это базовый класс, который у меня есть.Я сделал эти два метода virtual, так как планирую переопределить их подклассами для выполнения своих собственных задач.Таким образом, может быть что-то вроде:

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

и т. Д. Мой вопрос в том, является ли это наилучшим / самым чистым способом выполнения шаблона, подобного этому?

Код, который вызывает это, собираетсясодержит огромный список отфильтрованных идентификаторов, которые необходимо заполнить, вызывая каждый вызов классов GetTranQuotesToFillRatesAndPayments().Дайте мне знать, если это не имеет смысла.Я как бы отвлекаюсь на тот факт, что мне нужно будет вызывать один и тот же метод, как 6 раз, каждый в своем классе.Я думаю, что это может быть грязно само по себе, хотя цель этого состояла в том, чтобы сделать его чистым.Я не хочу, чтобы на вызывающей стороне было что-то подобное:

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

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

и т. Д.

Дайте мне знать, если вам нужно больше информации или информации.

Спасибо.

Ответы [ 2 ]

2 голосов
/ 16 января 2012

Несколько замечаний по дизайну:

  1. Использование ключевого слова ref обычно указывает на проблемы проектирования и его следует избегать.Нет необходимости передавать ссылочное значение с помощью ключевого слова ref (любое List<T> всегда передается по ссылке).Ваша программа будет работать одинаково без него.

  2. Лучшей идеей, чем передача списка в метод, было бы вернуть ваши данные из метода и позволить вызывающимрешить, что с этим делать.Возможно, вы захотите найти только одно значение в каком-то другом месте в вашей программе, и создание нового списка - это излишнее количество.Кроме того, вы должны попытаться добавить как можно меньше функциональности для каждого класса ( Принцип единой ответственности ), и ваш класс сейчас отвечает за выборку данных и , решая, как это должно бытьсохранен.

  3. Именование: имя вашего метода действительно сложное.Кроме того, имя «контроллер» обычно не представляет объект, ответственный за выборку данных.

  4. С другой стороны, у вас есть класс CoreDataManager ( кстати, Managerплохой суффикс для любого класса ), который, похоже, содержит набор методов, которые возвращают различные данные.Зачем тогда нужно ScheduleRatesController?Копирует ли это только в список?

  5. Бизнес-логика должна быть отделена от уровня доступа к данным.Вам следует рассмотреть возможность использования шаблона репозитория или аналогичного (например, отметьте этот ответ ), чтобы ваш класс данных только извлекал данные из БД.

Если у вас есть несколько классов, которым необходимо выполнить определенный контракт , начните с создания интерфейса , который они должны реализовать.Не думайте о повторном использовании кода в это время.Например, ваш код заставляет все подклассы использовать CoreDataManager, в то время как однажды может оказаться, что определенный «контроллер» может состоять из разных объектов.

0 голосов
/ 16 января 2012

Используйте 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;
}

Вы можетеиспользуйте лямбды для составления functionList примерно так:

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

Теперь вам не нужно зависеть от какой-либо конкретной иерархии наследования.Вы можете использовать композицию функций для создания всего списка.

...