我知道有很多关于这两种模式之间差异的帖子,但有一些东西我找不到。

From what I have been reading, I see that the factory method pattern allows you to define how to create a single concrete product but hiding the implementation from the client as they will see a generic product. My first question is about the abstract factory. Is its role to allow you to create families of concrete objects in (that can depend on what specific factory you use) rather than just a single concrete object? Does the abstract factory only return one very large object or many objects depending on what methods you call?

我最后两个问题是关于一句我在很多地方都见过的引语,我不能完全理解:

两者之间的一个区别是 使用抽象工厂模式,a 类委托的责任 对象实例化到另一个对象 通过合成,而工厂 方法模式使用继承和 类依赖于子类来处理 所需的对象实例化。

我的理解是,工厂方法模式有一个Creator接口,它将使ConcreteCreator负责知道要实例化哪个ConcreteProduct。这就是使用继承来处理对象实例化的意思吗?

现在,关于引用,抽象工厂模式是如何通过组合将对象实例化的责任委托给另一个对象的?这是什么意思?在我看来,抽象工厂模式似乎也使用继承来完成构造过程,但我仍然在学习这些模式。

任何帮助,特别是最后一个问题,将非常感激。


两者的区别

“工厂方法”和“抽象工厂”的主要区别在于,工厂方法是方法,而抽象工厂是对象。我想很多人都把这两个词搞混了,开始交替使用。我记得当我学习它们的时候,我很难找到它们之间的确切区别。

因为工厂方法只是一个方法,它可以在子类中被重写,因此引用的后半部分:

... 工厂方法模式使用的 继承并依赖于一个子类 来处理所需的对象 实例化。

引用假设对象在这里调用自己的工厂方法。因此,唯一可以改变返回值的是子类。

抽象工厂是一个具有多个工厂方法的对象。看看你引言的前半部分:

... 使用抽象工厂模式,一个类 委托对象的职责 实例化到另一个对象 作文……

他们说的是,有一个对象A,想要创建一个Foo对象。而不是创建Foo对象本身(例如,使用工厂方法),它将获得一个不同的对象(抽象工厂)来创建Foo对象。

代码示例

为了向你展示区别,这里有一个正在使用的工厂方法:

class A {
    public void doSomething() {
        Foo f = makeFoo();
        f.whatever();   
    }

    protected Foo makeFoo() {
        return new RegularFoo();
    }
}

class B extends A {
    protected Foo makeFoo() {
        //subclass is overriding the factory method 
        //to return something different
        return new SpecialFoo();
    }
}

这是一个正在使用的抽象工厂:

class A {
    private Factory factory;

    public A(Factory factory) {
        this.factory = factory;
    }

    public void doSomething() {
        //The concrete class of "f" depends on the concrete class
        //of the factory passed into the constructor. If you provide a
        //different factory, you get a different Foo object.
        Foo f = factory.makeFoo();
        f.whatever();
    }
}

interface Factory {
    Foo makeFoo();
    Bar makeBar();
    Aycufcn makeAmbiguousYetCommonlyUsedFakeClassName();
}

//need to make concrete factories that implement the "Factory" interface here

抽象工厂创建了一个基类,其抽象方法定义了应该创建的对象的方法。派生基类的每个工厂类都可以创建每种对象类型的自己的实现。

工厂方法只是一个用于在类中创建对象的简单方法。它通常添加在聚合根中(Order类有一个名为CreateOrderLine的方法)

抽象工厂

在下面的示例中,我们设计了一个接口,这样我们就可以将队列创建与消息传递系统分离,因此可以为不同的队列系统创建实现,而不必更改代码库。

interface IMessageQueueFactory
{
  IMessageQueue CreateOutboundQueue(string name);
  IMessageQueue CreateReplyQueue(string name);
}

public class AzureServiceBusQueueFactory : IMessageQueueFactory
{
      IMessageQueue CreateOutboundQueue(string name)
      {
           //init queue
           return new AzureMessageQueue(/*....*/);
      }

      IMessageQueue CreateReplyQueue(string name)
      {
           //init response queue
           return new AzureResponseMessageQueue(/*....*/);
      }

}

public class MsmqFactory : IMessageQueueFactory
{
      IMessageQueue CreateOutboundQueue(string name)
      {
           //init queue
           return new MsmqMessageQueue(/*....*/);
      }

      IMessageQueue CreateReplyQueue(string name)
      {
           //init response queue
           return new MsmqResponseMessageQueue(/*....*/);
      }
}

工厂方法

HTTP服务器的问题在于,我们总是需要为每个请求提供响应。

