Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 工厂方法是否更适合框架和图书馆的抽象工厂?_Java_Oop_Design Patterns_Abstract Factory_Factory Method - Fatal编程技术网

Java 工厂方法是否更适合框架和图书馆的抽象工厂?

Java 工厂方法是否更适合框架和图书馆的抽象工厂?,java,oop,design-patterns,abstract-factory,factory-method,Java,Oop,Design Patterns,Abstract Factory,Factory Method,抽象工厂和工厂方法模式都是创造性的设计模式,它们解决了不同场景中的对象创建问题 按照GOF工厂方法模式 定义用于创建对象的接口,但让子类决定实例化哪个类。工厂方法允许类将实例化延迟到子类 我的理解: 客户机的动机是获取一个存在于基本工厂类get execute中的方法,该方法依赖于一个具体类现在未知的对象(在这种情况下,无论是在向客户提供软件的过程中,都将对其进行定义,或者是由客户自己编写具体的实现,最有可能是在框架的情况下)。未知(或可能会更改)为产品提供了一个抽象类型:IProduct,并设

抽象工厂和工厂方法模式都是创造性的设计模式,它们解决了不同场景中的对象创建问题

按照GOF工厂方法模式

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

我的理解: 客户机的动机是获取一个存在于基本工厂类get execute中的方法,该方法依赖于一个具体类现在未知的对象(在这种情况下,无论是在向客户提供软件的过程中,都将对其进行定义,或者是由客户自己编写具体的实现,最有可能是在框架的情况下)。未知(或可能会更改)为产品提供了一个抽象类型:IProduct,并设置了一个契约,在将来的任何产品实现中都必须实现这个接口

i产品界面

package com.companyx;
public interface IProduct {
    public void serve();
}
package com.clientcompany;
import com.companyx.AppAFeatureXProductFactory;
import com.companyx.Factory;
public class Client {
    public static void main(String[] args) {
        Factory fact = new AppAFeatureXProductFactory();
        fact.executeJob();
    }
}
package com.clientcompany.productprovider;
import com.companyb.IFactory;
import com.companyb.IProductA;
public class SomeClientClass {
    private IFactory factory;
    private IProductA product;

    public void doSomeJobWithProductA() {
        // some code
        product.performAJob();
        //someCode();
    }
    public void setFactory(IFactory factory) {
        this.factory = factory;
        this.product = factory.createProduct();
    }
}

package com.clientcompany.productprovider;
import com.companyb.FactoryA;
public class SomeOtherClientCode {
    public static void main(String[] args) {
        SomeClientClass someClientClass = new SomeClientClass();
        someClientClass.setFactory(new FactoryA());
        someClientClass.doSomeJobWithProductA();
    }
}
带有需要执行的“方法”的工厂类

package com.companyx;
public abstract class Factory {
    public abstract IProduct createProduct();
    private void performCriticalJob(){
        IProduct product = createProduct();
        product.serve();
    }
    public void executeJob(){
        //some code
        performCriticalJob();
        //some more code
    }
}
一些具体产品

package com.companyx;
class AppAProductFeatureX implements IProduct{
    @Override
    public void serve() {
        //some code
    }
}
package com.companyx;
public class AppAFeatureXProductFactory extends Factory{
    @Override
    public IProduct createProduct() {
        return new AppAProductFeatureX();
    }
}
package com.companyb;
public interface IProductA {
    public void performAJob();
}
package com.companyb;
//can be named better, but lets go with this name for this time
public class ProductAVersion1 implements IProductA{
    @Override
    public void performAJob() {
        // some code
    }
}
混凝土产品的工厂

package com.companyx;
class AppAProductFeatureX implements IProduct{
    @Override
    public void serve() {
        //some code
    }
}
package com.companyx;
public class AppAFeatureXProductFactory extends Factory{
    @Override
    public IProduct createProduct() {
        return new AppAProductFeatureX();
    }
}
package com.companyb;
public interface IProductA {
    public void performAJob();
}
package com.companyb;
//can be named better, but lets go with this name for this time
public class ProductAVersion1 implements IProductA{
    @Override
    public void performAJob() {
        // some code
    }
}
客户端代码

package com.companyx;
public interface IProduct {
    public void serve();
}
package com.clientcompany;
import com.companyx.AppAFeatureXProductFactory;
import com.companyx.Factory;
public class Client {
    public static void main(String[] args) {
        Factory fact = new AppAFeatureXProductFactory();
        fact.executeJob();
    }
}
package com.clientcompany.productprovider;
import com.companyb.IFactory;
import com.companyb.IProductA;
public class SomeClientClass {
    private IFactory factory;
    private IProductA product;

    public void doSomeJobWithProductA() {
        // some code
        product.performAJob();
        //someCode();
    }
    public void setFactory(IFactory factory) {
        this.factory = factory;
        this.product = factory.createProduct();
    }
}

package com.clientcompany.productprovider;
import com.companyb.FactoryA;
public class SomeOtherClientCode {
    public static void main(String[] args) {
        SomeClientClass someClientClass = new SomeClientClass();
        someClientClass.setFactory(new FactoryA());
        someClientClass.doSomeJobWithProductA();
    }
}
按照GOF抽象工厂模式

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

我的理解 客户机对产品感兴趣,这里这个模式通过将具体的产品类隐藏在工厂类后面来帮助提供产品

