这段代码是实现'工厂模式',工厂方法,两者都没有?

时间:2016-07-11 14:05:12

标签: java factory-pattern

尽管已经多次讨论过这个问题,但我仍然发现自己对此过于困惑。

我有这个简单的代码示例:

public class FruitFactory {

    public static Apple getApple() {
        return new Apple();
    }

    public static Banana getBanana() {
        return new Banana();
    }

    public static Orange getOrange() {
        return new Orange();
    }
}
  • 此代码是Factory 类型?它是factory methods的正确写作吗?
  • 工厂模式定义是:创建对象而不将创建逻辑暴露给客户端

如果我将客户端暴露给某些创建复杂性,如下例所示,是糟糕工厂实现吗?

public static Orange getOrange(String weight, String size,) {
    return new Orange(weight, size);
}

3 个答案:

答案 0 :(得分:1)

  • 第一个代码是Factory模式,因为你只有一个没有子类化,覆盖等的类。

如果要使用工厂方法而不是写入(Banana继承自Fruit):

public abstract FruitFactory {
    public abstract Fruit createFruit();
}

public BananaFactory extends FruitFactory {
    @Override
    public Fruit createFruit() {
        return new Banana();
    }
}

实施:

public static Orange getOrange(String weight, String size) {
    return new Orange(weight, size);
}
在我看来,

也是一个正确的实现,因为你封装了像@amn中解释的创建逻辑。

使用static方法的好处是可以创建构造函数private,因此只能使用该方法实例化对象。

为了更好地理解,请参阅以下链接:patterns

答案 1 :(得分:1)

工厂模式的目的是在对象创建之上放置一个抽象层。

如果对象有足够的信息来创建自己而没有太多的参数或设置,那么您不需要使用工厂模式,因为对象的构造函数本身就是工厂。

这是您当前代码的问题,它不会为任何事物添加一层抽象。您只需封装构造函数。

第二个代码示例的问题是相同的,如果它是一个工厂,那么它会随机地或通过算法选择水果的重量或大小,就像真正的树一样。

编辑:原来的四人简介是

  

“定义用于创建对象的接口,但让子类决定实例化哪个类.Plant方法允许类将其用于子类的实例化延迟。”

这意味着您的代码不是工厂,因为您需要定义所需的代码。

答案 2 :(得分:0)

正如所说,工厂只是一个抽象,其中对象创建实现被有意地封装在工厂的公共接口之后。工厂不必是一个类,它不必是一个包 - 不同的语言以不同的方式实现状态和行为细节的封装(例如,考虑闭包)。

允许“顶级”功能的语言中的函数也可以是工厂:

public Orange growNewOrange(String weight, String size) {
    /// ...traditionally not callers concern.
}

如果工厂隐藏创建代码背后的方式让您使用它而不关心每个创建的对象的创建代码,那么您已经有了一个有用的隔离(在获取新对象和管理他们)解决工厂模式旨在解决的问题。

有些工厂旨在创建和管理一种对象,然后有一些工具可以创建和管理多种对象。水果工厂,您可以指定您想要的具体水果类,仍然匹配有效的工厂模式。

将工厂实现分类为“类型”是由各种OOP作者完成的,并且可能因各种原因而有用,但这对于能够利用总体思路来说并不是必不可少的。

立即有用的建议是将创建代码封装在Java包或类中,其中指定创建对象的参数是基于每个对象完成的,而工厂状态控制创建逻辑 - 例如重用对象池的大小等 - 在工厂创建期间设置。对象池是工作模式的一个例子。