public interface IHttpRequest
{
    // .. all other methods ..

    IHttpResponse CreateResponse(int httpStatusCode);
}

如果没有工厂方法,HTTP服务器用户(即程序员)将被迫使用特定于实现的类,这就违背了IHttpRequest接口的目的。

因此,我们引入工厂方法,以便响应类的创建也被抽象出来。

总结

区别在于,包含工厂方法的类的预期目的不是创建对象,而抽象工厂应该只用于创建对象。

使用工厂方法时应该小心,因为在创建对象时很容易破坏LSP(里斯科夫替换原则)。


AbstractFactory和Factory设计模式之间的区别如下:

Factory Method is used to create one product only but Abstract Factory is about creating families of related or dependent products. Factory Method pattern exposes a method to the client for creating the object whereas in the case of Abstract Factory they expose a family of related objects which may consist of these Factory methods. Factory Method pattern hides the construction of a single object whereas Abstract Factory hides the construction of a family of related objects. Abstract factories are usually implemented using (a set of) factory methods. Abstract Factory pattern uses composition to delegate the responsibility of creating an object to another class while Factory Method design pattern uses inheritance and relies on a derived class or subclass to create an object. The idea behind the Factory Method pattern is that it allows for the case where a client doesn't know what concrete classes it will be required to create at runtime, but just wants to get a class that will do the job while Abstract Factory pattern is best utilized when your system has to create multiple families of products or you want to provide a library of products without exposing the implementation details.!

工厂方法模式实现:

抽象工厂模式实现:


抽象工厂是创建相关产品的接口,而工厂方法只是一种方法。抽象工厂可以通过多种工厂方法实现。


让我们明确一点,在生产代码中,大多数时候我们使用抽象工厂模式,因为类A是用接口b编程的,而A需要创建b的实例,因此A必须有一个工厂对象来生成b的实例,因此A不依赖于b的任何具体实例,希望它有帮助。


我的第一个问题是关于抽象工厂。它的角色是否允许您在其中创建一系列具体对象(这取决于您使用的具体工厂),而不仅仅是单个具体对象?

是的。抽象工厂的目的是:

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


根据调用的方法,抽象工厂只返回一个非常大的对象还是多个对象?

理想情况下,它应该为客户端调用的每个方法返回一个对象。

我的理解是,工厂方法模式有一个Creator接口,它将使ConcreteCreator负责知道要实例化哪个ConcreteProduct。这就是使用继承来处理对象实例化的意思吗?

是的。工厂方法使用继承。

抽象工厂模式委托对象实例化的责任通过组合到另一个对象?这是什么意思?

AbstractFactory定义了一个FactoryMethod,而ConcreteFactory负责构建一个ConcreteProduct。只需按照本文中的代码示例进行操作。

你可以在SE的相关文章中找到更多细节:

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

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


比起工厂方法,我更喜欢抽象工厂。从Tom Dalling上面的例子(顺便说一句,解释得很好)中,我们可以看到抽象工厂是更可组合的,因为我们所需要做的只是将一个不同的工厂传递给构造函数(这里使用构造函数依赖注入)。但是工厂方法要求我们引入一个新类(需要管理更多的东西)并使用子类化。总是选择组合而不是继承。


