什么时候在对象中使用工厂方法而不是factory类是一个好主意?


当前回答

当您需要几个具有相同参数类型但具有不同行为的“构造函数”时,它们也很有用。

其他回答

清楚地区分使用工厂或工厂方法背后的思想是很重要的。 两者都旨在解决互斥的不同类型的对象创建问题。

让我们具体谈谈“工厂方法”:

首先,当您正在开发库或api时,这些库或api将用于进一步的应用程序开发,那么工厂方法是创建模式的最佳选择之一。原因;我们知道什么时候创建一个所需功能的对象,但对象的类型仍未确定,或者将根据传递的动态参数来决定。

Now the point is, approximately same can be achieved by using factory pattern itself but one huge drawback will introduce into the system if factory pattern will be used for above highlighted problem, it is that your logic of crating different objects(sub classes objects) will be specific to some business condition so in future when you need to extend your library's functionality for other platforms(In more technically, you need to add more sub classes of basic interface or abstract class so factory will return those objects also in addition to existing one based on some dynamic parameters) then every time you need to change(extend) the logic of factory class which will be costly operation and not good from design perspective. On the other side, if "factory method" pattern will be used to perform the same thing then you just need to create additional functionality(sub classes) and get it registered dynamically by injection which doesn't require changes in your base code.

interface Deliverable 
{
    /*********/
}

abstract class DefaultProducer 
{

    public void taskToBeDone() 
    {   
        Deliverable deliverable = factoryMethodPattern();
    }
    protected abstract Deliverable factoryMethodPattern();
}

class SpecificDeliverable implements Deliverable 
{
 /***SPECIFIC TASK CAN BE WRITTEN HERE***/
}

class SpecificProducer extends DefaultProducer 
{
    protected Deliverable factoryMethodPattern() 
    {
        return new SpecificDeliverable();
    }
}

public class MasterApplicationProgram 
{
    public static void main(String arg[]) 
    {
        DefaultProducer defaultProducer = new SpecificProducer();
        defaultProducer.taskToBeDone();
    }
}

工厂方法应该被认为是构造函数的替代品——尤其是在构造函数表达能力不够的时候。

class Foo{
  public Foo(bool withBar);
}

表现力不如:

class Foo{
  public static Foo withBar();
  public static Foo withoutBar();
}

当你需要一个复杂的过程来构造对象时,当构造需要一个你不想要的实际类的依赖关系时,当你需要构造不同的对象时,工厂类是有用的。

假设你有不同的客户,他们有不同的偏好。有人需要大众、奥迪等等。有一样东西是共同的,那就是汽车。

为了让我们的客户满意,我们需要一个工厂。工厂只需要知道客户想要哪一辆车,并将其交付给客户。如果以后我们有另一辆车,我们可以很容易地扩大我们的停车场和工厂。

下面你可以看到一个例子(ABAP):

现在,我们将创建工厂的实例,并监听客户的愿望。

我们只用一个create()方法创建了三种不同的汽车。

结果:

如果你想让逻辑更清晰,程序更可扩展,工厂模式通常非常有用。

GOF定义:

定义一个用于创建对象的接口,但是让子类来决定实例化哪个类。工厂方法允许类延迟实例化到子类。

一般例子:

public abstract class Factory<T> {

    public abstract T instantiate(Supplier<? extends T> supplier);

}

具体类

public class SupplierFactory<T> extends Factory<T> {

    @Override
    public T instantiate(Supplier<? extends T> supplier) {
        return supplier.get();
    }
}

实现

public class Alpha implements BaseInterface {
    @Override
    public void doAction() {
        System.out.println("The Alpha executed");
    }
}

public class Beta implements BaseInterface {
    @Override
    public void doAction() {
        System.out.println("The Beta executed");
    }
}

public interface BaseInterface {
    void doAction();
}

public class Main {
    public static void main(String[] args) {
        Factory<BaseInterface> secondFactory = new SupplierFactory<>();
        secondFactory.instantiate(Beta::new).doAction();
        secondFactory.instantiate(Alpha::new).doAction();
    }
}

短暂的优势

您正在分离可以变化的代码和不变的代码(即,使用简单工厂模式的优点仍然存在)。这种技术可以帮助您轻松地维护代码。 你的代码不是紧密耦合的;因此,你可以随时在系统中添加新的类,如Lion、Beer等,而无需修改现有的体系结构。因此,您遵循了“修改封闭,扩展开放”的原则。

我简短的解释是,当我们没有足够的信息来创建一个具体的对象时,我们使用工厂模式。我们要么不知道依赖关系,要么不知道对象的类型。我们几乎总是不知道它们因为这是运行时的信息。

示例:我们知道我们必须创建一个车辆对象,但我们不知道它是飞行还是在地面上工作。