【问题标题】:SimpleFactory, FactoryMethod, Abstract Factory (Solid Example)SimpleFactory、FactoryMethod、抽象工厂(实体示例)
【发布时间】:2014-03-16 15:36:44
【问题描述】:

我知道这个问题已经被多次解决,因此很明显,它并不像人们通常认为的那样微不足道......

为了澄清事情,我想我会使用相同的 bean 家族和相同的概念构建三种不同实现(简单工厂、工厂方法、抽象工厂)的示例,

您如何看待以下示例? 你觉得它们清晰正确吗?

对于所有示例,我将使用这一系列 bean

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();
    }
}

抽象工厂

对于抽象工厂示例,我添加了这些 bean

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
   }
}

【问题讨论】:

  • Gas implements Vehicle?
  • Spring 框架是工厂模式的一个很好的例子;它是使用设计模式从头开始构建的:docs.spring.io/spring/docs/4.0.x/spring-framework-reference/…。气体工具车辆没有意义。燃料的更好方法是燃烧()或其他东西。你不 addFuel() 燃料。您将燃料添加到车辆以供内燃机消耗。
  • 气体工具燃料,已编辑..错误副本! :)
  • mttdbrd 谢谢....Gas implements Vehicle,只是一个复制错误,对于addFuel,我同意最好使用像combust()这样的东西
  • 那很好。我想说您可能希望将这些类放在同一个包中,并使任何实现 Vehicle 的类的构造函数受保护,以便只有工厂可以实例化它们。这一切都取决于您使用工厂的目的。同样,我建议不要为这种模式编写示例,而是看看 Spring(或其他一些项目)是如何在内部实际实现的。通过查看真实世界的代码以及他们在设计模式方面做出的选择,您将比从这样的练习中学到更多。

标签: java design-patterns abstract-factory factory-method


【解决方案1】:

你的例子很好。我只建议使用常量甚至 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);

此外,我认为您的意思是“昂贵”而不是“便宜”,但肯定汽油也很昂贵:)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-05
    相关资源
    最近更新 更多