SimpleFactory, FactoryMethod, Абстрактная фабрика (твердый пример)

1

Я знаю, что проблема, о которой идет речь, неоднократно рассматривалась, поэтому очевидно, что она не такая тривиальная, как ее часто считают...

Чтобы прояснить ситуацию, я подумал, что буду строить примеры трех различных реализаций (простой фабричный, заводский метод, абстрактная фабрика), используя одно и то же семейство компонентов и одну и ту же концепцию,

Что вы думаете о следующих примерах? Вы находите их ясными и правильными?

Для всего примера я буду использовать это семейство бобов

interface Vehicle
{
     public void drive();
     public void clean();
}


class Car implements Vehicle
{
    @Override
    public void drive()
    {
       System.out.println("Driving a car...");
    }

    @Override
    public void clean()
    {
       System.out.println("Cleaning a car...");
    }
}

class Bus implements Vehicle
{
    @Override
    public void drive()
    {
       System.out.println("Driving a Bus...");
    }

    @Override
    public void clean()
    {
       System.out.println("Cleaning a Bus...");
    }
}

ПРОСТАЯ ФАБРИКА

/*client snippet*/
Vehicle car = VehicleFactory.getVehicle("small");


/*our factory*/
class VehicleFactory
{
   public static Vehicle getVehicle(String criteria)
   {
      if ( criteria.equals("small") )
          return new Car();
      else if ( criteria.equals("big") )
          return new Bus();
      return null;
   }
}   

ЗАВОДСКИЙ МЕТОД

//client Class
public class FactoryMethodPattern 
{
    public static void main(String[] args) 
    {
     //handleCreator(new ConcreteCreator1())
         handleVehicle(new CarFactory());
         handleVehicle(new BusFactory ());
    }

    //handleCreator(Creator creator)
    static void handleVehicle(VehicleDriver2 vDriver)
    {
         System.out.println("Handling a new vehicle. Pre lambda way");
         vDriver.driveVehicle();
         vDriver.cleanVehicle();
    }
}

//client snippet
VehicleFactory v = new CarFactory();
Vehicle vehicle = v.getVehicle();
     OR
VehicleFactory v = new CarFactory();
v.driveVehicle();



//creator
abstract class VehicleFactory
{
    //the abstract method of the creator
    public abstract Vehicle getVehicle();

    public void driveVehicle()
    {
       getVehicle().drive();
    }

    public void cleanVehicle()
    {
       getVehicle().clean();
    }
}

//concrete creator
class CarFactory extends VehicleFactory
{
    @Override
    public Vehicle getVehicle()
    {
       return new Car();
    }
}

//concrete creator
class BusFactory extends VehicleFactory
{
    @Override
    public Vehicle getVehicle()
    {
       return new Bus();
    }
}

АБСТРАКТНАЯ ФАБРИКА

Для абстрактного заводского примера я добавляю эти компоненты

interface Fuel
{
    public void combust();
}


class Petrol implements Fuel
{
    @Override
    public void combust()
    {
       System.out.println("Petrol...");
    }
}

class Gas implements Fuel
{
    @Override
    public void combust()
    {
       System.out.println("Gas...");
    }
}

И вот пример абстрактного завода

//AbstractFactory
public abstract class AbstractFactory 
{
   abstract Fuel getFuel(String criteria);
   abstract Vehicle getVehicle(String criteria) ;
}

//ConcreteFactory
public class VehicleFactory extends AbstractFactory 
{

   @Override
   public Vehicle getVehicle(String criteria)
   {
      if(criteria == null)
      {
         return null;
      }     
      if(criteria.equals("BIG"))
      {
         return new Bus();
      } 
      else if(criteria.equals("SMALL"))
      {
         return new Car();
      } 
      return null;
   }

   @Override
   Color getFuel(String criteria) 
   {
      return null;
   }
}

//ConcreteFactory
public class FuelFactory extends AbstractFactory 
{

   @Override
   public Vehicle getVehicle(String criteria)

   {
      return null;
   }

   @Override
   Fuel getFuel(String criteria) 
   {
      if(criteria == null)
      {
         return null;
      }     
      if(criteria.equals("CHEAP"))
      {
         return new Gas();
      } 
      else if(criteria.equals("EXPANSIVE"))
      {
         return new Petrol();
      } 
      return null;
   }
}


public class FactoryProducer 
{
   public static AbstractFactory getFactory(String criteria)
   {
      if(criteria.equalsIgnoreCase("VEHICLE"))
      {
         return new VehicleFactory();
      } 
      else if(criteria.equalsIgnoreCase("FUEL"))
      {
         return new FuelFactory();
      }
      return null;
   }
}

//client class
public class AbstractFactoryPatternDemo 
{
   public static void main(String[] args) 
   {
      AbstractFactory vehicleFactory = FactoryProducer.getFactory("VEHICLE");
      Vehicle car = vehicleFactory.getVehicle("SMALL");
      car.dirve();


      AbstractFactory fuelFactory = FactoryProducer.getFactory("FUEL");
      Fuel petrol = colorFactory.getFuel("EXPANSIVE");
      petrol.combust
   }
}
Теги:
design-patterns
factory-method
abstract-factory

1 ответ

2

Ваши примеры хороши. Я предлагаю использовать константы или даже enum для критериев, чтобы избежать необходимости запоминать строки и избегать орфографических ошибок.

Что-то вроде:

public class VehicleFactory {
    public enum Criteria{
       SMALL,BIG
   }

    public static Vehicle getVehicle(Criteria criteria)
    {
       if ( criteria.equals(Criteria.SMALL) )
           return new Car();
       else if ( criteria.equals(Criteria.BIG) )
           return new Bus();
       return null;
   }
}

И клиентский код:

VehicleFactory.getVehicle(VehicleFactory.Criteria.SMALL);

Более того, я думаю, вы имеете в виду "дорогие", так как это "дешево", но уверен, что бензин тоже экспансивный :)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню