参数化方法的java工厂模式

bqujaahr  于 2021-06-30  发布在  Java
关注(0)|答案(2)|浏览(384)

这是一组遵循相同算法的服务。使用者调用这些服务,服务将使用者的请求发送到某个后端系统。服务接口是restful的,后端是soap。因为它们都遵循相同的模式,所以我们有一个抽象类。方法的顺序是固定的,即commonmethodone需要发生在commonmethod2之前,等等。
具体类必须实现这两个抽象方法,因为每个服务接口是不同的。

public abstract class CommonService<T1, T2, T3, T4> {

    public T4 getResponse(T1 request) {
        T2 backendRequest = transformClientRequestToBackendRequest(request);
        commonMethodOne(request);
        commonMethodTwo(request);
        T3 backendResponse = getBackendResponse(backendRequest);
        commonMethodThree(backendResponse);
        commonMethodFour(backendResponse);
        return transformBackendResponseToClientResponse(backendResponse);
    }

    public abstract T2 transformClientRequestToBackendRequest(T1 request);

    public abstract T4 transformBackendResponseToClientResponse(T3 backendResponse);

    public void commonMethodOne(T1 request) {
        //some code
    }

    public void commonMethodTwo(T1 request) {
        //some code
    }

    public void commonMethodThree(T3 backendResponse) {
        //some code
    }

    public void commonMethodFour(T3 backendResponse) {
        //some code
    }

    public T3 getBackendResponse(T2 backendRequest) {
        // call to backend system
    }
}

问题如下。95%的服务将遵循这种模式。但是,一小部分人需要客户机请求才能将后端响应转换为客户机响应。
所以方法是: public abstract T4 transformBackendResponseToClientResponse(T3 backendResponse); 将变成: public abstract T4 transformBackendResponseToClientResponse(T1 clientRequest, T3 backendResponse); 但是,这只适用于服务的一小部分。因此,我不想在95%的服务中添加另一个抽象方法,也不想更改签名以保留一个方法,因为这将是对具体类的更改。另一种解决方案是有一个包含公共方法的父抽象类和两个子抽象类。每一个都会有不同的味道 transformBackendResponseToClientResponse ,但是 getResponse 必须在每个抽象类中重复。
如何在没有代码重复的情况下实现这一点?

wkyowqbh

wkyowqbh1#

一种选择是在~5%的情况下使用一个额外的接口。该接口可以如下所示,您的具体类将定义为 extends CommonService implements LessCommonInterface :

interface LessCommonInterface<T1, T3, T4> {
    T4 transformBackendResponseToClientResponse(T1 clientRequest, T3 backendResponse);
}

另一种选择是创建扩展第一个抽象类的第二个抽象类。这样,大约95%的具体类将被定义为 extends CommonService ,而~5%将被定义为 extends LessCommonService :

abstract class LessCommonService<T1, T2, T3, T4> extends CommonService {
    public abstract T4 transformBackendResponseToClientResponse(T1 clientRequest, T3 backendResponse);
}

另一种选择是像您当前所做的那样使用单个抽象类,并更改95%和5%用例的签名,以传递某种 Package 器对象,该对象总是包含 T1 对象,有时包含 T3 但这种代码很混乱,随着时间的推移可能会产生问题。

hec6srdp

hec6srdp2#

如果您使用的是java8+,那么可以使用默认方法实现。所以一步一步就是1。从commonservice中提取接口,其中包含所有要重写的方法,例如

interface ICommonService<T1, T2, T3, T4>{
       T2 transformClientRequestToBackendRequest(T1 request);
       T4 transformBackendResponseToClientResponse(T3 backendResponse);
       T4 transformBackendResponseToClientResponse(T1 clientRequest, T3 backendResponse);   
       default T4 transformBackendResponseToClientResponse(T1 clientRequest, T3 backendResponse) {
           return transformBackendResponseToClientResponse(clientRequest);
    }
    }

2.将抽象类标记为实现接口。95%将使用默认实现,其他将使用覆盖版本。希望有帮助

相关问题