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

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。这就是使用继承来处理对象实例化的意思吗?

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

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


当前回答

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

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

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


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

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

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

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

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

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

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

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

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

其他回答

为了使它非常简单,界面最小,请关注“//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.

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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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