覆盖泛型类中的方法

时间:2011-09-28 20:07:05

标签: java generics refactoring

我重构了一些单元测试。基本上,我发现不同客户端的单元测试实现了一组方法,例如:createClientWithNullResponse,createClientWithSuccessResponse等。

我想知道Java是否有可能为此实现通用解决方案,因为这些方法在数百个单元类中反复重复,只更改方法签名。

但是,有一个棘手的问题。请参阅方法示例:

/**
 * configures the client to return a succesful response
 * @return a client configured to return a succesful response
 */
private Client1 configureClientWithSuccesfulResponse()
{
    client = new Client1()
    {
        public CommonClientResponse processRequest( CommonsClientRequest commonsClientRequest )
        {
            CommonClientResponse commonClientResponse = new CommonClientResponse();
            commonClientResponse.setResponse( new Client1Response() );
            return commonClientResponse;
        }
    };
    return client;
}

因此,client2将使用相同的方法,除了签名具有Client2,并且覆盖的方法创建新的Client2Response,并且与几十个客户端相同。

附加信息:processRequest被覆盖以充当模拟,设置我希望每个方法的响应。 Client1扩展了CommonsWS,它扩展了AbstractCommons,它是一个抽象类,但包含processRequest方法的实现。

总而言之,我的想法是为所有单元测试创​​建一个Base类,使用一组通用方法,我可以传递类类型,然后为每一个重写processRequest。我试过了:

public class base <T extends AbstractCommonClient>{

    private T configureClientWithNullResponse(Class <? extends AbstractCommonClient> clazz, Class< ? extends ClientResponse> clazz1)
    {

        try
        {
            return clazz.newInstance()
            {
                CommonClientResponse processRequest( CommonsClientRequest commonsClientRequest )
                {
                    CommonClientResponse commonClientResponse = new CommonClientResponse();
                    commonClientResponse.setResponse( clazz1.newInstance() );
                    return commonClientResponse;
                };
            };
        }
    }

}

但它甚至没有编译。你对我如何开始实现这个有什么想法吗?

2 个答案:

答案 0 :(得分:1)

由于您正在尝试创建一个类型在运行时未知的匿名类,您是否考虑过在运行时调用编译器?我自己并没有太多使用它,但它可能值得研究。您可以使用

调用它
JavaCompiler compiler = javax.tools.ToolProvider.getSystemJavaCompiler();

请注意,这仅在应用程序在安装了JDK的系统上运行时才有效,如JRE (does not include javac)

答案 1 :(得分:1)

这是一个棘手的问题。我建议创建一个Factory类,它将返回每种类型的客户端,并提供响应并将其传递给工厂。类似的东西:

public class ClientFactory {

    public static createResponse(ClientResponse response) {
        CommonClientResponse commonClientResponse = new CommonClientResponse();
        commonClientResponse.setResponse(response);
        return commonClientResponse;
    }

    public static Client1 createClient1(final ClientResponse response) {
       return new Client1() {
            public CommonClientResponse processRequest(CommonsClientRequest unused) {
                return createResponse(response)
            };
        }
    };

    public static Client2 createClient2(final ClientResponse response) {
       return new Client2() {
            public CommonClientResponse processRequest(CommonsClientRequest unused) {
                return createResponse(response)
            };
        }
    };

    ..... // same for every type of Client

你用它来称呼它:

    factory.createClient1(new Client1Response());

仍有一些重复,但它有所帮助。一点。 你觉得怎么样?