Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/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
Design patterns 确定在使用factory方法设计模式时要使用的factory_Design Patterns_Factory Pattern - Fatal编程技术网

Design patterns 确定在使用factory方法设计模式时要使用的factory

Design patterns 确定在使用factory方法设计模式时要使用的factory,design-patterns,factory-pattern,Design Patterns,Factory Pattern,我目前正在对工厂设计模式进行一些研究,并列出了我对每种模式的理解的简要描述。如果有不正确的地方,请纠正我 1工厂-简单,实际上不是正式的设计模式,通常是一个类,它有一个或多个方法,有时静态地接受一个参数,以确定返回哪个抽象类型的子类 2工厂方法-正式的模式并使用抽象工厂类。对于预期退货类型的每个产品,创建关联的factory类,并实现或重写所需的方法。在客户机代码中,尽管变量被声明为抽象工厂,但它是用具体实现实例化的 3抽象工厂-通过相互关联或依赖的各种方法返回多种类型对象的模式 我的问题是,我

我目前正在对工厂设计模式进行一些研究,并列出了我对每种模式的理解的简要描述。如果有不正确的地方,请纠正我

1工厂-简单,实际上不是正式的设计模式,通常是一个类,它有一个或多个方法,有时静态地接受一个参数,以确定返回哪个抽象类型的子类

2工厂方法-正式的模式并使用抽象工厂类。对于预期退货类型的每个产品,创建关联的factory类,并实现或重写所需的方法。在客户机代码中,尽管变量被声明为抽象工厂,但它是用具体实现实例化的

3抽象工厂-通过相互关联或依赖的各种方法返回多种类型对象的模式

我的问题是,我一直在使用工厂,而不是带有共享方法的正式模式。然而,我正在考虑选择工厂方法并使用它,但我无法弄清楚的是如何确定抽象工厂类的哪个子类用于创建我的产品。据我目前所知,您仍然使用new关键字为声明为抽象工厂类的变量分配一个具体类

例如:

将工厂1标注为IFactory=新混凝土工厂1

将工厂2标注为IFactory=新混凝土工厂2

例如,如果我想根据数据库记录动态确定要返回哪个IFactory,我将如何做?让代码使用工厂模式而不使用工厂方法模式是否更好?我希望避免在客户机代码中使用select case或if语句。我可以用工厂模式包装工厂方法模式吗


希望我讲得有道理

好吧,这完全取决于为了支持设计理念而使用的语言。我将用Java描述这个想法,让我们开始吧

您具有以下功能:

AbstractFacotry instance1 = new ConcreteFacotry1();
AbstractFacotry instance2 = new ConcreteFacotry2();
你要避免在工厂里浇筑混凝土。这就是为什么您将使用一个Factory类,该类负责根据您案例中的参数,即您提到的数据库记录,为您提供正确的ConcretFactory实例。我会尽量简短地解释,希望在这个过程中不会失去任何人

我将从创建抽象类AbstractFactory开始,并从抽象类AbstractFactory扩展具体类,以实现示例的目的

public abstract class AbstractFactory {}
当然你的会更详细,我只需要实例化它来运行几个测试。现在让我们来介绍一下从它扩展而来的课程:

public class ConcreteFactory1 extends AbstractFactory {}
我不会粘贴其他的代码,它们都是一样的。以下是我创建的类:ConcreteFactory1、ConcreteFactory2、ConcreteFactory3、ConcreteFactory4

下一个类负责根据数据库参数为您提供AbstractFactory的具体实例。这个实现假设数据库参数不会超过15个左右。还可以将所述数据库参数转换为字符串

public class FactoryInstantiator {
public AbstractFactory optionOne(){
    return new ConcreteFactory1();
}

public AbstractFactory optionTwo(){
    return new ConcreteFactory2();
}

public AbstractFactory optionThree(){
    return new ConcreteFactory3();
}

public AbstractFactory optionFour(){
    return new ConcreteFactory4();
}
}
显然,name选项是数据库参数的字符串转换

