Abstract Factory Vs Factory Method

Many times it seems like factory and factory method pattern are doing the same job. But the evil is hidden in details. Let me show you what I am talking about.

Car Factory Method Story

Consider a factory which is manufacturing cars. It builds different parts of the car such as Door, Steering, Body and Engine etc. Then it puts these parts on to the chassis.

CarFactory

Car factory method class looks like this

 public abstract class CarFactory { protected abstract string BuildSteering(); protected abstract string BuildWheels(); protected abstract string BuildDoors(); public Car BuildCar() { var car = new Car(); car.Steering = BuildSteering(); Console.WriteLine("Steering is {0}",car.Steering); Console.WriteLine("Fit it with Bronze Bolts and Nuts on Chassis"); car.Wheels = BuildWheels(); Console.WriteLine("Wheels are {0}", car.Wheels); Console.WriteLine("Fit it with Bronze Bolts and Nuts on Chassis"); car.Doors = BuildDoors(); Console.WriteLine("Doors are {0}", car.Doors); Console.WriteLine("Fit it with Bronze Bolts and Nuts on Chassis"); return car; } }  

Note that for all cars the parts are connected to chassis in the same way. All parts will be placed and fastened with bolts and nuts.

Company decided to manufacture sports car which has alloy wheels, fiber doors and power steering. All parts are manufactured and sent to assembly line for adding the parts. Now in assembly line same procedure of fitting these parts are followed (which is fastening with bronze bolts and nuts)

SportCar

So Sports car factory looks like

 public class SportsCarFactory : CarFactory { protected override string BuildDoors() { return "Fiber Doors"; } protected override string BuildWheels() { return "Alloy wheels"; } protected override string BuildSteering() { return "Power Steering"; } }

codeTry the code here..

Competitor turned up 😦

Company opened many similar factories with same assembly operations until one day competitor turned up.

Just like competitor, company decided to manufacture the sports cars and commercial cars differently. They feel instead of using bronze bolts and nuts for sports cars, they can use fiber bolts to give speed advantage. Yeah.. sure.. why not.. But what about Commercial cars? They are built with metal body, and they can not take fiber bolts. Errr… Problem 😦

CommercialCar

Why problem? Because you can customize the parts, but can not customize the assembly operations.

 Into New Business with Abstract Factory 🙂

Company realized they need two different assembly operations for manufacturing cars.  But they are still building cars. Now car factory is just an abstraction. It doesn’t dictate any assembly operations.

 public abstract class CarFactory { protected abstract string BuildSteering(); protected abstract string BuildWheels(); protected abstract string BuildDoors(); public abstract Car BuildCar(); }

Now the Sports car factory and commercial car factory look like

 public class SportsCarFactory : CarFactory { protected override string BuildDoors() { return "Fiber Doors"; } protected override string BuildWheels() { return "Alloy wheels"; } protected override string BuildSteering() { return "Power Steering"; } public override Car BuildCar() { var car = new Car(); car.Steering = BuildSteering(); Console.WriteLine("Steering is {0}", car.Steering); Console.WriteLine("Fit it with fiber Bolts and Nuts on Chassis"); car.Wheels = BuildWheels(); Console.WriteLine("Wheels are {0}", car.Wheels); Console.WriteLine("Fit it with fiber Bolts and Nuts on Chassis"); car.Doors = BuildDoors(); Console.WriteLine("Doors are {0}", car.Doors); Console.WriteLine("Fit it with fiber Bolts and Nuts on Chassis"); return car; } } public class CommercialCarFactory : CarFactory { protected override string BuildDoors() { return "Metal Doors"; } protected override string BuildWheels() { return "Alloy wheels"; } protected override string BuildSteering() { return "Power Steering"; } public override Car BuildCar() { var car = new Car(); car.Steering = BuildSteering(); Console.WriteLine("Steering is {0}", car.Steering); Console.WriteLine("Fit it with bronze Bolts and Nuts on Chassis"); car.Wheels = BuildWheels(); Console.WriteLine("Wheels are {0}", car.Wheels); Console.WriteLine("Fit it with bronze Bolts and Nuts on Chassis"); car.Doors = BuildDoors(); Console.WriteLine("Doors are {0}", car.Doors); Console.WriteLine("Fit it with bronze Bolts and Nuts on Chassis"); return car; } } 

codeTry the code here

We turned away from factory method to abstract factory.

Let me know what you guys think.. 🙂

Single Responsibility Principle – I Hate It

I am fond of Single Responsibility Principle.. But as the day passed I developed distaste for this principle. Why? The application I was working on grew with huge number of classes and interfaces. Code seemed like a spaghetti code. I started thinking that this principle instead of solving problems adding more to it. None the less the application became loosely coupled but grew into something that is difficult to understand. I would say the code became less cohesive. entangled wires

But I began realizing that the principle is not wrong, but the way I perceived it was wrong. When single responsibility says there should be one responsibility and one reason for change, the questions are

1. What is going to change?

2. What is the responsibility boundary? Is it class, collection of classes, module, collection of module?

If you take the WCF Service which serves product, is it not that the Product service following single responsibility?. When it changes it changes more for the reason that something related to product changed.

Or lets take an example of Employee detail. In order to display employee detail we go through employee UI, employee business layer, data access layer. Each layer is following SRP.

 If you take the employee detail class, you could have methods like GetJoiningDate, GetRelievingDate, GetPromotedDate, GetSalary, GetIncomeTaxOnSalary. All related to employee and I can argue that the only reason it could change is when I want to modify the employee related rules. That is perfectly normal.

And instead what I did is I over imagined that Dates and Salary are not same thing of an employee. Why not break it into EmployeeSalary and EmployeeChronology? We got 2 classes now. And when I am thinking in-terms of EmployeeSalary I feel that IncomeTax could be calculated annually and monthly. OOpss.. we need another class EmployeeIncomeTax.  Now we got 3 classes. Now employee could be rewarded with bonus. Argh.. Yes we need another class. EmployeeBonus. We made 4 classes. Employee could leave and we need to calculate his settlement and dues.. Ah.. Its a good idea to break it into another class EmployeeSettlement. We got 5 classes. See.. this is what happens when single responsibility boundary is not fixed 🙂

But notice that all these classes in reality are representing behaviors. Does this behavior change more often? Do you think you need to break classes this way where behavior wont change in another 100 years? Design principle says what changes should be kept apart from what doesn’t change.

If its not going to change then I am happy with Employee detail class. If the way the bonus is calculated more often changes , you got to change the logic more often, then move it apart.. How often bonus rules change is the call of the business.

Now easier it is to move the parts apart as long as you maintain unit tests. Otherwise you are on your own when playing something like this.

Thanks for reading.. Let me know your thoughts.