首页 文章

抽象工厂模式与工厂方法的区别

提问于
浏览
339

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

从我一直在阅读的内容中,我看到工厂方法模式允许您定义如何创建单个具体产品,但是从客户端隐藏实现,因为他们将看到通用产品 . 我的第一个问题是抽象工厂 . 它的作用是允许您创建具体对象的族(可以取决于您使用的特定工厂)而不仅仅是单个具体对象?抽象工厂是否只返回一个非常大的对象或许多对象,具体取决于您调用的方法?

我最后两个问题是关于我在很多地方看到过的单一引言:

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

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

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

任何帮助,尤其是最后一个问题,将不胜感激 .

14 回答

  • 3

    两者之间的差异

    “工厂方法”和“抽象工厂”之间的主要区别在于工厂方法是单个方法,抽象工厂是对象 . 我想很多人会把这两个术语弄糊涂,并开始互换使用它们 . 我记得当我学习它们时,我很难找到确切的差异 .

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

    ... Factory Method模式使用继承并依赖子类来处理所需的对象实例化 .

    引用假定对象在此处调用自己的工厂方法 . 因此,唯一可以改变返回值的东西就是子类 .

    抽象工厂是一个对象,它有多个工厂方法 . 看看你的报价的前半部分:

    ...使用抽象工厂模式,类通过组合将对象实例化的责任委托给另一个对象......

    他们're saying is that there is an object A, who wants to make a Foo object. Instead of making the Foo object itself (e.g., with a factory method), it'将获得一个不同的对象(抽象工厂)来创建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
    
  • 383

    Abstract factory 使用抽象方法创建一个基类,这些方法定义了应该创建的对象的方法 . 派生基类的每个工厂类都可以创建自己的每个对象类型的实现 .

    enter image description here

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

    enter image description here

    抽象工厂

    在下面的示例中,我们设计了一个接口,以便我们可以将队列创建与消息传递系统分离,从而可以为不同的队列系统创建实现,而无需更改代码库 .

    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 接口的目的 .

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

    摘要

    区别在于包含工厂方法 is not to create objects 的类的 intended purpose ,而抽象工厂只应用于创建对象 .

    在使用工厂方法时应该注意,因为在创建对象时很容易破坏LSP(Liskovs Substitution principle) .

  • 20

    Difference between AbstractFactory and Factory design patters are as follows:

    • Factory Method 仅用于创建一个产品,但 Abstract Factory 用于创建相关或相关产品的系列 .

    • Factory Method 模式向客户端公开了一个创建对象的方法,而在 Abstract Factory 的情况下,它们公开了一系列相关对象,这些对象可能包含这些Factory方法 .

    • Factory Method 模式隐藏单个对象的构造,其中 Abstract factory method 隐藏了一系列相关对象的构造 . 抽象工厂通常使用(一组)工厂方法实施 .

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

    • Factory Method 模式背后的想法是,它允许客户端不知道在运行时需要创建哪些具体类的情况,但只是想获得一个可以完成工作的类,而 AbstractFactory 模式是最好的当您的系统必须创建多个系列产品或者您希望提供产品库而不暴露实现细节时使用 .

    Factory Method Pattern Implementation:
    Factory Method UML

    AbstractFactory Pattern Implementation:

    Abstract Factory UML

  • 5

    Abstract Factory是一个用于创建相关产品的界面,但Factory Method只是一种方法 . 抽象工厂可以通过多种工厂方法实现 .

    Abstract Factory UML

  • 8

    Consider this example for easy understanding.

    电信公司提供什么?例如,宽带,电话线和移动设备,您被要求创建一个应用程序,以便向其客户提供产品 .

    通常你在这里做的是,创建产品,即宽带,电话线和移动产品,通过你的 Factory Method ,你知道你对这些产品有什么属性和它的直线前进 .

    现在,该公司希望为他们的客户提供他们的产品捆绑,即宽带,电话线和移动设备,这里有 Abstract Factory .

    换句话说, Abstract Factory 是其他工厂的组成,他们负责创建自己的产品, Abstract Factory 知道如何将这些产品放在更有意义的自身职责上 .

    在这种情况下, BundleFactory 是抽象工厂, BroadbandFactoryPhonelineFactoryMobileFactoryFactory . 更简单地说,这些工厂将有 Factory Method 来初始化各个产品 .

    请看下面的代码示例:

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

    抽象工厂和工厂方法的主要区别在于 Abstract Factory is implemented by Composition ;但 Factory Method is implemented by Inheritance .

    是的,你读得正确:这两种模式之间的主要区别在于旧的辩论 .

    我不打算在这里重现UML图,因为那些可以在很多地方找到 . 我想提供代码示例;但是,因为我认为结合这个帖子中前两个答案的例子比单独回答更好 . 另外,我已经将(GoF)书中使用的术语添加到类和方法名称中 .

    Abstract Factory

    • 这里要 grab 的最重要的一点是抽象工厂注入客户端 . 这就是为什么我们说抽象工厂是由Composition实现的 . 通常,依赖注入框架会执行该任务;但DI不需要框架 .

    • 第二个关键点是这里的具体工厂 are not 工厂方法实施!工厂方法的示例代码如下所示 .

    • 最后,要注意的第三点是产品之间的关系:在这种情况下是出站和回复队列 . 一个具体的工厂 生产环境 Azure队列,另一个MSMQ . GoF将此产品关系称为"family",重要的是要注意在这种情况下家庭并不意味着类层次结构 .

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

    Factory Method

    • 这里要 grab 的最重要的一点是 ConcreteCreator 是客户 . 换句话说,客户端是其父类定义 factoryMethod() 的子类 . 这就是为什么我们说Factory Method是通过继承实现的 .

    • 第二个关键点是要记住工厂方法模式只不过是模板方法模式的专业化 . 这两种模式具有相同的结构 . 它们的目的不同 . 工厂方法是创造性的(它构建一些东西)而模板方法是行为的(它计算某些东西) .

    • 最后,要注意的第三点是 Creator (父)类调用自己的 factoryMethod() . 如果我们从父类中删除 anOperation() ,只留下一个方法,则它不再是Factory Method模式 . 换句话说,在父类中使用少于两个方法不能实现Factory Method;一个人必须援引另一个人 .

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

    Misc. & Sundry Factory Patterns

    请注意,尽管GoF定义了两种不同的工厂模式,但这些模式并不是现有的唯一工厂模式 . 它们甚至不一定是最常用的工厂模式 . 着名的第三个例子是Josh Bloch的Effective Java的静态工厂模式 . Head First Design Patterns一书包含了另一种他们称之为Simple Factory的模式 .

    不要陷入假设每个工厂模式必须与GoF匹配的模式 .

  • 0

    让我们说清楚大多数时间在 生产环境 代码中,我们使用抽象工厂模式,因为类A用接口B编程.A需要创建实例B.所以A必须有一个工厂对象来生成B的实例 . 所以A不依赖于B的任何具体实例 . 希望它有所帮助 .

  • 3

    Understand the differences in the motivations:

    假设您正在构建一个工具,您可以在其中创建对象,并具体实现对象的相互关系 . 由于您预见到对象的变化,因此您通过将创建对象变体的责任分配给另一个对象(我们称之为抽象工厂)来创建间接 . 这种抽象发现了很大的好处,因为您预见到将来扩展需要这些对象的变体 .

    在这一系列思路中另一个相当有趣的动机是整个组中的每个或每个对象都将具有相应的变体 . 基于某些条件,将使用任一变体,并且在每种情况下,所有对象必须具有相同的变体 . 理解这可能有点反直觉,因为我们经常认为 - 只要对象的变体遵循一个统一的统一 Contract (广义上的接口),具体的实现代码就永远不会破坏 . 这里有趣的事实是,并非总是如此,特别是当预期行为无法通过编程 Contract 建模时 .

    一个简单的(借用GoF的想法)是任何GUI应用程序都说虚拟监视器模仿MS或Mac或Fedora OS的外观 . 这里,例如,当窗口,按钮等所有窗口小部件对象具有MS变体时,除了从MAC变体派生的滚动条之外,该工具的目的严重失败 .

    上述情况构成了 Abstract Factory Pattern 的基本需求 .

    另一方面,假设您正在编写一个框架,以便许多人可以使用您的框架构建各种工具(例如上面示例中的一个) . 根据框架的想法,您不需要,尽管您不能在逻辑中使用具体对象 . 您宁愿在各种对象之间 Build 一些高级别的 Contract 以及它们如何交互 . 虽然您(作为框架开发人员)仍处于非常抽象的层次,但该工具的每个构建者都被迫遵循您的框架结构 . 但是,它们(工具构建器)可以自由决定要构建的对象以及它们创建的所有对象将如何交互 . 与之前的案例(抽象工厂模式)不同,您(作为框架创建者)在这种情况下不需要使用具体对象;而是可以保持对象的 Contract 级别 . 此外,与之前动机的第二部分不同,您或工具制造商从不会遇到混合变体对象的情况 . 在这里,虽然框架代码仍然处于 Contract 级别,但每个工具构建器都受限制(根据案例本身的性质)使用自己的对象 . 在这种情况下,对象创建委托给每个实现者,框架提供者只提供创建和返回对象的统一方法 . 对于框架开发人员来说,这些方法不可避免地要继续使用他们的代码,并且具有一个名为 Factory method 的特殊名称(底层模式的工厂方法模式) .

    Few Notes:

    • 如果您熟悉'模板方法',那么您会发现,如果程序与任何形式的框架相关,通常会从模板方法调用工厂方法 . 相比之下,应用程序的模板方法通常是特定算法的简单实现和工厂方法的无效 .

    • 此外,为了思想的完整性,使用框架(如上所述),当工具构建器正在构建工具时,在每个工厂方法内,而不是创建具体对象,他/她可以进一步将责任委托给抽象工厂对象,只要工具构建器预见到具体对象的变体以供将来扩展 .

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

    我的第一个问题是抽象工厂 . 它的作用是允许您创建具体对象的族(可以取决于您使用的特定工厂)而不仅仅是单个具体对象?

    是 . 抽象工厂的意图是:

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


    抽象工厂是否只返回一个非常大的对象或许多对象,具体取决于您调用的方法?

    理想情况下,它应该根据客户端调用的方法返回一个对象 .

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

    是 . 工厂方法使用继承 .

    Abstract Factory模式通过组合将对象实例化的责任委托给另一个对象?这是什么意思?

    AbstractFactory定义了FactoryMethod,ConcreteFactory负责构建ConcreteProduct . 只需按照article中的代码示例进行操作即可 .

    你可以找到更多细节相关的SE帖子:

    What is the basic difference between the Factory and Abstract Factory Patterns?

    Design Patterns: Factory vs Factory method vs Abstract Factory

  • 0

    要使界面最小化非常简单,请关注“// 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.Object-> byte,float ...);因此,如果你在程序中有继承,那么Factory(抽象工厂最不可能存在)已经存在于设计中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();
        }
    }
    

    要点:1 . 要求:本田将创建"Regular","Sports"但Hero将创建"DarkHorse","Sports"和"Scooty" . 2.为什么两个接口?一个用于制造商类型(IVehicleFactory),另一个用于产品工厂(IVehicle);理解2个接口的其他方法是抽象工厂是关于创建相关对象2.捕获是IVehicleFactory的子返回和IVehicle(而不是工厂中的具体);所以我得到父变量(IVehicle);然后我通过调用CreateSingleVehicle创建实际的具体类型,然后将父对象转换为实际的子对象 . 如果我这样做会怎么样 RegularBike heroRegularBike = (RegularBike)hero.CreateSingleVehicle("Regular"); ;您将获得ApplicationException,这就是我们需要通用抽象工厂的原因,如果需要我会解释 . 希望从初学者到中级受众有所帮助 .

  • 3

    真实生活的例子 . (容易记住)

    想象一下,你正在建造一所房子,然后你会接近木匠的门 . 你给出门和你的要求的测量,他将为你建造一扇门 . 在这种情况下,木匠是门的工厂 . 您的规格是工厂的输入,门是工厂的输出或产品 .

    抽象工厂

    现在,考虑门的相同例子 . 你可以去木匠,或者你可以去塑料门店或PVC商店 . 他们都是门工厂 . 根据具体情况,您可以决定需要接近哪种工厂 . 这就像一个抽象工厂 .

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

  • 2

    我随时都喜欢抽象工厂而不是工厂方法 . 从上面的Tom Dalling的例子(很好的解释),我们可以看到抽象工厂更可组合,因为我们需要做的就是将不同的工厂传递给构造函数(这里使用构造函数依赖注入) . 但是Factory Method要求我们引入一个新类(更多要管理的东西)并使用子类 . 总是喜欢组合而不是继承 .

  • 96

    请允许我准确地说出来 . 大多数答案已经解释过了,也提供了图表和示例 . 所以我的anwer只是一个班轮 . 我自己的话: - “abstract factory pattern adds on the abstract layer over multiple factory method implementations. means abstract factory contains or composite one or more than one factory method patterns”

  • 80

    上面的很多答案都没有提供抽象工厂和工厂方法模式之间的代码比较 . 以下是我尝试通过Java解释它 . 希望它可以帮助需要简单解释的人 .

    正如GoF恰当地说:Abstract Factory提供了一个接口,用于创建相关或依赖对象的族,而无需指定其具体类 .

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

相关问题