首页 文章

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

提问于
浏览
133

我正在从网站上阅读设计模式

在那里我读到了有关工厂,工厂方法和抽象工厂的信息,但是它们很混乱,我对定义并不清楚 . 根据定义

Factory - 创建对象而不将实例化逻辑暴露给客户端,并通过公共接口引用新创建的对象 . Factory Method Factory方法的简化版本 - 定义用于创建对象的接口,但让子类决定实例化哪个类,并通过公共接口引用新创建的对象 . 抽象工厂 - 提供用于创建相关对象族的界面,而无需明确指定其类 .

我还查看了关于抽象工厂与工厂方法的其他stackoverflow线程,但是那里绘制的UML图使我的理解更加糟糕 .

任何人都可以告诉我

  • 这三种模式如何相互不同?

  • 何时使用哪个?

  • 如果可能的话,还有与这些模式相关的任何java示例吗?

5 回答

  • 187

    所有三种工厂类型都做同样的事情:它们是“智能构造函数” .

    假设您希望能够创建两种水果:Apple和Orange .

    工厂

    工厂是“固定的”,因为你只有一个没有子类化的实现 . 在这种情况下,您将拥有这样的类:

    class FruitFactory {
    
      public Apple makeApple() {
        // Code for creating an Apple here.
      }
    
      public Orange makeOrange() {
        // Code for creating an orange here.
      }
    
    }
    

    使用案例:构造Apple或Orange有点太复杂,无法在构造函数中处理 .

    工厂方法

    工厂方法通常在类中进行一些通用处理时使用,但想要改变实际使用的水果种类 . 所以:

    abstract class FruitPicker {
    
      protected abstract Fruit makeFruit();
    
      public void pickFruit() {
        private final Fruit f = makeFruit(); // The fruit we will work on..
        <bla bla bla>
      }
    }
    

    ...然后,您可以通过在子类中实现工厂方法来重用 FruitPicker.pickFruit() 中的常用功能:

    class OrangePicker extends FruitPicker {
    
      @Override
      protected Fruit makeFruit() {
        return new Orange();
      }
    }
    

    抽象工厂

    抽象工厂通常用于依赖注入/策略之类的东西,当你想要能够创建一整套需要“同类”的对象时,并且有一些共同的基类 . 这是一个与水果有关的模糊例子 . 这里的用例是我们要确保我们不会在Apple上意外使用OrangePicker . 只要我们从同一家工厂获得我们的水果和采摘器,他们就会匹配 .

    interface PlantFactory {
    
      Plant makePlant();
    
      Picker makePicker(); 
    
    }
    
    public class AppleFactory implements PlantFactory {
      Plant makePlant() {
        return new Apple();
      }
    
      Picker makePicker() {
        return new ApplePicker();
      }
    }
    
    public class OrangeFactory implements PlantFactory {
      Plant makePlant() {
        return new Orange();
      }
    
      Picker makePicker() {
        return new OrangePicker();
      }
    }
    
  • 16

    这三种模式如何相互不同?

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

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

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

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

    何时使用哪个?

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

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

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

    抽象工厂类通常使用Factory Method实现 . 工厂方法通常在模板方法中调用 .

    如果可能,还有与这些模式相关的任何java示例?

    Factory and FactoryMethod

    Intent:

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

    UML diagram

    enter image description here

    Product:它定义Factory方法创建的对象的接口 .

    ConcreteProduct:实现产品界面

    创建者:声明工厂方法

    ConcreateCreator:实现Factory方法以返回ConcreteProduct的实例

    问题陈述:使用工厂方法创建游戏工厂,工厂方法定义游戏界面 .

    代码段:

    Factory Pattern. When to use factory methods?

    与其他创作模式比较:

    • 设计开始时使用 Factory Method (不那么复杂,可定制,子类增加)并逐渐向 Abstract Factory, Prototype, or Builder (更灵活,更复杂)发展,因为设计师发现需要更多灵活性的地方

    • Abstract Factory 类通常使用 Factory Methods 实现,但它们也可以使用 Prototype 实现

    进一步阅读的参考文献:Sourcemaking design-patterns

  • 0

    Factory - 单独的Factory类以创建复杂对象 .

    Ex:FruitFactory类创建Fruit的对象

    class FruitFactory{
    
    public static Fruit getFruit(){...}
    
    }
    

    Factory Method - 而不是工厂的整个单独的类,只需在该类中添加一个方法作为工厂 .

    例如:

    Calendar.getInstance() (Java's Calendar)
    

    Abstract Factory Method - 工厂工厂

    例如:假设我们想建造工厂电脑零件 . 因此有几种类型的计算机,如笔记本电脑,台式机,服务器 .

    因此,对于每种计算机类型,我们需要工厂 . 因此,我们创建了一个高级工厂,如下所示

    ComputerTypeAbstractFactory.getComputerPartFactory(String computerType) ---> This will return PartFactory which can be one of these ServerPartFactory, LaptopPartFactory, DesktopPartFactory.
    

    现在这3个本身又是工厂 . (您将处理PartFactory本身,但在引擎盖下,将根据您在抽象工厂中提供的内容进行单独实现)

    Interface-> PartFactory. getComputerPart(String s), 
    Implementations -> ServerPartFactory, LaptopPartFactory, DesktopPartFactory.
    
    Usage:
    new ComputerTypeAbstractFactory().getFactory(“Laptop”).getComputerPart(“RAM”)
    

    编辑:根据评论中的异议编辑,为抽象工厂提供精确的界面 .

  • 19

    每种设计模式都蓬勃发展,有助于确保不会触及书面的工作代码 . 我们都知道,一旦我们触及工作代码,现有工作流程就会出现缺陷,需要完成更多的测试才能确保我们不会破坏任何内容 .

    工厂模式根据输入条件创建对象,从而确保您不需要编写代码,就像这样创建此类对象,否则此类对象 . 一个很好的例子是旅游网站 . 旅游网站只能提供旅行(航班,火车,公共汽车)或/和提供酒店或/和提供旅游景点套餐 . 现在,当用户选择下一个时,网站需要决定需要创建哪些对象 . 它应该只创建旅行或酒店对象 .

    现在,如果您想要在您的投资组合中添加另一个网站,并且您认为使用相同的核心,例如拼车网站,现在搜索出租车并在线进行付款,您可以在您的核心使用抽象工厂 . 这样你就可以再搭乘一个出租车和拼车车间 .

    两个工厂都没有任何关系,所以它是一个很好的设计,让他们在不同的工厂 .

    希望现在很清楚 . 再次研究网站,记住这个例子,希望它会有所帮助 . 我真的希望我能正确地代表模式:) .

  • 8
    AbstractProductA, A1 and A2 both implementing the AbstractProductA
    AbstractProductB, B1 and B2 both implementing the AbstractProductB
    
    interface Factory {
        AbstractProductA getProductA(); //Factory Method - generate A1/A2
    }
    

    使用Factory Method,用户可以创建AbstractProductA的A1或A2 .

    interface AbstractFactory {
        AbstractProductA getProductA(); //Factory Method
        AbstractProductB getProductB(); //Factory Method
    }
    

    但抽象工厂有超过1种工厂方法(例如:2种工厂方法),使用这些工厂方法,它将创建一组对象/相关对象 . 使用Abstract Factory,用户可以创建AbstractProductA,AbstractProductB的A1,B1对象

相关问题