Understand the differences in the motivations: Suppose you’re building a tool where you’ve objects and a concrete implementation of the interrelations of the objects. Since you foresee variations in the objects, you’ve created an indirection by assigning the responsibility of creating variants of the objects to another object (we call it abstract factory). This abstraction finds strong benefit since you foresee future extensions needing variants of those objects. Another rather intriguing motivation in this line of thoughts is a case where every-or-none of the objects from the whole group will have a corresponding variant. Based on some conditions, either of the variants will be used and in each case all objects must be of same variant. This might be a bit counter intuitive to understand as we often tend think that - as long as the variants of an object follow a common uniform contract (interface in broader sense), the concrete implementation code should never break. The intriguing fact here is that, not always this is true especially when expected behavior cannot be modeled by a programming contract. A simple (borrowing the idea from GoF) is any GUI applications say a virtual monitor that emulates look-an-feel of MS or Mac or Fedora OS’s. Here, for example, when all widget objects such as window, button, etc. have MS variant except a scroll-bar that is derived from MAC variant, the purpose of the tool fails badly. These above cases form the fundamental need of Abstract Factory Pattern. On the other hand, imagine you’re writing a framework so that many people can built various tools (such as the one in above examples) using your framework. By the very idea of a framework, you don’t need to, albeit you could not use concrete objects in your logic. You rather put some high level contracts between various objects and how they interact. While you (as a framework developer) remain at a very abstract level, each builders of the tool is forced to follow your framework-constructs. However, they (the tool builders) have the freedom to decide what object to be built and how all the objects they create will interact. Unlike the previous case (of Abstract Factory Pattern), you (as framework creator) don’t need to work with concrete objects in this case; and rather can stay at the contract level of the objects. Furthermore, unlike the second part of the previous motivations, you or the tool-builders never have the situations of mixing objects from variants. Here, while framework code remains at contract level, every tool-builder is restricted (by the nature of the case itself) to using their own objects. Object creations in this case is delegated to each implementer and framework providers just provide uniform methods for creating and returning objects. Such methods are inevitable for framework developer to proceed with their code and has a special name called Factory method (Factory Method Pattern for the underlying pattern). Few Notes: If you’re familiar with ‘template method’, then you’d see that factory methods are often invoked from template methods in case of programs pertaining to any form of framework. By contrast, template methods of application-programs are often simple implementation of specific algorithm and void of factory-methods. Furthermore, for the completeness of the thoughts, using the framework (mentioned above), when a tool-builder is building a tool, inside each factory method, instead of creating a concrete object, he/she may further delegate the responsibility to an abstract-factory object, provided the tool-builder foresees variations of the concrete objects for future extensions. Sample Code: //Part of framework-code BoardGame { Board createBoard() //factory method. Default implementation can be provided as well Piece createPiece() //factory method startGame(){ //template method Board borad = createBoard() Piece piece = createPiece() initState(board, piece) } } //Part of Tool-builder code Ludo inherits BoardGame { Board createBoard(){ //overriding of factory method //Option A: return new LudoBoard() //Lodu knows object creation //Option B: return LudoFactory.createBoard() //Lodu asks AbstractFacory } …. } //Part of Tool-builder code Chess inherits BoardGame { Board createBoard(){ //overriding of factory method //return a Chess board } …. }


为了便于理解,考虑这个例子。

电信公司提供什么?例如宽带,电话线和移动电话,你被要求创建一个应用程序,向他们的客户提供他们的产品。

一般来说,你在这里要做的是,通过你的工厂方法创建产品,即宽带,电话线和手机,在那里你知道你为这些产品拥有什么属性,这是非常简单的。

现在,该公司想要为他们的客户提供他们的产品捆绑,即宽带、电话线和移动设备,而抽象工厂就来了。

换句话说,抽象工厂是由其他工厂组成的,他们负责创造自己的产品,抽象工厂知道如何在自己的责任方面把这些产品放在更有意义的地方。

在这种情况下,BundleFactory是抽象工厂,BroadbandFactory, PhonelineFactory和MobileFactory是工厂。为了进一步简化,这些工厂将使用工厂方法初始化各个产品。

运行下面的代码示例:

public class BroadbandFactory : IFactory {
    public static Broadband CreateStandardInstance() {
        // broadband product creation logic goes here
    }
}

public class PhonelineFactory : IFactory {
    public static Phoneline CreateStandardInstance() {
        // phoneline product creation logic goes here
    }
}

public class MobileFactory : IFactory {
    public static Mobile CreateStandardInstance() {
        // mobile product creation logic goes here
    }
}

public class BundleFactory : IAbstractFactory {

    public static Bundle CreateBundle() {
        broadband = BroadbandFactory.CreateStandardInstance();
        phoneline = PhonelineFactory.CreateStandardInstance();
        mobile = MobileFactory.CreateStandardInstance();

        applySomeDiscountOrWhatever(broadband, phoneline, mobile);
    }

    private static void applySomeDiscountOrWhatever(Broadband bb, Phoneline pl, Mobile m) {
        // some logic here
        // maybe manange some variables and invoke some other methods/services/etc.
    }
}

希望这能有所帮助。


为了使它非常简单,界面最小,请关注“//1”:

class FactoryProgram
    {
        static void Main()
        {
            object myType = Program.MyFactory("byte");
            Console.WriteLine(myType.GetType().Name);

            myType = Program.MyFactory("float"); //3
            Console.WriteLine(myType.GetType().Name);

            Console.ReadKey();
        }

        static object MyFactory(string typeName)
        {
            object desiredType = null; //1
            switch (typeName)
            {
                case "byte": desiredType = new System.Byte(); break; //2
                case "long": desiredType = new System.Int64(); break;
                case "float": desiredType = new System.Single(); break;
                default: throw new System.NotImplementedException();
            }
            return desiredType;
        }
    }

