Software Development Tricky

Tuesday 12 September 2017

Abstract Factory Pattern

  • Abstract factory is a creational design pattern, It define an interface which will create families of related or dependents object without the requirement of specifying the exact concrete classes that will be used.
  • This is all about a factory creating various object at run time based on user demand.

    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. The same time company planning to extend the old product category for client satisfaction.  They are planning to extend mobile phone in smart phone & normal phone categories. The same plan to apply new product ((i.e.). laptop) as well. Factory method pattern doesn’t resolve this problem because it involves multiple factories and products which are related to the parent company. To overcome this problem Abstract Factory Pattern come to this place. It allow to create multiple factories & products [(i.e.). products -> product categories -> product sub-categories -> etc…..]

    Sample Demo Diagram:

    UML Diagram:


    Drawbacks:
  • It support new kinds of products is difficult. Extending abstract factories to produce new kinds of Products isn’t easy. That’s because the AbstractFactory interface fixes the set of products that can be created. Supporting new kinds of products requires extending the factory interface, which involves changing the AbstractFactory class and all of its subclasses.
  • It makes exchanging product families easy. The class of a concrete factory appears only once in an application – that is, where it’s instantiated. This makes it easy to change the concrete factory an application uses. It can use different product configurations simply by changing the concrete factory. Because an abstract factory creates a complete family of products, the whole product family changes at once.

Sample Demo Program:

The following participants are involved in given program
  1. AbstractFactory - Declares an interface for operations that create abstract products
  2. ConcreteFactory - Implements the operations to create concrete product objects
  3. AbstractProduct - Declares an interface for a type of product object
  4. Product
                => Defines a product object to be created by the corresponding concrete factory
          => Implements the AbstractProduct interface
  5. Client - This is a class which use AbstractFactory and AbstractProduct interfaces to create a family of related objects
Entire Code Structure:


  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
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
using System;
namespace AbstractFactory_DesignPattern
{
    //AbstractProduct - Main 
    interface IElectronicProduct
    {
        //Common property
        string Name { get; set; }
        string Memory { get; set; }
        string Description { get; set; }

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

    //AbstractProduct - 1
    interface ILaptop : IElectronicProduct
    {
        string WarrantyPeriod { get; set; }
        string ModelDetails { get; set; }
    }

    //AbstractProduct - 2
    interface IMobile : IElectronicProduct
    {
        string WarrantyPeriod { get; set; }
        string ModelDetails { get; set; }
        string PhoneType { get; set; }
    }

    //'AbstractFactory' Interface
    interface IProduct
    {
        ILaptop CreateLaptopProduct(LaptopTypeDetails laptopTypeDetails);
        IMobile CreateMobileProduct(MobileTypeDetails mobileTypeDetails);
    }

    //'Product-1' For Laptop
    class GamingLaptop : ILaptop
    {
        private string _name;
        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }

        private string _memory;
        public string Memory
        {
            get { return _memory; }
            set { _memory = value; }
        }

        public string _description;
        public string Description
        {
            get { return _description; }
            set { _description = value; }
        }

        public string _WarrantyPeriod;
        public string WarrantyPeriod
        {
            get { return _WarrantyPeriod; }
            set { _WarrantyPeriod = value; }
        }

        public string _modelDetails;
        public string ModelDetails
        {
            get { return _modelDetails; }
            set { _modelDetails = value; }
        }

        public string GetMemory()
        {
            return Memory;
        }

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

        public GamingLaptop()
        {
            Name = "HP Omen";
            Memory = "1 TB";
            Description = "It's famous Gaming laptop in india";
            WarrantyPeriod = "1 Year";
            ModelDetails = "HP OMEN Core i5 7th Gen -(16 GB / 1 TB HDD/ 128 GB SSD/ Windows 10 Home / 4 GB Graphics) 15 - ax249TX Gaming Laptop  (15.6 inch, Black)";
        }
    }

    //'Product-2' For Laptop
    class NormalLaptop : ILaptop
    {
        private string _name;
        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }

        private string _memory;
        public string Memory
        {
            get { return _memory; }
            set { _memory = value; }
        }

