【问题标题】:Associate interfaces with classes without source access将接口与没有源访问的类关联
【发布时间】:2017-09-29 17:03:26
【问题描述】:

问题来了,我有两个绘图 JAR 库(A 和 B)。两者都提供单独但有用的功能。然而,在他们无限的智慧中,他们对基本点类有两种不同的概念。

都没有任何有趣或特别独特的方法或领域,基本上都归结为:

public class PointA{
   double x;
   double y;
}

public class PointB{
   double x;
   double y;
}

这些库中的函数具有如下所示的方法:

public static List<PointA> doInterestingThing();

public static PointB calculateThatThing();

我觉得应该有一些很好的方式来理解这两个类是针对所有意图的,相同的。

如果我有源代码访问权限,我可以让他们实现一些 IPoint 接口,但两个库都在 JARS 中。

在我看来,有几种选择:

  1. 将一个转换为另一个。要么使函数将所有 PointA 转换为 PointB,反之亦然。这实际上意味着通过使用一些样板转换代码包装其中的每个函数来在其中一个库之上创建一个抽象层。

    public static List<PointA>doInterestingThingWrapper(){
        return convertPoints(LibraryB.doInterestingThing()); 
    }
    
  2. 做一些第三类 PointC,这两个库的结果都转换为代表我的代码对一个点的理解。与上面相同的问题,但现在我需要编写两倍的样板转换!

  3. 直接编辑 JARS。显然这是不可取的。但是,它可以让我让 PointA 和 PointB 实现相同的接口。

  4. 一些神奇的动态界面交互我不知道。 会不会是 Java 有某种方式可以为已加载的类动态分配接口?

类似:

public interface IPoint{
   double getX();
   double getY();
}

public static void main(){
    //Magical made up linking syntax
    PointA implements IPoint{
        public getX(){
           this.getX()//PointA's method
        }
        public getY(){
           this.getY(){//pointA's method
        }
    }
    //And same for pointB

    //And now we can say things like:
    List<? extends IPoint> listOPoints=A.doInterestingThing();
    //and:
    IPoint thePoint=B.calculateThatThing();  
}

如果这是重复的,我提前道歉。我什至不知道如何称呼这个使搜索变得困难的问题。如果我错过了一些明显的设计模式(适配器模式?)可以解决这个问题,请告诉我。

【问题讨论】:

  • 您如何在代码中使用PointAPointB?如果这些类主要用于外部 API 调用,那么尝试创建抽象层没有多大意义,因为这些 API 无法使用它。 IE。你想用你的建议解决什么问题?
  • 目前我有一个PointC 类型,我可以在其中转换所有内容。我想你有一个很好的观点(哈哈),如果 A 或 B 中的大多数函数都有自己的观点,即doInterestingThing(PointA point),那么你总是需要转换它们。如果这些库已经定义并使用了自己的接口,我可以让 pointC 实现 IPointA 并且可以直接在 API 调用中使用它们而无需转换。
  • 我认为PointC(或只是您自己的Point)会很有用,如果您可以在外部 API 之上创建一个 facade 层,隔离与那里的那些图书馆的互动。然后,您可以让您的代码库仅依赖于公开单个“点”定义的“外观服务”。

标签: java inheritance interface


【解决方案1】:

你有两个解决方案

使用反射和非反射来使用相同的命名函数。

在您的项目代码中将两者包装到实现接口的对象中。

示例:

class A { public void d(){}}
class B { public void d(){}}
interface D { void d(); }
class AD extends A implements D {}
class BD extends B implements D {}

或者

class AD implements D {A obj = new A(); public void d(){obj.d();}}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-08-01
    • 1970-01-01
    • 1970-01-01
    • 2021-03-14
    • 1970-01-01
    • 2022-06-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多