这里的要点:1。Factory和AbstractFactory机制必须使用继承(System。对象->字节,浮点…所以如果你在程序中有继承,那么根据设计2,工厂(抽象工厂很可能不在那里)已经在那里了。Creator (MyFactory)知道具体类型,因此返回具体类型对象给调用者(Main);在抽象工厂中,返回类型是一个接口。

interface IVehicle { string VehicleName { get; set; } }
interface IVehicleFactory
    {
        IVehicle CreateSingleVehicle(string vehicleType);
    }
class HondaFactory : IVehicleFactory
    {
        public IVehicle CreateSingleVehicle(string vehicleType)
        {
            switch (vehicleType)
            {
                case "Sports": return new SportsBike();
                case "Regular":return new RegularBike();
                default: throw new ApplicationException(string.Format("Vehicle '{0}' cannot be created", vehicleType));
            }
        }
    }
class HeroFactory : IVehicleFactory
    {
        public IVehicle CreateSingleVehicle(string vehicleType)
        {
            switch (vehicleType)
            {
                case "Sports":  return new SportsBike();
                case "Scooty": return new Scooty();
                case "DarkHorse":return new DarkHorseBike();
                default: throw new ApplicationException(string.Format("Vehicle '{0}' cannot be created", vehicleType));
            }
        }
    }

class RegularBike : IVehicle { public string VehicleName { get { return "Regular Bike- Name"; } set { VehicleName = value; } } }
class SportsBike : IVehicle { public string VehicleName { get { return "Sports Bike- Name"; } set { VehicleName = value; } } }
class RegularScooter : IVehicle { public string VehicleName { get { return "Regular Scooter- Name"; } set { VehicleName = value; } } }
class Scooty : IVehicle { public string VehicleName { get { return "Scooty- Name"; } set { VehicleName = value; } } }
class DarkHorseBike : IVehicle { public string VehicleName { get { return "DarkHorse Bike- Name"; } set { VehicleName = value; } } }

class Program
{
    static void Main(string[] args)
    {
        IVehicleFactory honda = new HondaFactory(); //1
        RegularBike hondaRegularBike = (RegularBike)honda.CreateSingleVehicle("Regular"); //2
        SportsBike hondaSportsBike = (SportsBike)honda.CreateSingleVehicle("Sports");
        Console.WriteLine("******* Honda **********"+hondaRegularBike.VehicleName+ hondaSportsBike.VehicleName);

        IVehicleFactory hero = new HeroFactory();
        DarkHorseBike heroDarkHorseBike = (DarkHorseBike)hero.CreateSingleVehicle("DarkHorse");
        SportsBike heroSportsBike = (SportsBike)hero.CreateSingleVehicle("Sports");
        Scooty heroScooty = (Scooty)hero.CreateSingleVehicle("Scooty");
        Console.WriteLine("******* Hero **********"+heroDarkHorseBike.VehicleName + heroScooty.VehicleName+ heroSportsBike.VehicleName);

        Console.ReadKey();
    }
}

Important points: 1. Requirement: Honda would create "Regular", "Sports" but Hero would create "DarkHorse", "Sports" and "Scooty". 2. why two interfaces? One for manufacturer type(IVehicleFactory) and another for product factory(IVehicle); other way to understand 2 interfaces is abstract factory is all about creating related objects 2. The catch is the IVehicleFactory's children returning and IVehicle(instead of concrete in factory); so I get parent variable(IVehicle); then I create actual concrete type by calling CreateSingleVehicle and then casting parent object to actual child object. What would happen if I do RegularBike heroRegularBike = (RegularBike)hero.CreateSingleVehicle("Regular");; you will get ApplicationException and that's why we need generic abstract factory which I would explain if required. Hope it helps from beginner to intermediate audience.


现实生活中的例子。(容易记)

工厂

想象一下,你正在建造一所房子,你找一个木匠开一扇门。你给他门的尺寸和你的要求,他就会为你造一扇门。在这种情况下,木匠是门的工厂。你的规格是工厂的输入,门是工厂的输出或产品。

抽象工厂

现在,考虑同样的门的例子。你可以去找木匠,也可以去塑料门店或PVC店。他们都是门厂。根据情况,你决定你需要接触什么样的工厂。这就像一个抽象工厂。

我在这里解释了工厂方法模式和抽象工厂模式,从不使用它们来解释问题开始,然后通过使用上述模式来解决问题 https://github.com/vikramnagineni/Design-Patterns/tree/master


请允许我准确地说。大多数答案都已经解释过了,还提供了图表和例子。

所以我的回答就是一句话。我的原话是:“抽象工厂模式在抽象层上添加了多个工厂方法实现。它意味着一个抽象工厂包含或组合一个或多个工厂方法模式。


之前的很多回答都没有提供抽象工厂和工厂方法模式之间的代码比较。下面是我试图用Java来解释它。我希望它能帮助那些需要简单解释的人。

正如GoF所言:抽象工厂提供了一个接口,无需指定就可以创建相关或依赖的对象族 具体的阶级。

public class Client {
    public static void main(String[] args) {
        ZooFactory zooFactory = new HerbivoreZooFactory();
        Animal animal1 = zooFactory.animal1();
        Animal animal2 = zooFactory.animal2();
        animal1.sound();
        animal2.sound();

        System.out.println();

        AnimalFactory animalFactory = new CowAnimalFactory();
        Animal animal = animalFactory.createAnimal();
        animal.sound();
    }
}

public interface Animal {
    public void sound();
}

public class Cow implements Animal {

    @Override
    public void sound() {
        System.out.println("Cow moos");
    }
}

public class Deer implements Animal {

    @Override
    public void sound() {
        System.out.println("Deer grunts");
    }

}

public class Hyena implements Animal {

    @Override
    public void sound() {
        System.out.println("Hyena.java");
    }

}

public class Lion implements Animal {

    @Override
    public void sound() {
        System.out.println("Lion roars");
    }

}

public interface ZooFactory {
    Animal animal1();

    Animal animal2();
}

public class CarnivoreZooFactory implements ZooFactory {

    @Override
    public Animal animal1() {
        return new Lion();
    }

    @Override
    public Animal animal2() {
        return new Hyena();
    }

}

public class HerbivoreZooFactory implements ZooFactory {

    @Override
    public Animal animal1() {
        return new Cow();
    }

    @Override
    public Animal animal2() {
        return new Deer();
    }

}

public interface AnimalFactory {
    public Animal createAnimal();
}

public class CowAnimalFactory implements AnimalFactory {

    @Override
    public Animal createAnimal() {
        return new Cow();
    }

}

public class DeerAnimalFactory implements AnimalFactory {

    @Override
    public Animal createAnimal() {
        return new Deer();
    }

}

public class HyenaAnimalFactory implements AnimalFactory {

    @Override
    public Animal createAnimal() {
        return new Hyena();
    }

}

public class LionAnimalFactory implements AnimalFactory {

    @Override
    public Animal createAnimal() {
        return new Lion();
    }

}

抽象工厂与工厂方法的主要区别在于,抽象工厂是由组合实现的;但是工厂方法是通过继承实现的。

是的,您没有看错:这两种模式之间的主要区别在于古老的组合与继承之争。

UML图可以在(GoF)书中找到。我想提供代码示例,因为我认为将本文中前两个答案中的示例结合起来会比单独一个答案提供更好的演示。此外,我在类名和方法名中使用了书中的术语。

抽象工厂

The most important point to grasp here is that the abstract factory is injected into the client. This is why we say that Abstract Factory is implemented by Composition. Often, a dependency injection framework would perform that task; but a framework is not required for DI. The second critical point is that the concrete factories here are not Factory Method implementations! Example code for Factory Method is shown further below. And finally, the third point to note is the relationship between the products: in this case the outbound and reply queues. One concrete factory produces Azure queues, the other MSMQ. The GoF refers to this product relationship as a "family" and it's important to be aware that family in this case does not mean class hierarchy.

public class Client {
    private final AbstractFactory_MessageQueue factory;

    public Client(AbstractFactory_MessageQueue factory) {
        // The factory creates message queues either for Azure or MSMQ.
        // The client does not know which technology is used.
        this.factory = factory;
    }

    public void sendMessage() {
        //The client doesn't know whether the OutboundQueue is Azure or MSMQ.
        OutboundQueue out = factory.createProductA();
        out.sendMessage("Hello Abstract Factory!");
    }

    public String receiveMessage() {
        //The client doesn't know whether the ReplyQueue is Azure or MSMQ.
        ReplyQueue in = factory.createProductB();
        return in.receiveMessage();
    }
}

public interface AbstractFactory_MessageQueue {
    OutboundQueue createProductA();
    ReplyQueue createProductB();
}

public class ConcreteFactory_Azure implements AbstractFactory_MessageQueue {
    @Override
    public OutboundQueue createProductA() {
        return new AzureMessageQueue();
    }

    @Override
    public ReplyQueue createProductB() {
        return new AzureResponseMessageQueue();
    }
}

public class ConcreteFactory_Msmq implements AbstractFactory_MessageQueue {
    @Override
    public OutboundQueue createProductA() {
        return new MsmqMessageQueue();
    }

    @Override
    public ReplyQueue createProductB() {
        return new MsmqResponseMessageQueue();
    }
}

工厂方法

The most important point to grasp here is that the ConcreteCreator is the client. In other words, the client is a subclass whose parent defines the factoryMethod(). This is why we say that Factory Method is implemented by Inheritance. The second critical point is to remember that the Factory Method Pattern is nothing more than a specialization of the Template Method Pattern. The two patterns share an identical structure. They only differ in purpose. Factory Method is creational (it builds something) whereas Template Method is behavioral (it computes something). And finally, the third point to note is that the Creator (parent) class invokes its own factoryMethod(). If we remove anOperation() from the parent class, leaving only a single method behind, it is no longer the Factory Method pattern. In other words, Factory Method cannot be implemented with less than two methods in the parent class; and one must invoke the other.

public abstract class Creator {
    public void anOperation() {
        Product p = factoryMethod();
        p.whatever();
    }

    protected abstract Product factoryMethod();
}

public class ConcreteCreator extends Creator {
    @Override
    protected Product factoryMethod() {
        return new ConcreteProduct();
    }
}

混杂。&杂项工厂图案

请注意,尽管GoF定义了两种不同的工厂模式,但它们并不是唯一存在的工厂模式。它们甚至不一定是最常用的工厂模式。第三个著名的例子是Josh Bloch的《Effective Java》中的静态工厂模式。《头部优先设计模式》一书还包括另一种被称为简单工厂的模式。

不要落入假设每个工厂模式都必须匹配GoF中的一个模式的陷阱。


工厂方法依赖于继承:对象创建被委托给子类,子类实现了工厂方法来创建对象。

抽象工厂依赖于对象组合:对象创建是在工厂接口中公开的方法中实现的。

工厂和抽象工厂模式的高级图表,

有关Factory方法的更多信息,请参阅本文。

有关抽象工厂方法的更多信息,请参阅本文。


抽象工厂:工厂中的工厂;将独立但相关/依赖的工厂分组在一起,而不指定它们的具体类的工厂。 抽象工厂实例

Factory:它提供了一种将实例化逻辑委托给子类的方法。 工厂模式示例


abstract factory design pattern with realtime example: what is an abstract factory design pattern? It is similar to the factory method design pattern. we need to use this pattern when we have multiple factories. there will be a grouping of factories defined in this pattern. factory method pattern is a subset of abstract factory design pattern. They have the same advantages as factory patterns. abstract factory relies on object composition whereas the factory method deals with inheritance. factory design pattern in java with a realtime example: what is the factory design pattern? it is mostly used design in object-oriented programming. It is one of the creational patterns. it is all about creating instances. Clients will create the object without exposed to object creational logic. it is widely used in different frameworks ex: the spring framework. we use this pattern when the class doesn’t know the objects of another it must create. Realtime example: when our car breaks down on the road. We need to inform the repairman about what type of vehicle we are using so that repairman will carry tools to fix the repair. as per our input, the repairman will fix the issue and make it ready for us to travel again. There are a few built-in methods that use these patterns. example getInstance() method in JavaUtilcalendar class. With help of getInstance(), we can get objects whenever we execute this method. Javautilcalendar : getInstance() is method return object. https://trendydevx.com/factory-design-pattern-in-java-with-realtime-example/


有相当多的定义。基本上,描述工厂模式的三种常用方法是

简单的工厂

基于条件的简单对象创建方法/类。

工厂方法

使用子类提供实现的工厂方法设计模式。

抽象工厂

抽象工厂设计模式产生相关或依赖的对象族,而不指定它们的具体类。

下面的链接非常有用-工厂比较-重构。guru


工厂设计模式

generation 1 <- generation 2 <- generation 3
//example
(generation 1) shape <- (generation 2) rectangle, oval <- (generation 3) rectangle impressionism, rectangle surrealism, oval impressionism, oval surrealism

工厂

用例:实例化第2代的一个对象

这是一种创造模式,允许你在一个简单的地方创建第2代。它符合SRP和OCP -所有的更改都在一个类中进行。

enum ShapeType {
    RECTANGLE,
    OVAL
}

class Shape {}

//Concrete Products
//generation 2
class Rectangle extends Shape {}
class Oval extends Shape {}

//Factory
class Factory {
    Shape createShape(ShapeType type) {

        switch (type) {
            case RECTANGLE:
                return new Rectangle();
            case OVAL:
                return new Oval();
        }
    }
}

//Creator
class Painter {

    private Factory factory;

    Painter(Factory factory) {
        this.factory = factory;
    }

    Shape prepareShape(ShapeType type) {
        return factory.createShape(type);
    }
}

//using
class Main {
    void main() {
        Painter painter = new Painter(new Factory());

        Shape shape1 = painter.prepareShape(ShapeType.RECTANGLE);
        Shape shape2 = painter.prepareShape(ShapeType.OVAL);
    }
}

工厂方法

用例:实例化第3代的一个对象

有助于与下一代家庭成员合作。每个画家都有自己的风格,印象派、超现实主义……工厂方法使用抽象创造者作为工厂(抽象方法),具体创造者是这种方法的实现

enum ShapeType {
    RECTANGLE,
    OVAL
}

class Shape {}

//Concrete Products
//generation 2
class Rectangle extends Shape {}
class Oval extends Shape {}

//generation 3
class RectangleImpressionism extends Rectangle {}
class OvalImpressionism extends Oval {}
class RectangleSurrealism extends Rectangle {}
class OvalSurrealism extends Oval {}

//Creator
abstract class Painter {

    Shape prepareShape(ShapeType type) {
        return createShape(type);
    }

    //Factory method
    abstract Shape createShape(ShapeType type);
}

//Concrete Creators
class PainterImpressionism {

    @override
    Shape createShape(ShapeType type) {
        switch (type) {
            case RECTANGLE:
                return new RectangleImpressionism();
            case OVAL:
                return new OvalImpressionism();
        }
    }
}

class PainterSurrealism {

    @override
    Shape createShape(ShapeType type) {
        switch (type) {
            case RECTANGLE:
                return new RectangleSurrealism();
            case OVAL:
                return new OvalSurrealism();
        }
    }
}

//using
class Main {
    void main() {
        Painter painterImpressionism = new PainterImpressionism();
        Shape shape1 = painterImpressionism.prepareShape(ShapeType.RECTANGLE);

        Painter painterSurrealism = new PainterSurrealism();
        Shape shape2 = painterSurrealism.prepareShape(ShapeType.RECTANGLE);
    }
}

抽象工厂

用例:实例化第3代的所有对象

工厂是抽象工厂和具象工厂的一部分


//Concrete Products
//generation 2
class Rectangle extends Shape {}
class Oval extends Shape {}

//generation 3
class RectangleImpressionism extends Rectangle {}
class OvalImpressionism extends Oval {}
class RectangleSurrealism extends Rectangle {}
class OvalSurrealism extends Oval {}

//Abstract Factory
interface Factory {
    Rectangle createRectangle();
    Oval createOval();
}

//Concrete Factories
class ImpressionismFactory implements Factory {
    @Override
    public Rectangle createRectangle() {
        return new RectangleImpressionism();
    }

    @Override
    public Oval createOval() {
        return new OvalImpressionism();
    }
}

class SurrealismFactory implements Factory {
    @Override
    public Rectangle createRectangle() {
        return new RectangleSurrealism();
    }

    @Override
    public Oval createOval() {
        return new OvalSurrealism();
    }
}

//Creator
class Painter {

    Rectangle rectangle;
    Oval oval;

    Painter(Factory factory) {
        rectangle = factory.createRectangle();
        rectangle.resize();

        oval = factory.createOval();
        oval.resize();
    }
}

//using
class Main {
    void main() {
        Painter painter1 = new Painter(new ImpressionismFactory());
        Shape shape1 = painter1.rectangle;
        Shape shape2 = painter1.oval;

        Painter painter2 = new Painter(new ImpressionismFactory());
        Shape shape3 = painter2.rectangle;
        Shape shape4 = painter1.oval;
    }
}

A)工厂方法模式

