spring Java工厂模式

dbf7pr2w  于 5个月前  发布在  Spring
关注(0)|答案(2)|浏览(68)

我有模块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();
}


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

qmb5sa22

qmb5sa221#

最好的方法是这样的:

public interface FactoryProducer<T> {
  public T create(String param);
}

public class Factory<T> {
  Map producers = new HashMap<string, FactoryProducer<T>>();
  public void registerFactory(String key, FactoryProducer<T> producer) {
    producers.put(key, producer);
  }
  public FactoryProducer<T> getFactory(String key) {
    return producers.get(key);
  }
}

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

i7uaboj4

i7uaboj42#

使用Java SPI。

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

public interface ThirdPartyCallsStrategy {
    void apply(String orderId);

    String type();
}

字符串

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

public class AStrategy implements ThirdPartyCallsStrategy {
    public void apply(String orderId) {
        // Do something here.
    }
    public String type() {
        return "A";
    }
}
public class BStrategy implements ThirdPartyCallsStrategy {
    public void apply(String orderId) {
        // Do something different here.
    }
    public String type() {
        return "B";
    }
}

在META-INF中注册实现。

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

com.modela.AStrategy


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

com.modelb.BStrategy

在模型C中创建工厂。

public class CoreCallsFactory {
    private final Map<String, ThirdPartyCallsStrategy> strategyMap;

    public CoreCallsFactory() {
        strategyMap = new HashMap<>();
        ServiceLoader<ThirdPartyCallsStrategy> strategies = ServiceLoader.load(ThirdPartyCallsStrategy.class);
        for (ThirdPartyCallsStrategy strategy : strategies) {
            strategyMap.put(strategy.type(), strategy);
        }
    }

    public ThirdPartyCallsStrategy createThirdPartyCallsStrategy(String type) {
        ThirdPartyCallsStrategy strategy = strategyMap.get(type);
        if (strategy == null) {
            throw new IllegalArgumentException("There is no strategy for this type: " + type);
        }
        return strategy;
    }
}


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

相关问题