1

我正在尝试为此找到一个优雅的解决方案,但无法弄清楚。

我在某个地方有一个通用数据提供者。我想调用它来获取任意对象——它会根据请求从缓存、服务器等获取它们。

我想这样称呼它,例如:

List<Customer> customers = new DataProvider().getData(new CustomersRequest(20));

这将为我提供所有 20 岁的客户。DataProvider 决定如何以及从何处获取这些数据。

CustomersRequest 扩展了 Request 类。

要获得此工作 getData 需要对 Request 实例进行 instanceOf 检查,并从 DB 缓存或远程提供程序调用相应的方法......类似于:

if (request instanceof CustomersRequest) {
    DBDataProvider dbDataProvider = new DBDataProvider();
    List<Customer> customers = dbDataProvider.getCustomers(request);

    if (customers == null) {
        RemoteDataProvider removeDataProvider = new RemoteDataProvider();
        customers = removeDataProvider.getCustomers(request);

        if (request.cacheInDB) {
            //save response to db
        }

        return customers;

    }

}

但这只有在我Object从这个方法返回一个时才有效——这会让我每次调用它时都进行一次强制转换。我认为这是合适的解决方案,因为我将返回的数据也基于我在里面做的投射。

据说实例很糟糕。

我找不到用泛型解决这个问题的方法。

我也可以这样做:

List<Customer> customers = new DataProvider().getCostumers(20);

但这意味着,我必须在 DataProvider 中为所有不同的对象和参数创建许多方法,并且在每个方法中调用一个通用方法,该方法将用于缓存检查和其他事情。使用这种常用方法,我遇到了与第一种方法相同的问题。

或者还有:

List<Customer> customers = new CustomersDataProvider().getCostumers(20);

在这里,我对实例和泛型不再有任何问题,因为它不再是泛型了。但不确定我是否可以正确地抽象这一点,以便在一个地方为所有可能的数据获取缓存访问和验证。

最好的方法是什么?

4

3 回答 3

2

这是类Class有用的情况。你可以有这样的方法:

List<Customer> customers = new DataProvider().getCostumers(20, Customer.class);

您的方法的签名将类似于:

T getCostumer(int age, Class<T> clazz)
于 2013-07-23T11:41:23.737 回答
0

无论如何,如果您使用 instanceof、getClass() 或常量字符串,您将有一个开关。

我更喜欢常量字符串,如果你想设计一个可以被外部用户调用的 API,我会发现它们更好。

只要您不在应用程序中将它们相乘,有一个开关并没有那么糟糕。您可以使用基于接口的基本 oop 技术,以便只保留一个交换机。

干杯

于 2013-07-23T18:34:02.470 回答
0

我认为这里优雅的解决方案是向类添加一个getDBDataProvider方法Request。现在getData不必担心是否CustomerRequestRequest. (仅关于返回是否为 null。)获得正确的责任DBDataProvider在于方法 override in CustomerRequest,它不需要instanceof或反射知道它确实是 a CustomerRequest

一般来说,为了优雅,我认为超类和接口应该有足够的方法来处理它们所有子类/实现的需求。这意味着许多工作代码不必处理子类,为一个特定子类编写的代码将自动适用于所有子类。

我认为很多时候你最好只使用instanceof. 您将编写更少的代码并更快地完成。您不必将 null(或琐碎)方法放入它们并不真正适用的类中。但是,如果您希望以您正在做的事情为基础,那么这种方法是一种更好的方法。

于 2013-07-23T18:41:36.650 回答