Solved

Factory Method

Posted on 2010-08-25
10
682 Views
Last Modified: 2013-12-17
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Avacados
{

    class FactoryPattern
    {

        // Factory Method Pattern Judith Bishop 2006
        //  Example of exporting from different suppliers

        interface IProduct
        {
            string ShipFrom();
        }

        class ProductA : IProduct
        {
            public String ShipFrom()
            {
                return " from South Africa";
            }
        }

        class ProductB : IProduct
        {
            public String ShipFrom()
            {
                return "from Spain";
            }
        }

        class ProductC : IProduct
        {
            public String ShipFrom()
            {
                return "from India";
            }
        }


        class DefaultProduct : IProduct
        {
            public String ShipFrom()
            {
                return "not available";
            }
        }

        class Creator
        {
            public IProduct FactoryMethod(int month)
            {
                if (month >= 4 && month <= 11)
                    return new ProductA();
                else
                    if (month == 1 || month == 2 || month == 12)
                        return new ProductB();
                    else
                        return new DefaultProduct();
            }
        }

        static void Main()
        {
            Creator c = new Creator();
            IProduct product;

            for (int i = 1; i <= 12; i++)
            {
                product = c.FactoryMethod(i);
                Console.WriteLine("Avocados " + product.ShipFrom());
            }
        }
    }
}

Open in new window


I heard the  in factory pattern client is not aware of  concerate classes( Product A, Product B). So here in this example.

In the client the Creator class gets the reference of concerate Classes( Product A, Product B)
// Creator c = new Creator();

//   product = c.FactoryMethod(i);    So  Creator object is  getting reference of  con cerate classes and assigning to Interface. Therefore client  is getting  reference of concreate classes

 that means  client is aware of concereate classes  .

But definition of factroy method says that client is not ware of concerate classes.

Suppose if I add one more concereate classes Product C . Will the client will be aware of it or not. If not why ?





0
Comment
Question by:N_Sri
  • 2
  • 2
  • 2
  • +4
10 Comments
 
LVL 52

Expert Comment

by:Carl Tawn
Comment Utility
It's not aware of it as such. All it is aware of is that is has an object that implements the IProduct interface, rather than knowing specifically which type of concrete class it has a reference to.
0
 
LVL 5

Expert Comment

by:greatsubash
Comment Utility
0
 

Expert Comment

by:cyberwar81
Comment Utility
Client is not aware of the concrete class, client is only aware that the class refrence it is getting implements IProduct interface. and It supports all the methods that are defined in interface.

Tomorrow if you want to add one more concrete class, you just have to implement IProduct interface and change the value of month variable, rest of your client code remains same.

In typical use case the month value passed here is read from configuration file, so that you dont need to change the client code at all, just change the month value in configuration file, and it gets the concrete class corresponding to that.
0
 
LVL 18

Expert Comment

by:Richard Lee
Comment Utility
The client is not aware of the concrete class that the factory is responsible for creating. The client is aware of the factory itself as shown by your example.

Within any application, no matter how many abstractions you have there must be a concrete class somewhere otherwise how would your application work?

You can also use a factory that is a static class. See sample.

DaTribe
interface IProduct {}

class ProductA : IProduct {}
class ProductB : IProduct {}

static class ProductFactory {
   IProduct GetProduct(int month)
   {
      IProduct product;

      // ... do something

      return product;
   }
}

class Client
{
   void DoSomething {
      var product = ProductFactory.GetProduct(1);
   }
}

Open in new window

0
 
LVL 12

Accepted Solution

