Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/312.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_Python_Oop_Design Patterns_Factory - Fatal编程技术网

Java中的工厂实现

Java中的工厂实现,java,python,oop,design-patterns,factory,Java,Python,Oop,Design Patterns,Factory,在用python编写了几年代码之后,我最近转到Java进行一个项目。 在使用Python时,我为一个工厂提供了一个非常好的实现 #文件摘要_product.py 从abc导入abc,abstractmethod 类别抽象产品(ABC): @抽象方法 定义做某事(): 通过 #文件product_factory.py 从抽象产品导入抽象产品 类别产品工厂: 定义初始化(自): self.\u创建者={} def get(自身,产品名称)->产品: 如果产品名称不在self.\u创建者中: rai

在用python编写了几年代码之后,我最近转到Java进行一个项目。 在使用Python时,我为一个工厂提供了一个非常好的实现

#文件摘要_product.py
从abc导入abc,abstractmethod
类别抽象产品(ABC):
@抽象方法
定义做某事():
通过
#文件product_factory.py
从抽象产品导入抽象产品
类别产品工厂:
定义初始化(自):
self.\u创建者={}
def get(自身,产品名称)->产品:
如果产品名称不在self.\u创建者中:
raise VALUERROR('没有有效的实现!')
返回自我。创建者[产品名称]()
def寄存器(自身、产品名称、产品):
自创者[产品名称]=产品
产品工厂=产品工厂()
#文件product1.py
从抽象产品导入抽象产品
从产品工厂进口产品工厂
类别Product1(抽象产品):
定义做某事():
#做点什么
通过
产品工厂注册('product1',product1)
现在的优势是,如果我有一个新的 产品,我所要做的就是

#文件product2.py
从抽象产品导入抽象产品
从产品工厂进口产品工厂
类别Product2(抽象产品):
定义做某事():
#做点什么
通过
产品工厂注册(“产品2”,产品2)
上述方法的优点是:

  • 我的工厂是单身汉。在模块中定义变量可以确保
  • 注册新产品时,不包括对现有代码的更改
  • 任何地方都不需要安装脏梯子
  • 新实现在自己的模块中注册到工厂。非常干净:D:D
所有客户机代码都需要知道上面的
product\u factory
,以及客户机获取
product
实现所基于的字符串参数

然而,现在有了Java,我在想我能做些什么,以接近上述方法所具有的简单性和可扩展性

注:
还请建议一些其他方法,您可能会遇到一个可扩展工厂,甚至可能比上述更好

我喜欢这样做(以另一个班级为例)

公共类MyFactory{
私有映射factoryMap=新HashMap();
@自动连线
公共MyFactory(对象简化MyInterface列表){
对于(MyInterface MyInterface:ListoFobjectSimplementMyInterface){
//获取类注释值,将其用作贴图的键
String strategyKey=myInterface.getClass().getAnnotationsByType(Component.class)[0].value();
factoryMap.put(策略,myInterface);
}
}
//从工厂获取实例化
公共MyInterface getFromFactory(字符串策略键){
返回factoryMap.get(strategyKey);
}
}

上面的示例是spring f/w项目的一个片段,使用此方法,您可以使用spring注释填充工厂,而不是使用凌乱的if/else/switch块。上述方法也可以通过自定义注释扩展到其他情况。

您的python代码可以很容易地翻译成Java,而且看起来不太“陌生”

在我看来,从Python代码到Java的严格转换就是下面的代码片段。这对你来说应该更熟悉

对于一个简单的应用程序,您可以让您的工厂使用
静态
,或者使用单例设计模式来确保单个实例

如果您正在使用一些框架,很可能它提供了一种需要更少编码和更好测试性的替代方案

import java.util.HashMap;
导入java.util.Map;
//AbstractProduct甚至可以更好地成为一个“接口”
抽象类抽象产品{
抽象空剂量测定法();
}
类Product1扩展了AbstractProduct{
@凌驾
无效剂量测定法(){
System.out.println(“我是产品一(1)”;
}
}
类Product2扩展了AbstractProduct{
@凌驾
无效剂量测定法(){
System.out.println(“我是产品二(2)”;
}
}
一级品厂{

private final Map有一些OOP原则可以满足您的需要。请尝试查看委托等感谢您的回答。我仍然认为唯一的一点是,在应用程序代码中的某个地方,一旦添加了新的实现,您仍然需要注册。现在,该组件应该是什么?使用python实现n、 其实不需要单独的组件!你可以直接在新的实现下面做!如果我真的定义了一个新组件,我现在应该为我的应用程序中的所有工厂定义一个这样的组件吗?@RohitashwaNigam,我编辑了答案,并添加了一些额外的信息,作为对你评论的回复。谢谢你的评论你的答案。我仍然认为唯一的一件事是,在应用程序代码的某个地方,一旦添加了新的实现,你仍然需要注册。现在,该组件应该是什么?对于python实现,实际上不需要单独的组件!你可以在新实现的正下方进行注册!a如果我真的定义了一个新的组件,我现在应该为我的应用程序中的所有工厂定义一个这样的组件吗?@RohitashwaNigam我明白你的意思了。你通常会把这些寄存器调用放在一个单独的类中,或者放在
main
方法中,或者放在工厂类的构造函数中,这取决于你的情况。Java不是这个意思就像Python一样,有时代码不能也不应该被直接翻译。如果你想变得更有趣,我认为你可以用一个自定义的注释来注释你的所有产品,然后在工厂中,在类路径中找到所有具有该注释的类
public class MyFactory {
    private Map<String, MyInterface> factoryMap = new HashMap<>();

    @Autowired
    public MyFactory(List<MyInterface> listOfObjectsImplementingMyInterface) {
        for (MyInterface myInterface : listOfObjectsImplementingMyInterface) {
//Get the class annotation value, use it as map's key
            String strategyKey = myInterface.getClass().getAnnotationsByType(Component.class)[0].value();
            factoryMap.put(strategy, myInterface);
            
        }
    }

// To get an instantiation from factory
    public MyInterface getFromFactory(String strategyKey) {
        return factoryMap.get(strategyKey);
    }
}
// could even be an interface
abstract class Product {
  // ...
  abstract void doSomething();
}

final class ProductFactory {
  // not strictly a singleton, to allow you to create multiple factories
  // your python code allows this too

  private static ProductFactory instance = new ProductFactory();

  public static ProductFactory getInstance() {
    return instance;
  }

  private HashMap<String, Supplier<? extends Product>> creators = new HashMap<>();

  public void register(String productName, Supplier<? extends Product> creator) {
    creators.put(productName, creator);
  }

  public Product get(String productName) {
    Supplier<? extends Product> creator = creators.get(productName);
    if (creator == null) {
      throw new IllegalArgumentException("No valid implementation !");
    }
    return creator.get();
  }
}

class Product1 extends Product {

  @Override
  void doSomething() {

  }
}