最后一件事是创建负责根据数据库参数调用正确方法的类。这就是问题的症结所在,也是你避免使用if-ELSE和交换机的地方。这是您将从客户端调用的类

public class FactoryHandler {

public AbstractFactory getInstance(String databaseParameter) {
    try {
        return  getConcreteInstance(FactoryInstantiator.class, databaseParameter);
    } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | 
             InvocationTargetException | NoSuchMethodException ex) {
        Logger.getLogger(FactoryHandler.class.getName()).log(Level.SEVERE, null, ex);
    }
    throw new RuntimeException("Could not determine concrete instance based on data base parameter");
}


private AbstractFactory getConcreteInstance(Class<FactoryInstantiator> factoryInstantiator, String databaseParameter) 
                    throws InstantiationException, IllegalAccessException, IllegalArgumentException, 
                    InvocationTargetException, NoSuchMethodException {    
    Class[] methodParameterTypes=null;
    Object instance = factoryInstantiator.newInstance();
    Method method = factoryInstantiator.getDeclaredMethod(databaseParameter, methodParameterTypes);
    return  (AbstractFactory) method.invoke(instance);
}

}

就在这里。希望能有帮助

嗯,这完全取决于您将使用何种语言来支持设计理念。我将用Java描述这个想法,让我们开始吧

您具有以下功能:

AbstractFacotry instance1 = new ConcreteFacotry1();
AbstractFacotry instance2 = new ConcreteFacotry2();
你要避免在工厂里浇筑混凝土。这就是为什么您将使用一个Factory类,该类负责根据您案例中的参数,即您提到的数据库记录,为您提供正确的ConcretFactory实例。我会尽量简短地解释,希望在这个过程中不会失去任何人

我将从创建抽象类AbstractFactory开始,并从抽象类AbstractFactory扩展具体类,以实现示例的目的

public abstract class AbstractFactory {}
当然你的会更详细,我只需要实例化它来运行几个测试。现在让我们来介绍一下从它扩展而来的课程:

public class ConcreteFactory1 extends AbstractFactory {}
我不会粘贴其他的代码,它们都是一样的。以下是我创建的类:ConcreteFactory1、ConcreteFactory2、ConcreteFactory3、ConcreteFactory4

下一个类负责根据数据库参数为您提供AbstractFactory的具体实例。这个实现假设数据库参数不会超过15个左右。还可以将所述数据库参数转换为字符串

public class FactoryInstantiator {
public AbstractFactory optionOne(){
    return new ConcreteFactory1();
}

public AbstractFactory optionTwo(){
    return new ConcreteFactory2();
}

public AbstractFactory optionThree(){
    return new ConcreteFactory3();
}

public AbstractFactory optionFour(){
    return new ConcreteFactory4();
}
}
显然,name选项是d的字符串翻译 数据库参数

最后一件事是创建负责根据数据库参数调用正确方法的类。这就是问题的症结所在,也是你避免使用if-ELSE和交换机的地方。这是您将从客户端调用的类

public class FactoryHandler {

public AbstractFactory getInstance(String databaseParameter) {
    try {
        return  getConcreteInstance(FactoryInstantiator.class, databaseParameter);
    } catch (InstantiationException | IllegalAccessException | IllegalArgumentException | 
             InvocationTargetException | NoSuchMethodException ex) {
        Logger.getLogger(FactoryHandler.class.getName()).log(Level.SEVERE, null, ex);
    }
    throw new RuntimeException("Could not determine concrete instance based on data base parameter");
}


private AbstractFactory getConcreteInstance(Class<FactoryInstantiator> factoryInstantiator, String databaseParameter) 
                    throws InstantiationException, IllegalAccessException, IllegalArgumentException, 
                    InvocationTargetException, NoSuchMethodException {    
    Class[] methodParameterTypes=null;
    Object instance = factoryInstantiator.newInstance();
    Method method = factoryInstantiator.getDeclaredMethod(databaseParameter, methodParameterTypes);
    return  (AbstractFactory) method.invoke(instance);
}

}
就在这里。希望能有帮助