0

My Product Factory

public interface IProductFactory
{
    void Drive(int miles);
}

My Vehicle Factory

public interface IVehicleFactory
{
    IProdctFactory GetVehicle(string Vehicle);
}

Product Bike

class Bike:IProdctFactory
{
    public void Drive(int miles)
    {
        Console.WriteLine("Drive the Bike : " + miles.ToString() + "km");
    }
}

Product Scooter

class Scooter:IProdctFactory
{
    public void Drive(int miles)
    {
        Console.WriteLine("Drive the Scooter : " + miles.ToString() + "km");
    }
}

Product Car

class Car:IProdctFactory
{
    public void Drive(int miles)
    {
        Console.WriteLine("Drive the Car : " + miles.ToString() + "km");
    }
}

Product Jeep

class Jeep:IProdctFactory
{
    public void Drive(int miles)
    {
        Console.WriteLine("Drive the Jeep : " + miles.ToString() + "km");
    }
}

Two Wheeler Factory

public class TwoWheelerFactory : IVehicleFactory
{

    public IProdctFactory GetVehicle(string Vehicle)
    {
        switch (Vehicle)
        {
            case "Scooter":
                return new Scooter();
            case "Bike":
                return new Bike();
            default:
                throw new ApplicationException(string.Format("Vehicle '{0}' cannot be created", Vehicle));
        }
    }
}

Four Wheeler Factory

class FourWheelerFactory:IVehicleFactory
{

    public IProdctFactory GetVehicle(string Vehicle)
    {
        switch (Vehicle)
        {
            case "Car":
                return new Car();
            case "Jeep":
                return new Jeep();
            default:
                throw new ApplicationException(string.Format("Vehicle '{0}' cannot be created", Vehicle));
        }
    }
}

Client

class Program
{
    static void Main(string[] args)
    {
        IVehicleFactory twoWheelerfactory = new TwoWheelerFactory();

        IProdctFactory scooter = twoWheelerfactory.GetVehicle("Scooter");
        scooter.Drive(10);

        IProdctFactory bike = twoWheelerfactory.GetVehicle("Bike");
        bike.Drive(20);

        IVehicleFactory fourWheelerFactory = new FourWheelerFactory();
        IProdctFactory car = fourWheelerFactory.GetVehicle("Car");
        car.Drive(100);

        IProdctFactory jeep = fourWheelerFactory.GetVehicle("Car");
        jeep.Drive(200);

        Console.ReadKey();
    }
}

Is having two concrete vehicle class (TwoWheelerFactory, FourWheelerFactory) ok in factory pattern?

Though I read a lot about abstract factory pattern, I am still not sure about what it is :( Can someone help me to convert this as Abstract Factory pattern?

I read

Design Patterns: Abstract Factory vs Factory Method

and

http://www.dotnet-tricks.com/Tutorial/designpatterns/FUcV280513-Factory-Method-Design-Pattern---C

Community
  • 1
  • 1
Gopi
  • 5,656
  • 22
  • 80
  • 146
  • 3
    I don't understand what IVehicleFactory is giving you, it seems like you could just do the instantiation. Also, "Drive" is not a normal factory method. Overall this seems like a very odd design. – BradleyDotNET Jun 11 '14 at 01:02
  • 1
    PS I can't help but notice that `miles.ToString() + "km"` looks kinda wrong...like off by a factor of about 1.6 in fact. Not to mention distance should not be an int. – Aron Jun 11 '14 at 01:48
  • 1
    `IProductFactory` sure doesn't sound like something that `Drive`s... – Preston Guillot Jun 11 '14 at 03:26

1 Answers1

2

From Wikipedia - The essence of the Abstract Factory Pattern is to "Provide an interface for creating families of related or dependent objects without specifying their concrete classes.".

The key part is that the client never knows that it has an instance of a car or a bike or whatever, it only deals with the abstract types.

Different factories will give you different instances, but the abstract types are the same.

Your Bike, Scooter, Jeep and Car are all concrete products that should be created by a factory method. In your example, having those products inherit from an interface, particularly one named 'Factory' is wrong and confusing (I'm not saying that interfaces in general are wrong).

Below I've simply applied your example/wording (with some minor extensions) to the Abstract Factory pattern provided by Data & Object Factory guys to help give you some context.

While its great and exciting to learn new patterns and techniques, don't fall into the trap in trying to apply this new pattern that you learnt to every situation. The best thing you can do is write simple code. Any additional complexity should be avoided until its actually needed.

class MainApp
{

    public static void Main()
    {

        // Abstract factory #1
        AbstractFactory factory1 = new EuropeVehicleFactory();
        Client client1 = new Client(factory1);
        client1.Run();

        // Abstract factory #2
        AbstractFactory factory2 = new UsaVehicleFactory();
        Client client2 = new Client(factory2);
        client2.Run();

    }
}

/// <summary>
/// The 'AbstractFactory' abstract class
/// </summary>
abstract class AbstractFactory
{
  public abstract TwoWheelerProduct CreateTwoWheelerProduct();
  public abstract FourWheelerProduct CreateFourWheelerProduct();
}


/// <summary>
/// The 'ConcreteFactory1' class
/// </summary>
class UsaVehicleFactory : AbstractFactory
{
  public override TwoWheelerProduct CreateTwoWheelerProduct()
  {
    return new Bike();
  }
  public override FourWheelerProduct CreateFourWheelerProduct()
  {
    return new Car();
  }
}

/// <summary>
/// The 'ConcreteFactory2' class
/// </summary>
class EuropeVehicleFactory : AbstractFactory
{
  public override TwoWheelerProduct CreateTwoWheelerProduct()
  {
    return new Scooter();
  }
  public override FourWheelerProduct CreateFourWheelerProduct()
  {
    return new Jeep();
  }
}

/// <summary>
/// The 'AbstractProductA' abstract class
/// </summary>
abstract class TwoWheelerProduct
{
}

/// <summary>
/// The 'AbstractProductB' abstract class
/// </summary>
abstract class FourWheelerProduct
{
  //Disclaimer: I am a temporary citizen...
  public abstract void RunOver(TwoWheelerProduct twoWheeler);
}


/// <summary>
/// The 'ProductA1' class
/// </summary>
class Scooter : TwoWheelerProduct
{
}

/// <summary>
/// The 'ProductB1' class
/// </summary>
class Car : FourWheelerProduct
{
  public override void RunOver(TwoWheelerProduct twoWheeler)
  {
    Console.WriteLine(this.GetType().Name +
      " smashes into " + a.GetType().Name);
  }
}

/// <summary>
/// The 'ProductA2' class
/// </summary>
class Bike : TwoWheelerProduct
{
}

/// <summary>
/// The 'ProductB2' class
/// </summary>
class Jeep : FourWheelerProduct
{
  public override void RunsOver(TwoWheelerProduct twoWheeler)
  {
    Console.WriteLine(this.GetType().Name +
      " collides with " + a.GetType().Name);
  }
}

/// <summary>
/// The 'Client' class. Interaction environment for the products.
/// </summary>
class Client
{
  private TwoWheelerProduct _abstractTwoWheeler;
  private FourWheelerProduct _abstractFourWheeler;

  // Constructor
  public Client(AbstractFactory factory)
  {
    _abstractTwoWheeler = factory.CreateTwoWheeler();
    _abstractFourWheeler = factory.CreateFourWheeler();
  }

  public void Run()
  {
    _abstractFourWheeler.RunOver(_abstractTwoWheeler);
  }
}
HaveThunk
  • 230
  • 1
  • 7