by:
w00te earned 500 total points
Comment Utility
Honestly, I think you're getting a little too tied up in the semantics of the pattern.  The basic function of a factory pattern is to decouple object creation from the purpose of the actual object itself.
A class exists to serve a certain purpose, and you create all of the data members and function members to allow it to do so.  It is the case with some classes though that the actual creation of the class is so complex and requires so many operations that it reduces the clarity of purpose for the class.  The bulk of the code and logic in the class should be there to make the class fulfill its purpose, not to create it in the first place.
So... the idea is that your class itself shouldn't need to know how it is created, that work is delegated to the factory.  
1-Your factory should be a static class.
2-It should return an interface object.
3-The set of objects the factory is capable of creating should all implement the interface from #2.
From this point on, your factory knows about all of the classes it can create, and any new classes you add must be made to implement your interface and must be incorporated into the factory logic.
Your main code will use the static factory and will ONLY know about the interface, and thus it is completely decoupled from the internal workings of those classes and their creation.  The various subclasses should all implement overrides fo the same functions as specified in the interface so the interface can properly and completely control them.
If you (truely) need to do so, you can actually cast the interface into the real object type it represents in some conditions, but this is pretty frowned upon as it somewhat breaks the pattern.  Having said that, a pattern is there to aid you, not restrict you, so there are exceptions to every rule :)
-w00te
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 

Author Comment

by:N_Sri
Comment Utility
That means  client will be aware of  Interface and its method. Suppose if we add new method  in Interface ,
We should notify the client there is a new method also right?

 
0
 
LVL 52

Expert Comment

by:Carl Tawn
Comment Utility
It depends what you mean by "notify the client". If the client implements the interface then it will know precisely what methods the interface exposes.
0
 
LVL 12

Expert Comment

by:w00te
Comment Utility
The client is just your main code... you can call any functions the interface implements.  From the client's point of view, if theres a function call in the interface then the client can use it, if it's not in the interface then it doesn't exist.  You don't need to do anything special to tell the client about the function... you're coding the client.  Just insert the function call for any function you add to the interface that you wish to actually use.
It's no different than adding a function to any class and using it except that in order to make it work you have to appropriately overload it in the derived classes.
0
 
LVL 4

Expert Comment

by:avarmaavarma
Comment Utility
>>That means  client will be aware of  Interface and its method. Suppose if we add new method  in Interface ,
>>We should notify the client there is a new method also right?

While interfaces are an extremely flexible way to provide 'de-coupling' or loose coupling, there is one major disadvantage of using interfaces. You have hit it on the head - if you add a new method to the interface (or rename an existing one), all your clients implementing the interface will need to change. The way this is avoided in modern-day languages (c#, java..) is by introducing a second interface to contain the new method(s) or the renamed methods. Then, you have the option of having all those clients interested in the new method(s) simply implement Interface2 - other clients that are not interested can remain unchanged.

An alternative to using interfaces in a factory is to use AbstractClasses - to get what is known as an  AbstractFactory. The reason an Abstract class works better (than interfaces) in this factory scenario is because you can add new methods (or rename existing methods) in an Abstract Class without breaking any of the clients. A big win for Abstract Classes over interfaces. However, it is pattern dependent - in this case (factory), the Abstract class wins - but in a lot of other scenarios, interfaces would be a better choice.
0
 
LVL 4

Expert Comment

by:avarmaavarma
Comment Utility
I meant to provide you with a link to a useful diagram of an AbstractFactory (different from a regular Factory pattern)

http://www.dofactory.com/Patterns/PatternAbstract.aspx
0

Featured Post

What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

Join & Write a Comment

Entity Framework is a powerful tool to help you interact with the DataBase but still doesn't help much when we have a Stored Procedure that returns more than one resultset. The solution takes some of out-of-the-box thinking; read on!
Exception Handling is in the core of any application that is able to dignify its name. In this article, I'll guide you through the process of writing a DRY (Don't Repeat Yourself) Exception Handling mechanism, using Aspect Oriented Programming.
In this seventh video of the Xpdf series, we discuss and demonstrate the PDFfonts utility, which lists all the fonts used in a PDF file. It does this via a command line interface, making it suitable for use in programs, scripts, batch files — any pl…
In this tutorial you'll learn about bandwidth monitoring with flows and packet sniffing with our network monitoring solution PRTG Network Monitor (https://www.paessler.com/prtg). If you're interested in additional methods for monitoring bandwidt…

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now