简体   繁体   English

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

[英]GoF design patterns: different kinds of factory

I'm using GoF design patterns since a while and I found that I misunderstood some of them. 一段时间以来,我一直在使用GoF设计模式,但发现我误解了其中的一些模式。

I'm focused on Factory (not Abstract Factory). 我专注于工厂(不是抽象工厂)。 Until now, I've thought Factory was a class with several creational methods like BorderFactory in Java API: 直到现在,我还认为Factory是一个具有几种创建方法的类,例如Java API中的BorderFactory:

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

All methods returning the same kind of abstraction (eg interface). 所有方法都返回相同类型的抽象(例如接口)。

However, I've found that "Factory" in GoF (real name "Factory Method") is not really this kind of class, but a class with a unique method returning a concrete type depending on the input parameter (eg a string). 但是,我发现GoF中的“工厂”(实名“工厂方法”)实际上不是这种类,而是具有唯一方法的类,该方法根据输入参数(例如字符串)返回具体类型。 I'm using this kind of factory for parsing purposes (modeling language). 我将这种工厂用于解析目的(建模语言)。

GoF creational patterns are Factory Method, Abstract Factory, Builder, Singleton and Prototype. GoF的创建模式是工厂方法,抽象工厂,生成器,单例和原型。 There is no "Factory", unless Factory is considered as a refined Factory Method (too many input parameters -> need to define several createXXX methods) ? 没有“工厂”,除非将工厂视为精致的工厂方法(输入参数太多->需要定义多个createXXX方法)?

What do you think about this ? 你怎么看待这件事 ?

Thanks. 谢谢。

In OOP, static factories are indeed not known as GOF design patterns. 在OOP中,静态工厂确实不被称为GOF设计模式。
These are methods that allow to create and return objects. 这些方法允许创建和返回对象。
These has broad intentions such as : 这些具有广泛的意图,例如:

  • hiding to the clients some implementation details such as the runtime returned object. 向客户端隐藏一些实现细节,例如运行时返回的对象。
  • caching 高速缓存
  • proxying. 代理。
  • easing the API usage. 简化API使用。
  • replacing the constructors 替换构造函数

Note also that a static factory may not do any of these and just be used as a helper method to create objects. 还要注意, static工厂可能不会执行任何这些操作,而只是用作创建对象的辅助方法。 So it may use no OOP features at all, w which is not the case of factory method and of GOF design pattern in general. 因此,它可能根本不使用任何OOP功能,而通常不是工厂方法和GOF设计模式的情况。

There is no "Factory", unless Factory is considered as a refined Factory Method (too many input parameters -> need to define several createXXX methods) ? 没有“工厂”,除非将工厂视为精致的工厂方法(输入参数太多->需要定义多个createXXX方法)?

IHMO a factory method looks like more a variant of the static factory. IHMO工厂方法看起来更像是静态工厂的变体。
It doesn't have the same intention and is much more specialized : it doesn't abstract/hide the object creations but delegates it to some factory subclasses. 它没有相同的意图,并且更加专门:它不抽象/隐藏对象创建,而是将其委托给某些工厂子类。
Note also that the factory method can also rely on static factories to create their objects while the reverse is less obvious. 还要注意,工厂方法还可以依赖静态工厂来创建其对象,而相反的情况则不太明显。
So I consider this creational GOF pattern as more structuring than a static factory. 因此,我认为这种创新的GOF模式比static工厂更具结构性。

Example to illustrate : 举例说明:

An Animal can have children. Animal可以有孩子。 We have several subclass of Animal and only Animal subclasses should know which instance return for their children. 我们有几个子类Animal ,只有Animal子类应该知道哪些情况下返回自己的孩子。
Here we want to use a factory method as we let the instantiation task to subclasses. 这里我们要使用工厂方法,因为我们将实例化任务分配给子类。

You could so do : 您可以这样做:

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

And so for... 所以……

Ok, now suppose that LittleCat happens to have multiple constructors. 好的,现在假设LittleCat碰巧有多个构造函数。
It doesn't make the API simple. 它并没有使API变得简单。 Here we could use factory static methods instead of constructors to make things clearer : 在这里,我们可以使用工厂静态方法而不是构造函数来使事情更清楚:

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

And now the method factory relies on the static factory : 现在,方法工厂依赖于静态工厂:

public class Cat extends Animal {

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

You've stumbled upon exactly the situation that was described by GoF book authors 15 years after releasing the book: http://www.informit.com/articles/article.aspx?p=1404056 Just read thoroughly - 在发布本书15年后,您就偶然发现了GoF本书作者所描述的情况: http : //www.informit.com/articles/article.aspx? p = 1404056请仔细阅读-

Factory Method would be generalized to Factory 工厂方法将推广到工厂

My best suggestion to people is not to remember the canonical shape of GoF pattern or its implementation but rather to remember the idea behind the pattern. 我对人们的最佳建议不是记住GoF模式的规范形状或其实现,而是记住模式背后的想法。 The idea of that generalized Factory pattern would be to provide a method that is not a direct class' constructor and will return instances of its subclasses - either as interface references (preferred) or subclass instances. 通用Factory模式的想法是提供一种不是直接类的构造函数的方法,该方法将返回其子类的实例-作为接口引用(首选)或子类实例。 Indeed in modern languages the 'canonical' shape/implementation of GoF patterns doesn't make much sense frequently, but the idea behind each pattern totally makes sense as always - apply only when needed though. 确实,在现代语言中,GoF模式的“规范”形状/实现并不是很常见,但是每种模式背后的想法一如既往地有意义-尽管仅在需要时才适用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM