我有模块A和模块B,每个模块都有一些特定的服务,我有一个模块C,它与A和B没有任何依赖关系,所以我想从模块A和B调用服务,我想使用工厂模式实现这一点。
在模块C中,我已经创建了此接口,它将成为模块A和B中实现的公共接口
public interface ThirdPartyCallsStrategy {
void apply(String orderId);
}
字符串
这是一个工厂类的例子,将根据类型参数提供所需的适当示例
@Component
@AllArgsConstructor
public class CoreCallsFactory {
private static final String A_PACKAGE = "com.testA.service";
private static final String A_CLASS = "TestClassA";
private static final String B_PACKAGE = "com.testB.service";
private static final String B_CLASS = "TestClassA";
@SneakyThrows
public ThirdPartyCallsStrategy createThirdPartyCallsStrategy(String type) {
Class<?> clazz;
if (type.equals("A")) {
clazz = Class.forName(String.format("%s.%s", A_PACKAGE , A_CLASS ));
return (ThirdPartyCallsStrategy) clazz.getDeclaredConstructor().newInstance();
}
if (type.equals("B")) {
clazz = Class.forName(String.format("%s.%s", B_PACKAGE , B_CLASS ));
return (ThirdPartyCallsStrategy) clazz.getDeclaredConstructor().newInstance();
}
return null;
}
}
型ThirdPartyCallsStrategy
在不同模块的不同服务中实现
最后在模块C中,我通过java反射进行示例化,但这将在运行时进行,它可以在运行时而不是在编译时通过异常进行示例化
public String checkStatusAndRedirect(String orderId, String type) {
boolean status = checkStatus(orderId);
StringBuilder paymentResultUrl = new StringBuilder(frontUrl + "/public/payment/status?success=");
if (status) {
coreCallsFactory.createThirdPartyCallsStrategy(type).apply(orderId);
paymentResultUrl.append(Boolean.TRUE);
} else {
paymentResultUrl.append(Boolean.FALSE);
}
return paymentResultUrl.toString();
}
型
所以我需要一个更干净的方法来改变这个实现。
2条答案
按热度按时间qmb5sa221#
最好的方法是这样的:
字符串
通过这种方式,您可以构建FactoryProducers和Factories,并保持一切解耦。
i7uaboj42#
使用Java SPI。
在模型C中定义接口
com.modelc.ThirdPartyCallsStrategy
。字符串
在模型A和模型B中实现
ThirdPartyCallsStrategy
。型
在META-INF中注册实现。
在模型A
resources/META-INF/services/com.modelc.ThirdPartyCallsStrategy
的文件中:型
在型号B
resources/META-INF/services/com.modelc.ThirdPartyCallsStrategy
的文件中:型
在模型C中创建工厂。
型
模型A和B依赖于模型C中的接口,但模型C不知道模型A或B。