Java (Android) library project - 如何设计可选模块?
Java (Android) library project - How to design optional modules?
我正在创建一个基于 Android (Java) 的库项目 (JAR),其中有 -
- 核心功能
- 可选功能
现在由于大小限制,我必须将这个 JAR 分成 JAR 集合,这个库的用户可以灵活地包含可选的 JAR。同时,需求是为用户提供一个单一的接口,使用它他们应该能够调用 both 核心和可选的 APIs。为此,我想到了两个解决方案 -
解法-1
在核心库中为接口实现 class,其中与核心功能相关的 API 在这里实现,但可选功能的 API 将使用反射从此处调用,因此如果 class 找到,表示包含可选库,否则不包含。
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
}
}
Pros - 这里仅 optional 包括 core(用于核心实用程序方法),核心不包括可选。所以没有循环依赖。
缺点 - 使用反射
解法-2
为避免解决方案 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. core 和 optional 存在循环依赖,因为 core 包括 optional 来调用 optional API 和 可选 包括核心 以使用核心实用程序和服务。
2. 用户必须强制包含可选的 JAR(完整或空的实现)
您推荐哪种解决方案或其他更好的解决方案?请提出建议。
您可以使用桥接模式。在core文件中为每个可选的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 创建一个构建器,您可以在其中相应地设置实现。
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();
}
}
}
我正在创建一个基于 Android (Java) 的库项目 (JAR),其中有 -
- 核心功能
- 可选功能
现在由于大小限制,我必须将这个 JAR 分成 JAR 集合,这个库的用户可以灵活地包含可选的 JAR。同时,需求是为用户提供一个单一的接口,使用它他们应该能够调用 both 核心和可选的 APIs。为此,我想到了两个解决方案 -
解法-1 在核心库中为接口实现 class,其中与核心功能相关的 API 在这里实现,但可选功能的 API 将使用反射从此处调用,因此如果 class 找到,表示包含可选库,否则不包含。
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
}
}
Pros - 这里仅 optional 包括 core(用于核心实用程序方法),核心不包括可选。所以没有循环依赖。
缺点 - 使用反射
解法-2 为避免解决方案 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. core 和 optional 存在循环依赖,因为 core 包括 optional 来调用 optional API 和 可选 包括核心 以使用核心实用程序和服务。
2. 用户必须强制包含可选的 JAR(完整或空的实现)
您推荐哪种解决方案或其他更好的解决方案?请提出建议。
您可以使用桥接模式。在core文件中为每个可选的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 创建一个构建器,您可以在其中相应地设置实现。
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();
}
}
}