客户需要的产品类型

package com.companyx;
class AppAProductFeatureX implements IProduct{
    @Override
    public void serve() {
        //some code
    }
}
package com.companyx;
public class AppAFeatureXProductFactory extends Factory{
    @Override
    public IProduct createProduct() {
        return new AppAProductFeatureX();
    }
}
package com.companyb;
public interface IProductA {
    public void performAJob();
}
package com.companyb;
//can be named better, but lets go with this name for this time
public class ProductAVersion1 implements IProductA{
    @Override
    public void performAJob() {
        // some code
    }
}
产品的实施

package com.companyx;
class AppAProductFeatureX implements IProduct{
    @Override
    public void serve() {
        //some code
    }
}
package com.companyx;
public class AppAFeatureXProductFactory extends Factory{
    @Override
    public IProduct createProduct() {
        return new AppAProductFeatureX();
    }
}
package com.companyb;
public interface IProductA {
    public void performAJob();
}
package com.companyb;
//can be named better, but lets go with this name for this time
public class ProductAVersion1 implements IProductA{
    @Override
    public void performAJob() {
        // some code
    }
}
工厂接口,(也可以是抽象类)

工厂创建产品的具体实施a

package com.companyb

public class FactoryA implements IFactory{
    @Override
    public IProductA createProduct() {
        return new ProductAVersion1(); // concrete class of product is hidden
    }
}
客户端代码

package com.companyx;
public interface IProduct {
    public void serve();
}
package com.clientcompany;
import com.companyx.AppAFeatureXProductFactory;
import com.companyx.Factory;
public class Client {
    public static void main(String[] args) {
        Factory fact = new AppAFeatureXProductFactory();
        fact.executeJob();
    }
}
package com.clientcompany.productprovider;
import com.companyb.IFactory;
import com.companyb.IProductA;
public class SomeClientClass {
    private IFactory factory;
    private IProductA product;

    public void doSomeJobWithProductA() {
        // some code
        product.performAJob();
        //someCode();
    }
    public void setFactory(IFactory factory) {
        this.factory = factory;
        this.product = factory.createProduct();
    }
}

package com.clientcompany.productprovider;
import com.companyb.FactoryA;
public class SomeOtherClientCode {
    public static void main(String[] args) {
        SomeClientClass someClientClass = new SomeClientClass();
        someClientClass.setFactory(new FactoryA());
        someClientClass.doSomeJobWithProductA();
    }
}
Q1:在抽象工厂模式中是否需要相关产品系列,如果只有一种产品(如上所述)具有各种子类型,但没有各种相关类型,那么该模式是否仍然相关

Q2我的上述理解正确吗

Q3上面的问题让我产生了另一个疑问:Factory方法是否更适合框架(客户端可以在框架中提供产品的实现),就像模板方法模式一样,Factory从用户提供的具体工厂实现中调用
createProduct()
具体实现? 同样,抽象工厂更适合于库开发,具体的产品类(可能会有所不同)隐藏在更稳定的工厂类后面?

据我所知:

A1:产品系列不一定要相关,如图所示,只需要一个了解产品类型的客户。这种关系基本上是自然的,因为您可能不希望同一客户创建两个不相关的对象,例如,如果您有一个“AbstractPizzaFactory”,它看起来会很奇怪这创造了比萨饼和汽车,不是吗

A2:从技术上讲,您可以在factory模式中提供默认的factory方法,这样您仍然可以创建(默认)新对象,而无需始终对其进行子类化


A3:在这一点上,我同意你的观点,尽管创建库或框架从来都不是黑白的。

我很难理解你的观点。但我对这个主题很感兴趣,所以我会尝试一下。这里涉及的概念有
框架
工厂方法
抽象工厂
产品系列

首先,
library vs framework
实际上与工厂、抽象工厂或任何模式都没有关系。库vs framework的争论不是从实现的角度来讨论模式的。例如,JUnit是一个带有丰富断言库的框架。那么JUnit应该更喜欢一种模式而不是ot吗Java本身是一个框架,它附带了一个JCL库。Dot Net与Java类似,甚至称自己为框架,并包含BCL库。因此,在实现上下文中,不再有框架与库的争论

因此,问题归结为您应该使用哪种模式?这不是清楚的区别,而是在哪种情况下使用哪种模式。在这种情况下,
客户机代码
都是可以调用的代码,即您现在正在键入的代码。某些代码是您编写的还是其他人编写的都不重要否则,在相同或不同的jar中,来自相同或不同的组织。从一个代码片段的角度来看,任何其他代码(即使在同一类的不同方法中)都是客户机代码,如果该代码有可能调用您当前键入的代码

在键入任何代码时(无论框架或库状态如何),有时我们需要获取某些对象的实例。可能我们需要一个
BufferedReader
。如果在编译时我们对对象的具体类有绝对的把握,
KISS
它并使用
new
ing

我们可能不知道一个实例的具体类。现在,请询问客户机代码是否有此信息?如果客户机代码知道实际的具体类,但我不知道,那么我们使用
FactoryMethod
模式。我正在键入的代码将要求在中输入工厂对象的实例(例如)它的参数列表。知道实际具体类的客户机代码将提供一个工厂对象来进行创建。这种情况的示例见
JDBC
,就像我们想要处理sql语句一样