In this article we will create an ASP.Net application using Abstract Factory Pattern.

Agenda

Previous Articles

  1. Design Patterns: Introduction
  2. Learn Design Pattern - Singleton Pattern
  3. Learn Design Pattern - Factory Method Pattern

What is Abstract Design Pattern?

Why and When to extend Factory method to Abstract Factory Pattern?

If you haven't read Factory Method Pattern please go through it first.

Let's consider the same example we used for the Factory method pattern.
There we had a class called CustomerFactory which creates various customers according to input it gets.

Now the Company decides to extend the application and they say, all customers belonging to a specified country (country 1) and who are of Grade1 get a 200 Rs discount and Grade2 customers belonging to another country (country 2) get a discount of 100Rs, and remaining ____.

So the CustomerFactory ends up with a code which looks like this:

  1. public IBaseCustomer GetCustomer(string CustomerType, string Country)
  2. {
  3. switch (CustomerType)
  4. {
  5. case "1":
  6. switch (Country)
  7. {
  8. case "Country1":
  9. {
  10. IBaseCustomer c = new Grade1Customer();
  11. c.DiscountAmount = 200;
  12. return c;
  13. }
  14. default:
  15. {
  16. IBaseCustomer c = new Grade1Customer();
  17. c.DiscountAmount = 0;
  18. return c;
  19. }
  20. }
  21. case "2":
  22. switch (Country)
  23. {
  24. case "Country2":
  25. {
  26. IBaseCustomer c = new Grade2Customer();
  27. c.DiscountAmount = 100;
  28. return c;
  29. }
  30. default:
  31. {
  32. IBaseCustomer c = new Grade1Customer();
  33. c.DiscountAmount = 0;
  34. return c;
  35. }
  36. }
  37. default:
  38. {
  39. IBaseCustomer c = new Grade1Customer();
  40. c.DiscountAmount = 0;
  41. return c;
  42. }
  43. }
  44. }

Client Code

  1. CustomerFactory factory=new CustomerFactory();
  2. IBaseCustomer c= factory. GetCustomer("1","Country1");
  3. c.getAmount()//display;
Problem

Abstract Factory Pattern as the solution

Here a higher level factory is created which will act as a factory for other factories and those factories will create the final concrete classes as per specifications.

The Components involved in the Abstarct Factory Method Pattern are:

Let's modify the previous code.

Output

Abstract-Factory-Pattern-output.jpg

Step 1

Create a Base Factory or we can ____ Factory of Factories called CustomerFactory; see:

  1. public class CustomerFactory
  2. {
  3. }
Step 2

Create a static method which will create more factories as per requirements; see:
  1. public static CustomerFactory GetCustomerFactory(string Country)
  2. {
  3. switch (Country)
  4. {
  5. case "Country1":
  6. {
  7. return new Country1Factory();
  8. }
  9. case "Country2":
  10. {
  11. return new Country2Factory();
  12. }
  13. default:
  14. {
  15. return new CustomerFactory();//Returning itself for Default
  16. }
  17. }
  18. }

Step 3

Add a virtual method inside the CustomerFactory for creating final concrete classes; see:

  1. public virtual IBaseCustomer GetCustomer(string CustomerType)
  2. {
  3. switch (CustomerType)
  4. {
  5. case "1":
  6. Grade1Customer c1 = new Grade1Customer();
  7. c1.DiscountAmount = 0;
  8. return c1;
  9. case "2":
  10. Grade2Customer c2 = new Grade2Customer();
  11. c2.DiscountAmount = 0;
  12. return c2;
  13. default:
  14. return null;
  15. }
  16. }
Step 4

Define concrete factories, and inherit them from base factories i.e, from CustomerFactory; see:

  1. CustomerFactory
  2. public class Country1Factory : CustomerFactory
  3. {
  4. }
  5. public class Country2Factory : CustomerFactory
  6. {
  7. }
Step 5

Override virtual methods in concrete factories according to requirements and return final concrete classes; see:

  1. public override IBaseCustomer GetCustomer(string CustomerType)
  2. {
  3. switch(CustomerType)
  4. {
  5. case "1":
  6. Grade1Customer c1 = new Grade1Customer();
  7. c1.DiscountAmount = 200;
  8. return c1;
  9. case "2":
  10. Grade2Customer c2 = new Grade2Customer();
  11. c2.DiscountAmount = 0;
  12. return c2;
  13. default:
  14. return null;
  15. }
  16. }

Step 6

Write Client Code

  1. CustomerFactory objFactory = CustomerFactory.GetCustomerFactory(DdlCountry.SelectedValue);
  2. IBaseCustomer objCustomer = objFactory.GetCustomer(DdlGrade.SelectedValue);
  3. objCustomer.CustomerName = TxtName.Text;
  4. objCustomer.Amount = int.Parse(TxtAmount.Text);
  5. Response.Write("Welcome " + TxtName.Text + ", Your toal unpaid amount is " + objCustomer.GetTotalAmount().ToString());
Class Diagram

Abstact Factory pattern.png


We are done with the third creation pattern, please download the attached zip file for the complete source code.

Hope you enjoyed. Keep reading and comments are always welcome.