【问题标题】:How to avoid casting of interfaces with good design?如何避免铸造具有良好设计的接口?
【发布时间】:2023-03-16 07:55:01
【问题描述】:

我的接口有问题。特别是我使用了一个需要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 的对象。 这两个接口不仅有不同的签名方法,而且还有额外的 ad hoc 方法。

我考虑过使用适配器模式,使用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 对象时(例如,当我调用 KDTree class of librarynearest method 时)我应该将其转换为 LocationAdapter并调用 removeAdapter() 方法获取原始 ILocation 对象,我可以在库外使用它。
这个解决方案增加了开销,因为最初我从数据库中将 ILocation 对象加载到内存中,然后为每个对象创建适配器并将其传递给库。考虑到我是在android上开发的,存储在db中的对象很多(大约1000个)。

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

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

很抱歉问了这么长的问题。

【问题讨论】:

  • 你能添加一个MVCE吗? IMO 真的很难理解你的问题。您正在询问overheaddatabase, memory, library, andorid` 和更多主题。真的很难说出你的实际问题是什么。
  • 我很困惑你的 'distance' 方法返回的是 'double' 而不是 'IMultiPoint'。
  • 我很抱歉这个错误,我编辑了这个问题。我使用了一个名为 KDTree(一个特定的搜索二叉树)的类,它有一个最近的(IMultiPoint imp),它返回树中最近的 IMultiPoint。为了完整起见,我应该添加另一个代码还是 uml 类图?

标签: java interface casting adapter


【解决方案1】:

我认为这个适配器应该实现这两个接口,这样任何一个实例都可以替代这些接口中的任何一个。因此,您可能不需要任何强制转换。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2022-08-12
  • 2015-09-15
  • 2011-05-09
  • 1970-01-01
  • 2012-12-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多