使用参数化方法的工厂模式

这些是一组都遵循相同算法的服务。消费者调用这些服务,这些服务将对消费者的请求发送到某个后端系统。服务接口是RESTful,后端是SOAP。因为它们都遵循相同的模式,所以我们有一个抽象类。方法的顺序是固定的,即commonmethodOne需要在commonmethodTwo等之前发生。

由于每个服务接口不同,具体类将必须实现两个抽象方法。

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必须在每个抽象类中重复。

如何在没有代码重复的情况下实现?

plokmn0987 回答:使用参数化方法的工厂模式

一个选择可能是在〜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,T4> extends CommonService {
    public abstract T4 transformBackendResponseToClientResponse(T1 clientRequest,T3 backendResponse);
}

另一种选择是像现在一样使用单个抽象类,并更改95%和5%用例的签名以传递某种总是包含T1对象的包装对象并且有时包含一个T3对象,但是这种代码很杂乱,随着时间的推移可能会产生问题。

,

如果您使用的是Java8 +,则可以使用默认方法实现。因此,将逐步 1.使用所有您要覆盖的方法从CommonService提取接口,例如

 interface ICommonService<T1,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%将使用默认实现,其他将使用替代版本。希望对您有帮助

本文链接:https://www.f2er.com/2715996.html

大家都在问