        public string _description;
        public string Description
        {
            get { return _description; }
            set { _description = value; }
        }

        public string _WarrantyPeriod;
        public string WarrantyPeriod
        {
            get { return _WarrantyPeriod; }
            set { _WarrantyPeriod = value; }
        }

        public string _modelDetails;
        public string ModelDetails
        {
            get { return _modelDetails; }
            set { _modelDetails = value; }
        }

        public string GetMemory()
        {
            return Memory;
        }

        public void SetMemory(int value)
        {
            Memory = string.Format("{0} {1}", value, "TB");
        }
        public NormalLaptop()
        {
            Name = "Dell Inspiration";
            Memory = "2 TB";
            Description = "It's famous Gaming laptop in india";
            WarrantyPeriod = "1.5 Year";
            ModelDetails = "HP OMEN Core i5 7th Gen -(16 GB / 1 TB HDD/ 128 GB SSD/ Windows 10 Home / 4 GB Graphics) 15 - ax249TX Gaming Laptop  (15.6 inch, Black)";
        }
    }

    //'Product-1' For Mobile Phone
    class SmartPhone : IMobile
    {
        private string _name;
        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }

        private string _memory;
        public string Memory
        {
            get { return _memory; }
            set { _memory = value; }
        }

        public string _description;
        public string Description
        {
            get { return _description; }
            set { _description = value; }
        }

        public string _WarrantyPeriod;
        public string WarrantyPeriod
        {
            get { return _WarrantyPeriod; }
            set { _WarrantyPeriod = value; }
        }

        public string _modelDetails;
        public string ModelDetails
        {
            get { return _modelDetails; }
            set { _modelDetails = value; }
        }

        //GSM or CDMA
        public string _phoneType;
        public string PhoneType
        {
            get { return _phoneType; }
            set { _phoneType = value; }
        }

        public string GetMemory()
        {
            return Memory;
        }

        public void SetMemory(int value)
        {
            Memory = string.Format("{0} {1}", value, "GB");
        }
        public SmartPhone()
        {
            Name = "Lenovo Vibe K5 Note";
            Memory = "8 GB";
            Description = "It's famous Smart Phone in india";
            WarrantyPeriod = "2 Year";
            ModelDetails = "Lenovo Vibe K5 Note (Gold, 32 GB)  (3 GB RAM)";
            PhoneType = "GSM";
        }
    }

    //'Product-2' For Mobile Phone
    class NormalPhone : IMobile
    {
        private string _name;
        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }

        private string _memory;
        public string Memory
        {
            get { return _memory; }
            set { _memory = value; }
        }

        public string _description;
        public string Description
        {
            get { return _description; }
            set { _description = value; }
        }

        public string _WarrantyPeriod;
        public string WarrantyPeriod
        {
            get { return _WarrantyPeriod; }
            set { _WarrantyPeriod = value; }
        }

        public string _modelDetails;
        public string ModelDetails
        {
            get { return _modelDetails; }
            set { _modelDetails = value; }
        }

        //GSM or CDMA
        public string _phoneType;
        public string PhoneType
        {
            get { return _phoneType; }
            set { _phoneType = value; }
        }

        public string GetMemory()
        {
            return Memory;
        }

        public void SetMemory(int value)
        {
            Memory = string.Format("{0} {1}", value, "MB");
        }
        public NormalPhone()
        {
            Name = "Nokia 1600 ";
            Memory = "256 MB";
            Description = "It's famous Normal Phone in india";
            WarrantyPeriod = "1 Year";
            ModelDetails = "REBOXED Nokia 1600 256 MB Black RAM";
            PhoneType = "CDMA";
        }
    }

    
    //'ConcreteFactory' class
    class ElectronicProduct : IProduct
    {
        //'Maintain ConcreteFactory-1'
        public ILaptop CreateLaptopProduct(LaptopTypeDetails laptopTypeDetails)
        {
            switch(laptopTypeDetails)
            {
                case LaptopTypeDetails.Gaming:
                    return new GamingLaptop();
                case LaptopTypeDetails.Normal:
                    return new NormalLaptop();
                default:
                    throw new ApplicationException((LaptopTypeDetails.Gaming == laptopTypeDetails) ? "Gaming" : "Normal"  + "type can not be created");
            }
        }

        //'Maintain ConcreteFactory-2'
        public IMobile CreateMobileProduct(MobileTypeDetails mobileTypeDetails)
        {
            switch (mobileTypeDetails)
            {
                case MobileTypeDetails.Smart:
                    return new SmartPhone();
                case MobileTypeDetails.Normal:
                    return new NormalPhone();
                default:
                    throw new ApplicationException((MobileTypeDetails.Smart == mobileTypeDetails) ? "Smart" : "Normal" + "type can not be created");
            }
        }

    }

    //'Client' Class
    class Product
    {
        public Product()
        {
            Console.WriteLine("Creating Product Factory");
        }

        //maintain laptop products
        public ILaptop LaptopProduct(IProduct Product, LaptopTypeDetails laptopTypeDetails)
        {
            return Product.CreateLaptopProduct(laptopTypeDetails);
        }

        //maintain mobile products
        public IMobile MobileProduct(IProduct Product, MobileTypeDetails mobileTypeDetails)
        {
            return Product.CreateMobileProduct(mobileTypeDetails);
        }
    }

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

    enum LaptopTypeDetails
    {
        Gaming,
        Normal
    }

    enum MobileTypeDetails
    {
        Smart,
        Normal
    }

    //main class act as 'Client'
    class Program
    {
        static void Main(string[] args)
        {
            IProduct electronicProduct = new ElectronicProduct();
            Product product = new Product();

            //-------------------------Laptop product----------------------------------------------
            Console.WriteLine("------------------------------------------Laptop Products------------------------------------------");
            foreach (LaptopTypeDetails laptopTypeDetail in Enum.GetValues(typeof(LaptopTypeDetails)))
            {
                var laptopProduct = product.LaptopProduct(electronicProduct, laptopTypeDetail);
                Console.WriteLine("------------------------------------------{0} Laptop------------------------------------------", laptopTypeDetail.ToString());
                Console.WriteLine("Name: {0}, Memory: {1}, Description: {2}, Available Memory: {3}, Contract Period: {4}, Model Details: {5} "
                    , laptopProduct.Name, laptopProduct.Memory, laptopProduct.Description, laptopProduct.GetMemory(), laptopProduct.WarrantyPeriod
                    , laptopProduct.ModelDetails);
                Console.WriteLine("Do you want to reset {0} memory?", laptopProduct.Name);
                Console.Write("Press 1 to reset memory: ");
                if (Convert.ToInt32(Console.ReadLine()) == 1)
                {
                    Console.Write("Enter Memory Capacity: ");
                    laptopProduct.SetMemory(Convert.ToInt32(Console.ReadLine()));
                    Console.WriteLine("Current Reset Memory Value: {0}", laptopProduct.GetMemory());
                }
            }

            //-------------------------Mobile product----------------------------------------------
            Console.WriteLine("------------------------------------------Mobile Phone Products------------------------------------------");
            foreach (MobileTypeDetails mobileTypeDetail in Enum.GetValues(typeof(MobileTypeDetails)))
            {
                var mobileProduct = product.MobileProduct(electronicProduct, mobileTypeDetail);
                Console.WriteLine("------------------------------------------{0} Phone------------------------------------------", mobileTypeDetail.ToString());
                Console.WriteLine("Name: {0}, Memory: {1}, Description: {2}, Available Memory: {3}, Contract Period: {4}, Model Details: {5}, Phone Type: {6} "
                    , mobileProduct.Name, mobileProduct.Memory, mobileProduct.Description, mobileProduct.GetMemory(), mobileProduct.WarrantyPeriod
                    , mobileProduct.ModelDetails, mobileProduct.PhoneType);
                Console.WriteLine("Do you want to reset {0} memory?", mobileProduct.Name);
                Console.Write("Press 1 to reset memory: ");
                if (Convert.ToInt32(Console.ReadLine()) == 1)
                {
                    Console.Write("Enter Memory Capacity: ");
                    mobileProduct.SetMemory(Convert.ToInt32(Console.ReadLine()));
                    Console.WriteLine("Current Reset Memory Value: {0}", mobileProduct.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