GoF设计模式:不同类型的工厂

时间:2019-01-11 08:24:25

标签: design-patterns factory-pattern factory-method

一段时间以来,我一直在使用GoF设计模式,但发现我误解了其中的一些。

我专注于工厂(不是抽象工厂)。 直到现在,我还认为Factory是一个具有几种创建方法的类,例如Java API中的BorderFactory:

  • 边界b1 = BorderFactory.createLineBorder(Color.RED)
  • 边界b2 = BorderFactory.createTitledBorder(“ Hello”)

所有返回相同抽象类型的方法(例如接口)。

但是,我发现GoF中的“ Factory”(真实名称为“ Factory Method”)并不是真正的此类,而是具有唯一方法的类根据输入参数返回具体类型(例如串)。我将这种工厂用于解析目的(建模语言)。

GoF创建模式是工厂方法,抽象工厂,构建器,单例和原型。没有“工厂”,除非将工厂视为精致的工厂方法(输入参数太多->需要定义多个createXXX方法)?

您对此有何看法?

谢谢。

2 个答案:

答案 0 :(得分:2)

在OOP中,静态工厂确实不被称为GOF设计模式。
这些方法允许创建和返回对象。
这些具有广泛的意图,例如:

  • 向客户端隐藏一些实现细节,例如运行时返回的对象。
  • 缓存
  • 代理。
  • 简化API的使用。
  • 替换构造函数

还要注意,static工厂可能不会执行任何这些操作,而只是用作创建对象的辅助方法。因此它可能根本不使用任何OOP功能 通常不是工厂方法和GOF设计模式的情况。

  

没有“工厂”,除非工厂被认为是精炼工厂   工厂方法(输入参数太多->需要定义多个   createXXX方法)?

IHMO工厂方法看起来更像是静态工厂的变体。
它没有相同的意图,并且更加专业化:它不抽象/隐藏对象创建,而是将其委托给某些工厂子类。
还要注意,工厂方法还可以依靠静态工厂来创建其对象,而相反的情况则不太明显。
因此,我认为这种创新的GOF模式比static工厂更具结构性。

示例说明:

Animal可以有孩子。我们有Animal个子类,只有Animal个子类应该知道哪个实例为其子代返回。
这里我们要使用工厂方法,因为我们将实例化任务分配给子类。

您可以这样做:

public abstract class Animal {
    public abstract ChildAnimal createChild(String name, LocalDate birthdate);
}

public class Dog extends Animal {

    @Override
    public ChildAnimal createChild(String name, LocalDate birthdate) {
        return new LittleDog(name, birthdate);
    }
}

public class Cat extends Animal {

    @Override
    public ChildAnimal createChild(String name, LocalDate birthdate) {
        return new LittleCat(name, birthdate);
    }
}

等等...

好吧,现在假设LittleCat碰巧有多个构造函数。
它并没有使API变得简单。 在这里,我们可以使用工厂静态方法而不是构造函数来使事情更清楚:

public class LittleCat implements ChildAnimal {


    static LittleCat withNameAndBirthDateAndParents(String name, LocalDate birthdate, Cat dad, Cat mom) {
        return new LittleCat("kitty", birthdate, dad, mom);
    }

    static LittleCat withNameAndBirthDate(String name, LocalDate birthdate) {
        return new LittleCat(name, birthdate, null, null);
    }

    static LittleCat withNoInformation() {
        return new LittleCat("kitty", LocalDate.now(), null, null);
    }


    private LittleCat(String name, LocalDate birthdate, Cat dad, Cat mom) {
        // implementation
    }
}

现在方法工厂依赖于静态工厂:

public class Cat extends Animal {

    @Override
    public ChildAnimal createChild(String name, LocalDate birthdate) {
        return LittleCat.withNameAndBirthDate(name, birthdate);
    }
}

答案 1 :(得分:1)

您误以为GoF图书作者在发布这本书15年后所描述的情况:http://www.informit.com/articles/article.aspx?p=1404056 只需仔细阅读-

  

Factory方法将通用化为Factory

我对人们的最佳建议不是记住GoF模式的规范形状或其实现,而是记住模式背后的想法。 通用Factory模式的想法是提供一种不是直接类的构造函数的方法,该方法将返回其子类的实例-作为接口引用(首选)或子类实例。 确实,在现代语言中,GoF模式的“规范”形状/实现并不是很常见,但是每种模式背后的想法一如既往地有意义-尽管仅在需要时才适用。