Software Development Tricky

Thursday, 7 September 2017

Factory Method Pattern

  • Factory Method is creational design pattern that provides an interface for creating object in superclass, but allow subclasses to alter the type of object that will be created. In other words, subclasses are responsible to create the instance of the class.

    Examples:
    Consider you are creating electronic product management application. The first version of your application can handle only mobile phone, so the bulk of your code lives in a mobile phone class.

    After a while, your application becomes so popular that you get huge request to include laptop as well.

    It’s good but how about the code? It looks that most of your code is coupled to the mobile phone class. Adding laptop would require making changes to the entire code base. Moreover, if you decide to add another type of electronic product to the application, you will probably need to make all of those change again. To overcome this problem factory method pattern come to this place. It allow the sub classes to choose type object to create ((i.e.). mobile, laptop, mp3player object ete….). Our parent ((i.e.). Electronics Manufacturing Company) class hold common property & behaviour ((i.e.). [Property: Name, Memory, Description] [Behaviour: GetMemroy(), SetMemory() etc…])
Sample Demo Diagram:

UML Diagram:



Drawbacks:

It provides a simple way of extending the family of products with minor changes in application code.

It provides customization hooks, when the objects are created directly inside the class, it’s hard to replace them by objects which extend their functionality.

Sample Demo Program:

The following participants are involved in given program
1)      IProduct – The Interface for the concrete product
2)      Concrete Product – Class type that provides Concrete implementation of IProduct Interface
3)      Creator – Abstract class that provides FactoryMethod
4)      ConcreteCreator – Class that will implement abstract method FactoryMethod
5)      FactoryMethod – Method will decide which class will instantiate

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
using System;
namespace FactoryMethod_DesignPattern
{
    //'Creator' abstract class
    abstract class ElectronicProduct
    {
        //Common property
        public string Name { get; set; }
        public string Memory { get; set; }
        public string Description { get; set; }

        //Common Method / Function / Behaviour
        public abstract string GetMemory();
        public abstract void SetMemory(int value);
    }
    

    //'ConcreteProduct' Class
    class MobilePhone : ElectronicProduct
    {
        public MobilePhone()
        {
            Name = "Nokia";
            Memory = "8 GB";
            Description = "It's famous mobile phone in india";
        }
        //GSM or CDMA
        public string PhoneType { get; set; }

        public override string GetMemory()
        {
            return Memory;
        }

        public override void SetMemory(int value)
        {
            Memory = string.Format("{0} {1}", value, "GB");
        }
    }

    //'ConcreteProduct' Class
    class Laptop : ElectronicProduct
    {
        public Laptop()
        {
            Name = "Lenovo";
            Memory = "500 GB";
            Description = "It's famous labtop in india";
        }
        //DualCore or MultiCore
        public string ProcessorType { get; set; }

        public override string GetMemory()
        {
            return Memory;
        }

        public override void SetMemory(int value)
        {
            Memory = string.Format("{0} {1}", value, "GB");
        }
    }

    //'ConcreteProduct' Class
    class ExternalHardDrive : ElectronicProduct
    {
        public ExternalHardDrive()
        {
            Name = "Dell";
            Memory = "1 TB";
            Description = "It's famous External Hard Drive in india";
        }
        //SSD or HDD (Solid State Drive OR Hard Disk Drive)
        public string Type { get; set; }

        public override string GetMemory()
        {
            return Memory;
        }

        public override void SetMemory(int value)
        {
            Memory = string.Format("{0} {1}", value, "TB");
        }
    }

    //'ConcreteProduct' Class
    class GenericProduct : ElectronicProduct
    {
        //TODO
        public override string GetMemory()
        {
            throw new NotImplementedException();
        }

        public override void SetMemory(int value)
        {
            throw new NotImplementedException();
        }
    }

    //'IProduct' Interface
    interface IProductFactory
    {
        ElectronicProduct CreateProduct(ProductDetails productDetails);
    }

    //'Concrete Creator' Class
    class ProductFactory : IProductFactory
    {
        public ProductFactory()
        {
            Console.WriteLine("Creating Product Factory");
        }

        //'Factory Method' to decide which class instantiate
        public ElectronicProduct CreateProduct(ProductDetails productDetails)
        {
            switch (productDetails)
            {
                case ProductDetails.MobilePhone:
                    return new MobilePhone();
                case ProductDetails.Laptop:
                    return new Laptop();
                case ProductDetails.ExternalHardDrive:
                    return new ExternalHardDrive();

                default:
                    return new GenericProduct();
            }
        }

    }

    //Different product that can be created by the factory
    enum ProductDetails
    {
        MobilePhone,
        Laptop,
        ExternalHardDrive
    }

    //main class act as 'Client'
    class Program
    {
        static void Main(string[] args)
        {
            ProductFactory factory = new ProductFactory();
            ElectronicProduct product;
            foreach (ProductDetails prodDetail in Enum.GetValues(typeof(ProductDetails)))
            {
                product = factory.CreateProduct(prodDetail);
                Console.WriteLine("Name: {0}, Memory: {1}, Description: {2}, Available Memory: {3}", product.Name, product.Memory, product.Description, product.GetMemory());
                Console.WriteLine("Do you want to reset {0} memory?", product.Name);
                Console.Write("Press 1 to reset memory: ");
                if (Convert.ToInt32(Console.ReadLine()) == 1)
                {
                    Console.Write("Enter Memory Capacity: ");
                    product.SetMemory(Convert.ToInt32(Console.ReadLine()));
                }
                Console.WriteLine("Current Reset Memory Value: {0}", product.GetMemory());
            }
            Console.WriteLine("Press any key to exit");
            Console.ReadLine();
        }
    }
}

Final output:



Click here to download sample program

If you like this post. Kindly share your valuable comments.

No comments:

Post a Comment

Followers