Java中的工厂实现
在用python编写了几年代码之后,我最近转到Java进行一个项目。 在使用Python时,我为一个工厂提供了一个非常好的实现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
#文件摘要_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() {
}
}