如何避免铸造具有良好设计的接口?

时间:2018-02-16 00:56:09

标签: java interface casting adapter

我的接口有问题。特别是,我使用了一个需要IMultiPoint接口的库,但是我的类实现了ILocation,如下所示:

IMultiPoint interface (library source code)

/* 
 * My custom interface: the ILocation is a "class" of objects that can be 
 * represented in two different systems: the plane (with coordinates x and 
 * y, expressed in meters) and the signal space (the number of dimensions 
 * is the number of bluetooth beacons).
*/
public interface ILocation {

    // returns the name of the region where the point is located
    String getRegion();

    void setRegion(String region);

    // returns the Cartesian coordinates x and y (expressed in meters) in the plane
    double[] getCartesianCoordinates();

    void setCartesianCoordinates (double x, double y);

    /* returns all dimensions in signal space (ordered for 
       beacon/dimension), with their relative values of power (rssi) */
    SortedMap<IBeacon, Integer> getAllRssi();

    void setRssi(Map<IBeacon, Integer> dimensions);

}

所以我有一个可以是ILocation或IMultiPoint的对象。 这两个接口不仅具有不同的签名方法,而且还有其他特殊方法。

我考虑使用适配器模式,使用Hyperpoint class of library

public class LocationAdapter implements IMultiPoint {

    private ILocation location;
    private IMultiPoint multiPoint;

    public LocationAdapter(ILocation location) {
        this.location = location;
        double[] coordinates = Doubles.toArray(location.getAllRssi().values());
        // Default IMultiPoint implementation, provided by the library
        this.multiPoint = new Hyperpoint(coordinates);
    }

    int dimensionality() {
        return this.multiPoint.dimensionality();
    }

    double getCoordinate(int dx) {
        return this.multiPoint.getCoordinate(dx);
    }

    double distance(IMultiPoint imp) {
        return this.multiPoint.distance(imp);
    }

    double[] raw() {
        return this.multiPoint.raw();        
    }

    // To obtain original object
    ILocation removeAdapter() {
        return this.location;
    }

}

此解决方案允许我将ILocation对象传递给库(通过适配器),但是当库返回一个IMultiPoint对象时(例如当我调用nearest methodKDTree class of library时)我应该将它放在LocationAdapter中并调用removeAdapter()方法以获取原始ILocation对象,我可以在库外使用它。
这个解决方案增加了开销,因为最初我在内存中加载来自db的ILocation对象,稍后我为每个对象创建适配器并将其传递给库。存储在数据库中的对象很多(大约1000个),考虑到我在android上开发。

另一个解决方案是创建一个实现ILocation并扩展Hyperpoint的Location类,但是我被迫使用强制转换,此外,如果我将来更改库,我也应该更改此类。

我该怎么办?我哪里错了?我想做一个好的设计。

对不起,我很抱歉。

1 个答案:

答案 0 :(得分:0)

我认为这个适配器应该实现这两个接口,以便任何这样的实例都可以代替任何这些接口。因此,您可能不需要任何演员。