首页 文章

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

提问于
浏览
442

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

20 回答

  • 35

    Factory method: 您有一个工厂可以创建从特定基类派生的对象

    Abstract factory: 您有一个工厂可以创建其他工厂,而这些工厂又会创建从基类派生的对象 . 这样做是因为您通常不只是想创建单个对象(与Factory方法一样) - 而是要创建相关对象的集合 .

  • 37

    抽象工厂是用于创建相关对象的接口,但工厂方法是一种方法 . 抽象工厂是通过工厂方法实现的 .

    enter image description here

  • 3

    Basic difference:

    Factory: 创建对象而不将实例化逻辑暴露给客户端 .

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

    Abstract Factory :提供用于创建相关或从属对象族的接口,而无需指定其具体类 .

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

    来自oodesign文章:

    Factory类图:

    enter image description here

    示例: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示例的非静态工厂:

    Design Patterns: Factory vs Factory method vs Abstract Factory

    When to use: 客户端只需要一个类,而不关心它正在实现哪个具体实现 .

    Factory Method class digaram:

    enter image description here

    When to use: 客户端不知道在运行时需要创建哪些具体类,但只是想获得一个可以完成工作的类 .

    Abstract Factory类图dzone

    enter image description here

    When to use: 当您的系统必须创建多个系列产品或您想要提供产品库而不暴露实施细节时 .

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

    与代码示例相关的SE问题:

    Factory Pattern. When to use factory methods?

    Differences:

    • Abstract工厂类通常使用工厂方法实现,但也可以使用Prototype实现

    • Designs开始使用Factory Method(更简单,更可定制,子类激增),并向更需要更多灵活性的其他创建模式(更灵活,更复杂)发展 .

    • 工厂方法通常在模板方法中调用 .

    其他有用的文章:

    来自sourcemaking的factory_method

    来自sourcemaking的abstract_factory

    abstract-factory-design-pattern来自journaldev

  • 21

    Extending John Feminella answer:

    AppleBananaCherry 实现了 FruitFactory ,它有一个名为 Create 的方法,它独自负责创建Apple或Banana或Cherry . 你用 Factory 方法完成了 .

    现在,你想要用你的水果特制沙拉 Abstract Factory . Abstract Factory知道如何用Apple,Banana和Cherry创建特殊的沙拉 .

    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.
        }
    }
    
  • 1

    使用Factory模式,可以生成特定接口(例如 IFruit )的实现实例( AppleBananaCherry 等) .

    使用抽象工厂模式,您可以为任何人提供自己的工厂 . 这使您的仓库可以是 IFruitFactoryIJuiceFactory ,而不需要您的仓库了解有关水果或果汁的任何信息 .

  • 5

    此信息的来源取自:http://java.dzone.com/news/intro-design-patterns-abstract

    抽象工厂与工厂方法

    抽象工厂的方法是作为工厂方法实现的 . 抽象工厂模式和工厂方法模式都通过抽象类型和工厂将客户端系统与实际实现类分离 . Factory方法通过继承创建对象,其中Abstract Factory通过合成创建对象 .

    抽象工厂模式由AbstractFactory,ConcreteFactory,AbstractProduct,ConcreteProduct和Client组成 .

    如何实施

    抽象工厂模式可以使用工厂方法模式,原型模式或单例模式来实现 . ConcreteFactory对象可以实现为Singleton,因为只需要ConcreteFactory对象的一个实例 .

    Factory Method模式是Abstract Factory模式的简化版本 . Factory Method模式负责创建属于一个系列的产品,而Abstract Factory模式负责处理多个产品系列 .

    Factory方法使用接口和抽象类将客户端与生成器类和生成的产品分离 . Abstract Factory有一个发生器,它是几种工厂方法的容器,以及将客户端与发生器和产品分离的接口 .

    何时使用工厂方法模式

    当需要将客户端与其使用的特定产品分离时,请使用Factory Method模式 . 使用工厂方法减轻客户对创建和配置产品实例的责任 .

    何时使用抽象工厂模式

    当客户端必须与产品类分离时,请使用抽象工厂模式 . 特别适用于程序配置和修改 . 抽象工厂模式还可以强制限制哪些类必须与其他类一起使用 . 建造新的混凝土工厂可能需要做很多工作 .

    示例:

    抽象工厂实例1

    用于在面食制作机中准备不同类型面食的盘的规范是抽象工厂,并且每个特定盘是工厂 . 所有工厂(面食制造商磁盘)从抽象工厂继承他们的属性 . 每个单独的磁盘包含如何创建面食的信息,而面食制造商则没有 .

    抽象工厂示例2:

    Stamping Equipment对应于Abstract Factory,因为它是创建抽象产品对象的操作的接口 . 模具对应于混凝土工厂,因为它们创造了一种混凝土产品 . 每个零件类别(引擎盖,门等)对应于抽象产品 . 特定部件(即99 camry的驾驶员侧门)对应于混凝土产品 .

    工厂方法示例:

    玩具公司对应于造物主,因为它可以使用工厂来创建产品对象 . 制造特定类型玩具(马或汽车)的玩具公司的分部对应于ConcreteCreator .

  • 2

    工厂模式:工厂 生产环境 IProduct实现

    抽象工厂模式:工厂 - 工厂 生产环境 IFactories,反过来 生产环境 IP产品:)

    [根据评论更新]
    根据Wikipedia,我之前写的内容不正确 . 抽象工厂只是一个工厂界面 . 有了它,您可以在运行时切换工厂,以允许不同的工厂在不同的环境中 . 示例可以是针对不同操作系统,SQL提供程序,中间件驱动程序等的不同工厂 .

  • 15

    抽象工厂模式

    • 提供用于创建相关或从属对象族的接口,而无需指定其具体类 .

    • 抽象工厂模式非常类似于工厂方法模式 . 两者之间的一个区别是,使用抽象工厂模式,类通过组合将对象实例化的责任委托给另一个对象,而工厂方法模式使用继承并依赖子类来处理所需的对象实例化 .

    • 实际上,委托对象经常使用工厂方法来执行实例化!

    工厂模式

    • 工厂模式是创作模式的例子

    • Creational模式抽象对象实例化过程 . 它们隐藏了如何创建对象,并帮助使整个系统独立于其对象的创建和组合方式 .

    • 类创建模式侧重于使用继承来决定要实例化的对象Factory Method

    • 对象创建模式侧重于将实例化委托给另一个对象Abstract Factory

    参考:Factory vs Abstract Factory

  • 96

    抽象工厂的示例/场景

    我住在雨季下雨的地方,冬天下雪,夏天炎热,阳光充足 . 我需要不同种类的衣服来保护自己免受这些因素的影响 . 为此,我去了我家附近的商店,要求衣服/物品来保护自己 . 店主根据口袋的环境和深度给我合适的物品 . 他给我的物品质量和价格范围相同 . 由于他了解我的标准,因此他很容易这样做 . 但是,当街对面的富人提出相同的要求时,他会获得一件昂贵的品牌商品 . 一个值得注意的事情是他给我的所有项目在术语质量,标准和成本方面相互补充 . 可以说他们互相帮助 . 这个有钱人得到的物品也是如此 .

    因此,通过观察上面的场景,我现在欣赏店主的效率 . 我可以替换它店主与抽象商店 . 我们通过抽象项目和我以及富人作为透视客户获得的项目 . 我们所需要的只是符合我们需求的产品/产品 .

    现在我可以很容易地看到自己正在考虑一个为其众多客户提供一系列服务的在线商店 . 每个客户都属于三个组中的一个 . 当高级组用户打开网站时,他获得了很棒的UI,高度定制的广告窗格,菜单中的更多选项等 . 这些相同的功能集呈现给黄金用户,但菜单中的功能较少,广告大多是相关的,并且略微减少了egronomic UI . 最后是我的用户,一个“免费组”用户 . 我的服务足够让我不被冒犯 . 用户界面是最低限度的,广告偏离轨道太多,所以我不知道它的内容,最后菜单只有注销 .

    如果我有机会 Build 类似这个网站的东西,我肯定会考虑抽象工厂模式 .

    抽象产品:广告窗格,菜单,UI画家 .
    抽象工厂:网上商店用户体验
    Concreate Factory:高级用户体验,金牌用户体验,一般用户体验 .

  • 41

    许多人可能会感到惊讶,但这个问题是 incorrect . 如果您在面试中听到这个问题,您需要帮助面试官了解混淆的位置 .

    让我们从没有具体模式被称为“工厂”的事实开始 . 有被称为“抽象工厂”的模式,有被称为“工厂方法”的模式 .

    那么,“工厂”是什么意思呢?以下之一(根据参考范围,所有都可以认为是正确的):

    • 有些人将它用作“Abstract Factory”的别名(快捷方式) .

    • 有些人将它用作“Factory Method”的别名(快捷方式) .

    • 有些人将它用作所有工厂/创作模式的更通用的名称 . 例如 . "Abstract Factory"和"Factory Method"都是工厂 .

    并且, unfortunately ,许多人使用"Factory"表示另一种工厂,它创建工厂或工厂(或他们的接口) . 根据他们的理论:

    Product实现了由Factory创建的IProduct,它实现了由AbstractFactory创建的IFactory .

    要理解这是多么愚蠢,让我们继续我们的等式:

    AbstractFactory实现了IAbstractFactory,它是由... AbstractAbstractFactory ???创建的

    我希望你明白这一点 . 不要混淆,请不要发明不合理的东西 .

    P.S. :Factory for Products是AbstractFactory,而Factory For Abstract Factory也是AbstractFactory的另一个例子 .

  • 1
    //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
    }
    

    其他答案已经提供了教科书定义 . 我想我也会提供一个例子 .

    所以这里 PizzaIngredientsFactoryabstract factory ,因为它提供了创建相关产品系列的方法 .

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

    工厂方法

    提供具体实施的实例

    在示例中:

    • createDough() - 提供面团的具体实施 . 所以这是一种工厂方法

    抽象工厂

    提供用于创建相关对象族的界面

    在示例中:

    • PizzaIngredientsFactory 是一个抽象工厂,因为它允许创建一组相关的对象,如 Dough ,_ ClamsSauce . 为了创建每个对象系列,它提供了一个工厂方法 .

    Head First design patterns中的示例

  • 1

    Factory方法是一种非静态方法,它返回基类或接口类型,并在层次结构中实现以启用多态创建 . 工厂方法必须由类和类的一个或多个子类定义/实现 . 每个类和子类都充当工厂 . 但是,我们并未说工厂方法是工厂 . 抽象工厂是用于创建相关或从属对象族而不指定其具体类的接口 .

    抽象工厂被设计为在运行时可替代,因此系统可以配置为使用抽象工厂的特定具体实现者 . 每个抽象工厂都是工厂,但不是每个工厂都是抽象工厂 . 类那些工厂,而不是抽象工厂,当需要支持创建几个相关或依赖对象系列时,有时会演变为抽象工厂 .

  • 3

    我有一些观点可以用John的答案作出如下贡献:

    抽象工厂是工厂的工厂!

    使用"Factory Method"(因为只是"Factory"是不明确的),您可以生成特定接口的实现( Lemon ,_ Orange 等),例如 IFruit . 这个工厂可以叫做 CitricFruitFactory .

    但现在你想要创造另一种水果,而CitricFruitFactory无法创造 . 如果你在其中创建一个 Strawberry (草莓不是柠檬水果!),也许 CitricFruitFactory 的代码没有意义 .

    因此,您可以创建一个名为 RedFruitFactory 的新工厂,该工厂生成 Strawberry ,_ Raspberry 等 .

    Like John Feminella said: “使用抽象工厂模式,您可以生成特定工厂界面的实现 - 例如, IFruitFactory . 每个人都知道如何创建不同种类的水果 . ”

    IFruitFactory 的实现是 CitricFruitFactoryRedFruitFactory

  • 30

    我的来源是: StackOverflow ,_ tutorialspoint.comprogrammers.stackexchange.comCodeProject.com .


    Factory Method (也称为 Factory )用于解除 Interface 实现的客户端 . 对于示例,我们有一个带有两个 CircleSquare 实现的 Shape 接口 . 我们使用带有确定参数(如 Type )的工厂方法和 Shape 接口的新相关实现来定义工厂类 .


    Abstract Factory 包含多个工厂方法或多个工厂实现的工厂接口 . 对于下面的上一个示例,我们有一个带有两个 RedYellow 实现的 Color 接口 . 我们定义了一个带有两个 RedCircleFactoryYellowSquareFactoryShapeColorFactory 接口 . 以下代码解释了这个概念:

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

    这里 FactoryMethodAbstractFactory 之间的区别 . Factory Method 只是返回一个接口的具体类但 Abstract Factory 返回 factory of factory . 换句话说 Abstract Factory 返回一系列界面的不同组合 .


    我希望我的解释有用 .

  • 18

    这些工厂的主要区别在于您想要对工厂做什么以及何时想要使用它 .

    有时,当您进行IOC(控制反转,例如构造函数注入)时,您知道可以创建实体对象 . 如上面的水果示例中所述,如果您准备创建水果对象,则可以使用简单的 factory pattern .

    但很多时候,你不想创建实体对象,它们将在程序流程的后期出现 . 但是配置会告诉您在启动时要使用的工厂类型,而不是创建对象,您可以将从公共工厂类派生的工厂传递给IOC中的构造函数 .

    所以,我认为它也是关于对象的生命周期和创造 .

  • 1

    通过定义,我们可以拖出两个的差异:

    Factory:接口用于创建对象,但子类决定实例化哪个类 . 在需要时完成对象的创建 .

    抽象工厂:抽象工厂模式作为一个超级工厂,创造其他工厂 . 在抽象工厂模式中,接口负责创建一组相关对象或从属对象,而不指定其具体类 .

    因此,在上面的定义中,我们可以强调一个特定的差异 . 也就是说,Factory模式负责创建对象,而Abstract Factory负责创建一组相关对象;显然都是通过一个界面 .

    工厂模式:

    public interface IFactory{
      void VehicleType(string n);
     }
    
     public class Scooter : IFactory{
      public void VehicleType(string n){
       Console.WriteLine("Vehicle type: " + n);
      }
     }
    
     public class Bike : IFactory{
      public void VehicleType(string n) {
      Console.WriteLine("Vehicle type: " + n);
      }
     }
    
     public interface IVehicleFactory{
      IFactory GetVehicleType(string Vehicle);
     }
    
     public class ConcreteVehicleFactory : IVehicleFactory{
     public IFactory GetVehicleType(string Vehicle){
       switch (Vehicle){
        case "Scooter":
         return new Scooter();
        case "Bike":
         return new Bike();
        default:
        return new Scooter();
      }
     }
    
     class Program{
      static void Main(string[] args){
       IVehicleFactory factory = new ConcreteVehicleFactory();
       IFactory scooter = factory.GetVehicleType("Scooter");
       scooter.VehicleType("Scooter");
    
       IFactory bike = factory.GetVehicleType("Bike");
       bike.VehicleType("Bike");
    
       Console.ReadKey();
     }
    }
    

    抽象工厂模式:

    interface IVehicleFactory{
     IBike GetBike();
     IScooter GetScooter();
    }
    
    class HondaFactory : IVehicleFactory{
         public IBike GetBike(){
                return new FZS();
         }
         public IScooter GetScooter(){
                return new FZscooter();
         }
     }
    class HeroFactory: IVehicleFactory{
          public IBike GetBike(){
                return new Pulsur();
         }
          public IScooter GetScooter(){
                return new PulsurScooter();
         }
    }
    
    interface IBike
        {
            string Name();
        }
    interface IScooter
        {
            string Name();
        }
    
    class FZS:IBike{
       public string Name(){
         return "FZS";
       }
    }
    class Pulsur:IBike{
       public string Name(){
         return "Pulsur";
       }
    }
    
    class FZscooter:IScooter {
      public string Name(){
         return "FZscooter";
       }
    }
    
    class PulsurScooter:IScooter{
      public string Name(){
         return "PulsurScooter";
       }
    }
    
    enum MANUFACTURERS
    {
        HONDA,
        HERO
    }
    
    class VehicleTypeCheck{
            IBike bike;
            IScooter scooter;
            IVehicleFactory factory;
            MANUFACTURERS manu;
    
            public VehicleTypeCheck(MANUFACTURERS m){
                manu = m;
            }
    
            public void CheckProducts()
            {
                switch (manu){
                    case MANUFACTURERS.HONDA:
                        factory = new HondaFactory();
                        break;
                    case MANUFACTURERS.HERO:
                        factory = new HeroFactory();
                        break;
                }
    
          Console.WriteLine("Bike: " + factory.GetBike().Name() + "\nScooter: " +      factory.GetScooter().Name());
            }
      }
    
    class Program
        {
            static void Main(string[] args)
            {
                VehicleTypeCheck chk = new VehicleTypeCheck(MANUFACTURERS.HONDA);
                chk.CheckProducts();
    
                chk= new VehicleTypeCheck(MANUFACTURERS.HERO);
                chk.CheckProducts();
    
                Console.Read();
            }
        }
    
  • 2

    检查这里:http://www.allapplabs.com/java_design_patterns/abstract_factory_pattern.htm似乎Factory方法使用特定类(不是抽象)作为基类,而Abstract工厂使用抽象类 . 此外,如果使用接口而不是抽象类,结果将是抽象工厂模式的不同实现 .

    :d

  • 136

    Factory MethodAbstract Factory 使客户端与具体类型分离 . 两者都创建对象,但 Factory 方法使用继承而 Abstract Factory 使用组合 .

    Factory Method 在子类中继承以创建具体对象(产品),而 Abstract Factory 提供用于创建相关产品族的接口,这些接口的子类定义如何创建相关产品 .

    然后将实例化时的这些子类传递到产品类中,并将其用作抽象类型 . Abstract Factory 中的相关产品通常使用 Factory Method 实现 .

  • 385

    Abstract Factory是用于创建不同类型接口的模板 . 假设您有项目要求您解析包含数量,价格和项目特定信息的不同类型的csv文件,例如某些包含有关巧克力的水果数据,然后解析后需要在相应的数据库中更新此信息,这样您就可以拥有一个抽象工厂返回你的解析器和修改器工厂,然后这个解析器工厂可以返回巧克力解析器对象,Fruit Parser Object等,类似的Modifier Factory可以返回Chocolate修饰符对象,Fruit Modifier对象等 .

  • 5

    我想我们可以通过查看Java8示例代码来理解这两者之间的区别:

    interface Something{}
    
      interface OneWhoCanProvideSomething {
         Something getSomething();
      }
    
      interface OneWhoCanProvideCreatorsOfSomething{
         OneWhoCanProvideSomething getCreator();
      }
    
    
    public class AbstractFactoryExample {
    
        public static void main(String[] args) {
            //I need something
            //Let's create one
            Something something = new Something() {};
    
            //Or ask someone (FACTORY pattern)
            OneWhoCanProvideSomething oneWhoCanProvideSomethingOfTypeA = () -> null;
            OneWhoCanProvideSomething oneWhoCanProvideSomethingOfTypeB = () -> null;
    
            //Or ask someone who knows soemone who can create something (ABSTRACT FACTORY pattern)
            OneWhoCanProvideCreatorsOfSomething oneWhoCanProvideCreatorsOfSomething = () -> null;
    
            //Same thing, but you don't need to write you own interfaces
            Supplier<Something> supplierOfSomething = () -> null;
            Supplier<Supplier<Something>> supplierOfSupplier = () -> null;
        }
    
    }
    

    现在的问题是你应该使用哪种创作方式和原因:第一种方式(没有模式,只是简单的构造函数):自己创建不是一个好主意,你必须做所有的工作,你的客户端代码绑定到特定的实施 .

    第二种方式(使用工厂模式):为您提供可以传递任何类型的实现的好处,它可以根据某些条件(可能是传递给创建方法的参数)提供不同类型的实现 .

    第三种方式(使用抽象工厂模式):这为您提供了更大的灵活性 . 您可以根据某些条件(可能是传递的参数)找到不同类型的创建者 .

    Note that you can always get away with Factory pattern by combining two conditions together (which slightly increases code complexity, and coupling), I guess that's why we rarely see real life use cases of Abstract Factory pattern.

相关问题