0

What is the main meaning of using Factory Pattern?

  • At the beginning we have a Simple Factory
class FanFactory : IFanFactory { public IFan CreateFan(FanType type) { switch (type) { case FanType.TableFan: return new TableFan(); case FanType.CeilingFan: return new CeilingFan(); case FanType.ExhaustFan: return new ExhaustFan(); default: return new TableFan(); } } } 

Although it violates the Principle of SOLID, it seems logical. Using one factory object I can create any other.

  • Factory method
static void Main(string[] args) { IFanFactory fanFactory = new PropellerFanFactory(); IFan fan = fanFactory.CreateFan(); fan.SwitchOn(); Console.ReadLine(); } 

In this case, I could do as well:

IFan fan = new PropellerFan(); fan.SwitchOn(); 

What was the purpose of Factory Method? You can not see the simplification of the code in it. If we use inheritance in classes and in a child we add a method other than in the parent, then everything loses meaning.

Link to examples

13
  • 1
    Sometimes you don´t even have access to PropellerFan (or don´t want it to be bound to that type at compile-time). There are many reasons to use dependecy-injection. Commented Feb 25, 2019 at 10:30
  • See this question for example: softwareengineering.stackexchange.com/questions/253254/… Commented Feb 25, 2019 at 10:31
  • 1
    Your code should also make no assumption abnout the factory being used. The factory should also be injected to that code. You may have a look at dependency-injection. Anyway: why do you say that a factory breaks SOLID? Commented Feb 25, 2019 at 10:44
  • 1
    With the factory pattern you can create a fan of a particular type at run-time, your example with IFan fan needs to know already at compile time which type it should instantiate as well have access to the type, with a factory pattern the actual data type is hidden and you talk to the instances via an interface, not the data type itself. Commented Feb 25, 2019 at 10:49
  • 1
    Which rule specifically you refer to? I can´t see how the factory breaks any of them. Commented Feb 25, 2019 at 10:50

2 Answers 2

3

Factory pattern allows:

  • replace class constructors. So you can use IoC(Inversion Of Control)
  • If your application use IoC, then you can easily write Unit Tests. As your code is loosely coupled
  • postpone instantiation of a concrete implementation of class. So type of class can be determined at run-time.

For example:

public YourClass(IYourDependency dep) { } 

Then you can use your factory to create a dependency:

var dep = new FanFactory.CreateFan(...)// An example of IoC var cl = new YourClass(dep); 

And then you can mock your dependency in unit tests:

var dep = new Mock<IYourDependency>().Object; var cl= new YourClass(dep); 
Sign up to request clarification or add additional context in comments.

Comments

3

You´re right that the factory itself breaks the OPEN/CLOSED-principle, as it is statically bound to the types it instantiates. The same happens in your abstract factory, as you only introduce a further level of abstraction. Not the factory decides which type to create, but the code that creates the factory.

But actually you have to perform the switch somewhere. This code will probably break some principles. That´s a tradeoff you have to do quite often in programming. However it´s considered a low price for a higher gain: instead of changing every client-code wherenever you introduce a new type, you have to do it only once within the factory. So all consumer-code can stay unchanged.

Another advantage is that your client-code is completely un-aware of the actual class. It does not need to know it. In fact the actual class can even be some arbitrary mock. This way you can test your client-code even if the dependecy (the actually class that implements IFan) does not yet exist or is only partially developed by another team-member:

// there´s currently no valid implementation for the interface, // however we don´t care for it, we´re just interested in our own class // Thus we mock that dependency away IFan mock = new Mock<IFan>(); systemUnderTest.DoSomething(mock.Object); 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.