Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Factory Design Pattern - Why Interface necessary?

I started looking at different design patterns, and now I am focussing on the Factory Design Pattern. I looked at some examples, youtube tuturials and blogs and I got most but I still didnt get why an interface is necessary.

The official definition is:

Define an interface for creating an object, but let subclasses decide which class to instantiate. Factory Method lets a class defer instantiation to subclasses.

So an Interface seems to be an important part of the Factory Design Pattern, but the only reason I found where its practical is when you make a collection in the main method. If you dont want that, you can just delete it (look at the code below, where that is possible) and it still works like planned.

using System;
using System.Collections.Generic;
using System.Collections;

namespace FactoryDesignPattern
{
    class Program
    {
        static void Main(string[] args)
        {
            var FordFiestaFactory = new FordFiestaFactory();
            var FordFiesta = FordFiestaFactory.CreateCar("Blue");
            Console.WriteLine("Brand: {0} \nModel: {1} \nColor: {2}", FordFiesta.Make, FordFiesta.Model, FordFiesta.Color);
            Console.WriteLine();


            //Inserted this later. Using a collection requires the Interface to be there.
            List<ICreateCars> Cars = new List<ICreateCars>();
            Cars.Add(new FordFiestaFactory());
            Cars.Add(new BMWX5Factory());

            foreach (var Car in Cars)
            {
                var ProductCar = Car.CreateCar("Red");
                Console.WriteLine("Brand: {0} \nModel: {1} \nColor: {2}", ProductCar.Make, ProductCar.Model, ProductCar.Color);
                Console.WriteLine();
            }

            Console.ReadKey();
        }
    }

    public abstract class Car
    {
        public string Make { get; set; }
        public string Model { get; set; }
        public string EngineSize { get; set; }
        public string Color { get; set; }
    }

    public class FordFiesta : Car
    {
        public FordFiesta()
        {
            Make = "Ford";
            Model = "Fiesta";
            EngineSize = "1.1";
        }
    }

    public class BMWX5 : Car
    {
        public BMWX5()
        {
            Make = "BMW";
            Model = "X5";
            EngineSize = "2.1";
        }
    }

    public interface ICreateCars
    {
        Car CreateCar(string color);
    }

    class FordFiestaFactory : ICreateCars
    {
        public Car CreateCar(string color)
        {
            return new FordFiesta() { Color = color };
        }
    }

    class BMWX5Factory : ICreateCars
    {
        public Car CreateCar(string color)
        {
            return new BMWX5(){ Color = color };
        }
    }
}

So why do I need that Interface? I read multiple abstract explenations but I didnt get it, so I prefer practical answers.

Thanks in advance!

like image 887
Hindrik Avatar asked Dec 22 '13 12:12

Hindrik


4 Answers

The interface (or abstract factory base class, which is essentially the same as an interface in effect) is useful whenever the caller of the factory does not know the type of the factory.

You provided the base for your own practical example, so I'll add my explanation here why that's not only useful when having a list of factories:

Imagine a method that is supposed to create a car when appropriate, without knowing what type of car to create (that is decided by the factory implementation). The method looks at a Person object, which has an OwnsCar property, and that property ultimately decides whether the factory method should be called:

public Car CreateCarForPerson(Person person, ICreateCars carType)
{
    if (person.OwnsCar) {
        return carType.CreateCar("red");
    } else {
        return null;
    }
}

In the same way, you could also use such a factory to create an arbitrary number of cars:

public Car[] CreateAnyNumberOfCars(ICreateCars carType)
{
    var result = new List<Car>();
    for (int i = new Random().Next(100); i >= 0; i--) {
        result.Add(carType.CreateCar("blue"));
    }
    return result.ToArray();
}

Note how none of these two methods knows what car type is being created; they use a factory of whom they only know the interface, but not the exact type.

So, if you want to be able to supply different factory implementations, you can declare a common interface for your factories. If your factory only serves to keep your callers away from direct invocations of the target constructor, you do not need the factory interface.

like image 155
O. R. Mapper Avatar answered Nov 01 '22 05:11

O. R. Mapper


You can always apply a design pattern in the way you like. There is nothing wrong with deleting an interface. You should however take into account that deleting the interface leads to a less general structure.

You use the factory pattern because you don't want your calling code (main function) to know anything about the construction details. You don't want to know what a FordFiest is. You just want a car in general to be built. If it is a Ford Fiesta, then so be it. This detail is something the factory (and its subclasses) should handle. Right?

If you don't want your code to depend on the specific factory, you need an extra abstraction layer, provided by the interface, leading to "decoupling" the two parts. If you don't mind your code binding to the specific factory implementation, you could always remove the interface.

Hope I helped!

like image 26
Pantelis Natsiavas Avatar answered Nov 01 '22 05:11

Pantelis Natsiavas


Sure you could use CarFactory to create derived car classes, but then everyone who wants to support the creation of cars has to derive from CarFactory. It seems to me that the purpose of the interface is to allow more flexibility in who can act as a car factory. The notion is that all you need to do to be a CarFactory in this example is to implement the ICreateCars interface. No need to introduce the overhead of the delivered CarFactory base class.

The key is in deciding what your parameter type will be on functions that accept a Car Factory. (or what the member type will be for a member that stores a CarFactory) If you use ICreateCars, then anyone who wants to create cars need only implement the interface. If your parameter type is CarFactory, then they would have to inherit from CarFactory.

like image 36
BlueMonkMN Avatar answered Nov 01 '22 06:11

BlueMonkMN


Well, not really - an interface is not an integral part of this pattern. You could implement a factory equally well as a static class or even a normal one.

It's just that using interfaces is generally a very good idea and most good, component-based designs make heavy use of this. It's called Interface based programming, among its main advantages is that it allows for IoC containers and that it makes your code testable.

Me personally, I use interfaces almost blindly, without even thinking about it...

like image 35
Thomas Weller Avatar answered Nov 01 '22 07:11

Thomas Weller