How do I split large and bloated classes into smaller ones?

I have a large "Manager" class, which I think is too much, but I'm not sure how to divide it into more logical units.

In general, a class consists mainly of the following methods:

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

The Manager class is part of my business logic and is an instance of another Manager class at the data access level that contains all CRUD operations for all objects.

I have different objects coming from the data access level and, therefore, I have a converter outside the Manager class to convert data objects to business objects.

The reason for the manager classes was because I wanted to be able to mock each of the "Manager" classes when I did unittesting. Each of the manager classes now exceeds 1000 loc and contains 40-50 methods. I believe that they are quite bloated and find it inconvenient to put all the data access logic in one class. What should I do differently?

How can I separate them and is there any specific design pattern I should use?

+3
source share
4 answers

You really should not put all data access in one class, unless it is shared. I would like to start by splitting the data access classes into one manager per object or related groups of objects, i.e. with CompanyManager, CustomerManager, etc. If you need to access the manager through one “god class”, you can have an instance of each manager in your true Manager class.

+1
source

Your FooBarManager very similar to a God Object .

In a situation like yours, consider how to turn to Martin Fowler's “Enterprise Application Architecture Templates” . At first glance, it looks like you want to create a Data Mapper . But consider alternatives, such as Active Record s, that might be enough for your needs.

Also consider using the ORM library / software for your platform. Building your own without a good reason will only confront you with many problems that have already been more or less solved by these tools.

+1
source
  / FooManager Manager (derive from Manager) \ BarManager 

Must be self-evident

0
source

I would suggest using composition. Think about what functions the manager performs. Divide them into lines of shared responsibility. Most FooBarManager seems to be a collection of Foo and bar objects. So, at a minimum, wrest the collection logic from 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
source

Source: https://habr.com/ru/post/987585/


All Articles