Java(Android)库项目 - 如何设计可选模块?

时间:2016-01-23 18:47:59

标签: java android reflection jar circular-dependency

我正在创建一个基于Android(Java)的库项目(JAR),其中有 -

  1. 核心功能
  2. 可选功能
  3. 现在由于大小限制,我必须将这个JAR分解为JAR集合,其中该库的用户可以灵活地包含可选的JAR。同时,要求是为用户提供单一界面,使用该界面他们应该能够调用 核心和可选API。为实现这一目标,我有两个解决方案 -

    解决方案-1 在核心库中具有接口的类实现,其中与核心功能相关的API在此处实现,但是可选功能的API将使用反射从此处调用,因此如果找到类,则表示包含可选库,否则不包括。

    APIInterface.java

    public interface APIInterface {
        public void coreMethod();
        public void optionalMethod();
    }
    

    CoreClass.java

    public class CoreClass implements APIInterface {
      public void coreMethod() {
        // implementation
      }
      public void optionalMethod() {
        // use reflection to access optional method from OptionalClass
      }
    }
    

    OptionalClass.java

    public class OptionalClass {
      public void optionalMethod() {
        new CoreClass().utilityMethod(); // or super.utilityMethod();
        // implementation
      }
    }
    

    优点 - 此处只有可选包含核心(对于核心实用程序方法),核心不包括可选的的。所以没有循环依赖 缺点 - 使用反射

    解决方案-2 为避免在solution-1中提到的反射,请创建两个版本的可选库。首先是完全实现,第二个是空实现(只有包装器)。用户必须强制要求包括其中一个,取决于用户是否需要可选功能。有了这个,依赖关系将被反转。因此,核心默认包含可选库,并且可以从可选库中调用API而无需反射。

    APIInterface.java

    public interface APIInterface {
        public void coreMethod();
        public void optionalMethod();
    }
    

    CoreClass.java

    public class CoreClass implements APIInterface {
      public void coreMethod() {
        // implementation
      }
      public void optionalMethod() {
        new OptionalClass().optionalMethod();
      }
    }
    

    OptionalClass.java //完整实施

    public class OptionalClass {
      public void optionalMethod() {
        new CoreClass().utilityMethod(); // or super.utilityMethod();
        // optional implementation
      }
    }
    

    OptionalClass.java //空实现

    public class OptionalClass {
      public void optionalMethod() {
        // do nothing
      }
    }
    

    职业选手 - 没有反思
    缺点 - 1.核心和可选的循环依赖,因为核心包括可选来调用可选API而可选包括核心使用核心公用事业和服务。
    2.用户必须强制包含可选的JAR(完整或空实现)

    您推荐哪种解决方案或任何其他更好的解决方案?请建议。

1 个答案:

答案 0 :(得分:2)

您可以使用桥接模式。为核心文件中的每个可选jar文件提供一个接口,并在可选的jar中实现该接口。

// in the core jar file
public interface Optional {
    void optionalMethod();
}

// in the optional jar file
public class OptionalImpl implements Optional {
    public void optionalMethod() {
        // implementation
    }
}

现在,为CoreClass创建一个Builder,您可以在其中相应地设置实现。

CoreClass coreClass = new CoreClass.Builder()
    .setOptional(new OptionalImpl())
    .build();

在CoreClass中,检查是否存在实现,并相应地委派调用。

public class CoreClass implements APIInterface {
    // is set via Builder
    private Optional optional = null; 

    public void coreMethod() {
        // implementation
    }

    public void optionalMethod() {
        if(optional != null) {
            optional.optionalMethod();
        }
    }
}