Как мне разделить большие и раздутые классы на более мелкие? - PullRequest
3 голосов
/ 30 сентября 2008

У меня есть большой класс «Менеджер», который, я думаю, делает слишком много, но я не уверен, как разделить его на более логичные единицы.

Вообще говоря, класс в основном состоит из следующих методов:

class FooBarManager
{
  GetFooEntities();
  AddFooEntity(..);
  UpdateFooEntity(..);
  SubmitFooEntity(..);
  GetFooTypes();
  GetBarEntities();
}

Класс Manager является частью моей бизнес-логики и содержит экземпляр другого класса "Manager" на уровне доступа к данным, который содержит все операции CRUD для всех объектов.

У меня есть разные сущности, поступающие со слоя доступа к данным, и поэтому у меня есть преобразователь вне класса Manager для преобразования сущностей данных в бизнес-сущности.

Причиной для классов менеджера было то, что я хотел иметь возможность смоделировать каждый из классов "Менеджера", когда я выполняю тестирование модулей. Каждый из классов менеджера теперь более 1000 loc и содержит 40-50 методов каждый. Я считаю их довольно раздутыми, и мне неудобно помещать всю логику доступа к данным в один класс. Что я должен делать по-другому?

Как мне их разделить, и есть ли какой-то конкретный шаблон дизайна, который я должен использовать?

Ответы [ 4 ]

1 голос
/ 30 сентября 2008

Ваш FooBarManager очень похож на объект Бога анти-паттерн.

В ситуации, подобной вашей, рассмотрите вопрос о шаблонах архитектуры корпоративных приложений . Автор Martin Fowler На первый взгляд кажется, что вы хотите создать Data Mapper . Но рассмотрите альтернативы, такие как Active Record s, которых может быть достаточно для ваших нужд.

Также рассмотрите возможность использования библиотеки ORM для вашей платформы. Создание собственного без веской причины только столкнет вас со многими проблемами, которые уже были более или менее решены с помощью этих инструментов.

1 голос
/ 30 сентября 2008

Вы действительно не должны помещать весь доступ к данным в один класс, если он не является общим. Я бы начал с того, что разделил ваши классы доступа к данным на одного менеджера для каждого объекта или связанных групп объектов, например CompanyManager, CustomerManager и т. Д. Если вам нужен доступ к менеджеру через один «класс Бога», вы можете иметь экземпляр каждого менеджера в наличии в вашем единственном истинном классе менеджера.

0 голосов
/ 30 сентября 2008

Я бы предложил использовать композицию. Подумайте о функциях, которые выполняет менеджер. Разделите их по принципу единой ответственности. Похоже, большая часть FooBarManager представляет собой набор сущностей Foo и bar. Итак, как минимум, вырвите логику сбора из FooBarManager

public class EntityCollection<T> : IList<T> 
 where T : BaseEntity
{ /* all management logic here */}
public class FooCollection : EntityCollection<foo> {}
public class BarCollection : EntityCollection<bar> {}
public class FooBarManager 
{ 
public FooCollection { /*...*/ } 
public BarCollection { /*...*/ } 
public FooBarManager() : this(new FooCollection(), new BarCollection()){}
public FooBarManager(FooCollection fc, BarCollection bc) { /*...*/ } 
}
0 голосов
/ 30 сентября 2008
       / FooManager
Manager                  (derive from Manager)
       \ BarManager

Должен быть самоочевидным

...