tags:

views:

230

answers:

4

I have a large 'Manager' class which I think is doing too much but I am unsure on how to divide it into more logical units.

Generally speaking the class basically consists of the following methods:

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

The Manager class is part of my business logic and constains an instance of another "Manager" class on the data access level which contains all CRUD operations for all entities.

I have different entities coming from the data access layer and therefore have a converter in place outside of the Manager class to convert data entities to business entities.

The reason for the manager classes was that I wanted to be able to mock out each of the "Manager" classes when I do unittesting. Each of the manager classes is now over 1000 loc and contain 40-50 methods each. I consider them to be quite bloated and find it awkward to put all of the data access logic into a single class. What should I be doing differently?

How would I go about splitting them and is there any specific design-pattern should I be using?

+1  A: 

You really shouldn't put all data access into one class unless it's generic. I would start by splitting out your data access classes into one manager per object or related groups of objects, i.e. CompanyManager, CustomerManager, etc. If your need to access the manager through one "god class" you could have an instance of each manager available in your one true Manager class.

Jamie Ide
Ok sounds logical but how would you go about it in the xManager in the business layer where you need to get all orders for a customer? would you have reference to both CustomerManager as well as OrderManager and when getting a customer call get orders for that customer? seems like alot of managers?
Xerx
Given what you have now, that's how I would do it. Think about which entity is responsible for the operation -- you wouldn't ask a real Customer to give you a list of their orders, you'd ask your Order system to give you a list of orders for a customer.
Jamie Ide
I would +1 this if you had added a note about Manager classes being a bad idea...
metao
How so? The original question wasn't asking for a DDD best practices tutorial, it was asking how to refactor existing code into something more manageable.
Jamie Ide
A: 
       / FooManager
Manager                  (derive from Manager)
       \ BarManager

Should be self-explaining

daddz
This is definately not what I was looking for as FooManager and BarManager are really independent and do not derive from some abstract class. -1
Xerx
A: 

I'd suggest using composition. Think about the functions the manager is doing. Split them along the lines of single responsibility. It appears most of FooBarManager is a collection of Foo and bar entities. So, at a minimum, break out 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) { /*...*/ } 
}
Will
+1  A: 

Your FooBarManager looks a lot like a God Object anti pattern.

In a situation like yours, consider delving into Patterns of Enterprise Application Architecture, by Martin Fowler. At first sight, it looks like you want to create a Data Mapper. But consider alternatives like Active Records, that might be enough for your needs.

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

Mac