工厂方法是一种创建设计模式,它提供了创建对象的接口,但允许子类改变将要创建的对象的类型。

如果在基类和扩展它的子类中有一个创建方法,您可能会考虑工厂方法。

B)抽象工厂模式

抽象工厂是一种创造性的设计模式,允许在不指定具体类的情况下产生相关或依赖的对象族。

什么是“对象族”?例如,以这组类为例:传输+引擎+控制。这些可能有几种变体:

1-汽车+内燃机+方向盘

2-平面+ JetEngine +轭

如果你的程序不使用产品族,那么你就不需要抽象工厂。

同样,很多人混淆了抽象工厂模式和简单的工厂类声明为抽象。不要那样做!

裁判:https://refactoring.guru/design-patterns/factory-comparison


据我估计,@TomDalling给出的答案确实是正确的(不管它有什么价值),但是评论中似乎仍然有很多困惑。

我在这里所做的是为这两种模式创建一些略显非典型的示例,并试图使它们乍一看非常相似。这将有助于查明将它们分开的关键差异。

如果您对这些模式完全不熟悉,那么这些示例可能不是最好的开始。

工厂方法

Client.javaish

Client(Creator creator) {
    ProductA a = creator.createProductA();
}

Creator.javaish

Creator() {}

void creatorStuff() {
    ProductA a = createProductA();
    a.doSomething();
    ProductB b = createProductB();
    b.doStuff();
}

