spring Java工厂模式

dbf7pr2w  于 2024-01-05  发布在  Spring
关注(0)|答案(2)|浏览(144)

我有模块A和模块B,每个模块都有一些特定的服务,我有一个模块C,它与A和B没有任何依赖关系,所以我想从模块A和B调用服务,我想使用工厂模式实现这一点。
在模块C中,我已经创建了此接口,它将成为模块A和B中实现的公共接口

  1. public interface ThirdPartyCallsStrategy {
  2. void apply(String orderId);
  3. }

字符串
这是一个工厂类的例子,将根据类型参数提供所需的适当示例

  1. @Component
  2. @AllArgsConstructor
  3. public class CoreCallsFactory {
  4. private static final String A_PACKAGE = "com.testA.service";
  5. private static final String A_CLASS = "TestClassA";
  6. private static final String B_PACKAGE = "com.testB.service";
  7. private static final String B_CLASS = "TestClassA";
  8. @SneakyThrows
  9. public ThirdPartyCallsStrategy createThirdPartyCallsStrategy(String type) {
  10. Class<?> clazz;
  11. if (type.equals("A")) {
  12. clazz = Class.forName(String.format("%s.%s", A_PACKAGE , A_CLASS ));
  13. return (ThirdPartyCallsStrategy) clazz.getDeclaredConstructor().newInstance();
  14. }
  15. if (type.equals("B")) {
  16. clazz = Class.forName(String.format("%s.%s", B_PACKAGE , B_CLASS ));
  17. return (ThirdPartyCallsStrategy) clazz.getDeclaredConstructor().newInstance();
  18. }
  19. return null;
  20. }
  21. }


ThirdPartyCallsStrategy在不同模块的不同服务中实现
最后在模块C中,我通过java反射进行示例化,但这将在运行时进行,它可以在运行时而不是在编译时通过异常进行示例化

  1. public String checkStatusAndRedirect(String orderId, String type) {
  2. boolean status = checkStatus(orderId);
  3. StringBuilder paymentResultUrl = new StringBuilder(frontUrl + "/public/payment/status?success=");
  4. if (status) {
  5. coreCallsFactory.createThirdPartyCallsStrategy(type).apply(orderId);
  6. paymentResultUrl.append(Boolean.TRUE);
  7. } else {
  8. paymentResultUrl.append(Boolean.FALSE);
  9. }
  10. return paymentResultUrl.toString();
  11. }


所以我需要一个更干净的方法来改变这个实现。

qmb5sa22

qmb5sa221#

最好的方法是这样的:

  1. public interface FactoryProducer<T> {
  2. public T create(String param);
  3. }
  4. public class Factory<T> {
  5. Map producers = new HashMap<string, FactoryProducer<T>>();
  6. public void registerFactory(String key, FactoryProducer<T> producer) {
  7. producers.put(key, producer);
  8. }
  9. public FactoryProducer<T> getFactory(String key) {
  10. return producers.get(key);
  11. }
  12. }

字符串
通过这种方式,您可以构建FactoryProducers和Factories,并保持一切解耦。

展开查看全部
i7uaboj4

i7uaboj42#

使用Java SPI。

在模型C中定义接口com.modelc.ThirdPartyCallsStrategy

  1. public interface ThirdPartyCallsStrategy {
  2. void apply(String orderId);
  3. String type();
  4. }

字符串

在模型A和模型B中实现ThirdPartyCallsStrategy

  1. public class AStrategy implements ThirdPartyCallsStrategy {
  2. public void apply(String orderId) {
  3. // Do something here.
  4. }
  5. public String type() {
  6. return "A";
  7. }
  8. }
  9. public class BStrategy implements ThirdPartyCallsStrategy {
  10. public void apply(String orderId) {
  11. // Do something different here.
  12. }
  13. public String type() {
  14. return "B";
  15. }
  16. }

在META-INF中注册实现。

在模型A resources/META-INF/services/com.modelc.ThirdPartyCallsStrategy的文件中:

  1. com.modela.AStrategy


在型号B resources/META-INF/services/com.modelc.ThirdPartyCallsStrategy的文件中:

  1. com.modelb.BStrategy

在模型C中创建工厂。

  1. public class CoreCallsFactory {
  2. private final Map<String, ThirdPartyCallsStrategy> strategyMap;
  3. public CoreCallsFactory() {
  4. strategyMap = new HashMap<>();
  5. ServiceLoader<ThirdPartyCallsStrategy> strategies = ServiceLoader.load(ThirdPartyCallsStrategy.class);
  6. for (ThirdPartyCallsStrategy strategy : strategies) {
  7. strategyMap.put(strategy.type(), strategy);
  8. }
  9. }
  10. public ThirdPartyCallsStrategy createThirdPartyCallsStrategy(String type) {
  11. ThirdPartyCallsStrategy strategy = strategyMap.get(type);
  12. if (strategy == null) {
  13. throw new IllegalArgumentException("There is no strategy for this type: " + type);
  14. }
  15. return strategy;
  16. }
  17. }


模型A和B依赖于模型C中的接口,但模型C不知道模型A或B。

展开查看全部

相关问题