工厂模式和抽象工厂模式之间的基本区别是什么?


当前回答

抽象工厂是创建相关对象的接口,而工厂方法是一种方法。抽象工厂采用工厂方法实现。

其他回答

基本的区别:

工厂:创建对象时不向客户端公开实例化逻辑。

工厂方法:定义用于创建对象的接口,但让子类决定实例化哪个类。Factory方法允许类延迟实例化到子类

抽象工厂:提供一个接口,用于创建一系列相关或依赖的对象,而无需指定它们的具体类。

AbstractFactory模式使用组合将创建对象的责任委托给另一个类,而Factory方法模式使用继承并依赖于派生类或子类来创建对象

来自oodesign的文章:

工厂类图:

例如:StaticFactory

 public class ShapeFactory {

   //use getShape method to get object of type shape 
   public static Shape getShape(String shapeType){
      if(shapeType == null){
         return null;
      }     
      if(shapeType.equalsIgnoreCase("CIRCLE")){
         return new Circle();

      } else if(shapeType.equalsIgnoreCase("RECTANGLE")){
         return new Rectangle();

      } else if(shapeType.equalsIgnoreCase("SQUARE")){
         return new Square();
      }

      return null;
   }
}

非静态工厂实现FactoryMethod的例子在这篇文章中可用:

设计模式:工厂vs工厂方法vs抽象工厂

何时使用:客户端只需要一个类,并不关心它得到的是哪个具体实现。

工厂方法类digaram:

何时使用:客户端不知道在运行时需要创建什么具体的类,而只是想获得一个可以完成这项工作的类。

来自dzone的抽象工厂类图

何时使用:当您的系统必须创建多个产品系列,或者您希望提供一个产品库而不公开实现细节时。

以上文章中的源代码示例非常有助于清楚地理解这些概念。

相关SE问题与代码示例:

工厂模式。什么时候使用工厂方法?

差异:

抽象工厂类通常使用工厂方法来实现,但它们也可以使用原型来实现 设计开始使用工厂方法(不太复杂,更可定制,子类激增),然后向其他需要更多灵活性的创建模式(更灵活,更复杂)发展。 工厂方法通常在模板方法中调用。

其他有用的文章:

来自sourcemmaking的Factory_method

摘要工厂从sourcemmaking

来自journaldev的抽象工厂设计模式

//Abstract factory - Provides interface to create factory of related products
interface PizzaIngredientsFactory{    
   public Dough createDough(); //Will return you family of Dough
   public Clam createClam();   //Will return you family of Clam
   public Sauce createSauce(); //Will return you family of Sauce
}

class NYPizzaIngredientsFactory implements PizzaIngredientsFactory{

   @Override
   public Dough createDough(){
      //create the concrete dough instance that NY uses
      return doughInstance;
   }

   //override other methods
} 

课本上的定义已经由其他答案提供了。我想我也会提供一个例子。

因此这里pizzaingredient factory是一个抽象工厂,因为它提供了创建一系列相关产品的方法。

注意,抽象工厂中的每个方法本身都是一个工厂方法。就像createDough()本身是一个工厂方法,其具体实现将由nypizzafactorentsfactory等子类提供。因此,使用这个方法,每个不同的位置都可以创建属于其位置的具体成分实例。

工厂方法

提供具体实现的实例

在这个例子中: - createDough() -提供面团的具体实现。这是一个工厂方法

抽象工厂

提供创建相关对象族的接口

在这个例子中: pizzafactorentsfactory是一个抽象工厂,因为它允许创建一组相关的对象,如面团,蛤蜊,酱汁。为了创建每个对象族,它提供了一个工厂方法。

来自Head First设计模式的示例

我的资源是:StackOverflow, tutorialspoint.com, programmers.stackexchange.com和CodeProject.com。


工厂方法(也称为工厂)用于解耦接口实现的客户端。例如,我们有一个具有圆和方两个实现的Shape接口。我们已经定义了一个工厂类,它带有一个工厂方法和一个确定参数,如Type和Shape接口的新的相关实现。


抽象工厂包含多个工厂方法或多个工厂实现的工厂接口。 对于上面的下一个示例,我们有一个带有两个红色和黄色实现的颜色接口。 我们已经用两个RedCircleFactory和YellowSquareFactory定义了一个ShapeColorFactory接口。下面的代码解释这个概念:

interface ShapeColorFactory
{
    public Shape getShape();
    public Color getColor();
}

class RedCircleFactory implements ShapeColorFactory
{
    @Override
    public Shape getShape() {
        return new Circle();
    }

    @Override
    public Color getColor() {
        return new Red();
    }
}
class YellowSquareFactory implements ShapeColorFactory
{
    @Override
    public Shape getShape() {
        return new Square();
    }

    @Override
    public Color getColor() {
        return new Yellow();
    }
} 

这里是FactoryMethod和AbstractFactory的区别。工厂方法返回接口的具体类,而抽象工厂返回工厂的工厂。换句话说,抽象工厂返回不同组合的一系列界面。


我希望我的解释有用。

延伸John Feminella的回答:

Apple, Banana, Cherry实现了FruitFactory,它有一个叫做Create的方法,它只负责创建Apple, Banana或Cherry。Factory方法就完成了。

现在,你想用你的水果创建一个特殊的沙拉,这就是你的抽象工厂。抽象工厂知道如何用苹果、香蕉和樱桃制作你的特殊沙拉。

public class Apple implements Fruit, FruitFactory {
    public Fruit Create() {
        // Apple creation logic goes here
    }
}

public class Banana implements Fruit, FruitFactory {
    public Fruit Create() {
        // Banana creation logic goes here
    }
}

public class Cherry implements Fruit, FruitFactory {
    public Fruit Create() {
        // Cherry creation logic goes here
    }
}

public class SpecialSalad implements Salad, SaladFactory {
    public static Salad Create(FruitFactory[] fruits) {
        // loop through the factory and create the fruits.
        // then you're ready to cut and slice your fruits 
        // to create your special salad.
    }
}

这些工厂的主要区别是什么时候你想用工厂做什么,什么时候你想使用它。

有时候,当你在做IOC(控制反转,例如构造函数注入)时,你知道你可以创建固体对象。如上面的水果示例所述,如果准备创建水果对象,可以使用简单的工厂模式。

但是很多时候,你不想创建实体对象,它们会在程序流的后面出现。但是配置告诉你你想在开始时使用什么样的工厂,而不是创建对象,你可以将从公共工厂类派生的工厂传递给IOC中的构造函数。

所以,我认为这也是关于对象的生命周期和创建。