abstract ProductA createProductA();

ProductB createProductB() {
    return new ProductB1();
}

为什么会有创造者和客户?

为什么不呢?FactoryMethod可以与两者一起使用,但它将是决定所创建的特定产品的Creator类型。

为什么createProductB在Creator中不是抽象的?

可以提供默认实现,子类仍然可以覆盖该方法以提供自己的实现。

我以为工厂方法只生产一种产品?

每个方法只返回一个产品,但创建者可以使用多个工厂方法,只是它们不一定以任何特定的方式相关。

抽象工厂

Client.javaish

AbstractFactory factory;

Client() {
    if (MONDAY) {
        factory = new Factory2();
    } else {
        factory = new AbstractFactory();
    }
}

void clientStuff() {
    ProductA a = factory.createProductA();
    a.doSomething();
    ProductB b = factory.createProductB();
    b.doStuff();
}

等等!你的AbstractFactory不是,嗯……er文摘

没关系,我们仍然在提供接口。create方法的返回类型是我们想要生成的产品的超类型。

圣烟蝙蝠侠!Factory2没有覆盖createProductA(),“产品族”发生了什么?

模式中并没有说一个对象不能属于一个以上的家族(尽管您的用例可能禁止这样做)。每个混凝土工厂负责决定哪些产品可以一起生产。

这是不对的,客户端没有使用依赖注入

您必须决定某个地方的具体类是什么,客户机仍然被写入AbstractFactory接口。

这里的混淆在于人们将组合与依赖注入混为一谈。客户端拥有一个AbstractFactory,而不管它是如何得到它的。与IS-A关系相比,Client和AbstractFactory之间没有继承关系。

关键的不同点

抽象工厂总是关于对象的家族 工厂方法只是一个允许子类指定具体对象类型的方法 抽象工厂为客户端提供了一个接口,它与产品的使用位置是分开的,工厂方法可以由创建者自己使用,也可以暴露给客户端。

总结

工厂的目的是为客户端或工厂本身提供对象。

创建者有自己的职责,可能需要使用对象或将对象传递给客户端

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

抽象工厂:

提供一个接口来创建相关或依赖的对象族,而不指定它们的具体类。——GoF


PlantUML代码,如果你想玩图:

@startuml FactoryMethod
abstract class Creator {
    creatorStuff()
    {abstract} createProductA(): ProductA
    createProductB(): ProductB
}
class Creator1 {
    createProductA(): ProductA
}
class Creator2 {
    createProductA(): ProductA
    createProductB(): ProductB
}

together {
    interface ProductA {
        doSomething()
    }
    class ProductA1
    ' class Product1B
}
together {
    interface ProductB {
        doStuff()
    }
    class ProductB1
    class ProductB2
}
Client --> Creator

Creator <|-- Creator1
Creator <|-- Creator2

Creator --> ProductB1
ProductA1 <-- Creator1
ProductA1 <-- Creator2
ProductB2 <-- Creator2

ProductA <|.. ProductA1
ProductB <|.. ProductB1
ProductB <|.. ProductB2

ProductA <- Creator

@enduml
@startuml AbstractFactory

together {
    interface ProductA {
        doSomething()
    }
    class ProductA1
}

together {
    interface ProductB {
        doStuff()
    }
    class ProductB1
    class ProductB2
}

class AbstractFactory {
    createProductA(): ProductA
    createProductB(): ProductB
    --
    -
}

class Factory2 {
    createProductB(): ProductB
}

Client --> AbstractFactory
AbstractFactory <|-- Factory2

ProductA <|.. ProductA1
ProductB <|.. ProductB1
ProductB <|.. ProductB2

AbstractFactory --> ProductA1
AbstractFactory --> ProductB1
ProductB2 <-- Factory2

@enduml

My conclusion: there is no difference. Why? Because I cannot see any justification to equip objects other than factories with factory methods - otherwise you get a violation of the separation of responsibility principle. In addition, I cannot see any difference between a factory with a single factory method and a factory with multiple factory methods: both create "families of related objects" unless anyone can prove that a single-family-member family is not a family. Or a collection that contains a single item is not a collection.