作者:兄弟465748208_279 | 来源:互联网 | 2022-10-25 17:42
我正在使用一个外部库,该库提供紧密相关的类(从某些模板生成),但是不幸的是,没有共享的接口,例如
public class A {
public UUID id();
public Long version();
public String foo();
public String bar();
}
public class B {
public UUID id();
public Long version();
public String foo();
public String bar();
}
public class C {
public UUID id();
public Long version();
public String foo();
public String bar();
}
// ... and more: D, E, F, etc.
鉴于我对外部库没有影响,编写共享相同方法签名的一组类的公共逻辑的惯用方式是什么(至少对于公共逻辑使用的方法而言)?
目前,我会根据具体情况做以下三件事之一:
我编写了辅助方法,这些方法从每个对象获取原始结果,例如
private static void myHelper(UUID id, Long version, String foo, String bar) {
...
}
这样,无论类型如何,我都可以“解压缩”对象:
myHelper(whatever.id(), whatever.version(), whatever.foo(), whatever.bar());
但这很罗word,尤其是当我需要与许多成员一起工作时。
在仅使用吸气剂的情况下(即仅需要访问对象的当前值),我找到了一种使用诸如Dozer或ModelMapper之类的映射库将A或B或C映射到我自己的通用类的方法。 ,例如
public class CommonABC {
UUID id;
Long version;
String foo;
String bar;
}
通过玩配置,您可以获取这些库以将所有成员(无论是方法还是字段,公共或私有)映射到您的类,例如
modelMapper.getConfiguration()
.setFieldMatchingEnabled(true)
.setFieldAccessLevel(Configuration.AccessLevel.PRIVATE);
但这是一种“大刀阔斧”的方法,这是IMO显然没有理由仅仅为了排除重复代码而做出的破解。
最后,在某些其他情况下,最简洁的做法是
private static void myHelper(Object extLibEntity) {
if (extLibEntity instanceof A) {
...
} else if (extLibEntity instanceof B) {
...
} else if (extLibEntity instanceof C) {
...
} else {
throw new RuntimeException(...);
}
}
很明显为什么这很糟糕。
在企业环境中,您必须以这种方式来使用图书馆,您将怎么办?
我倾向于编写一个非常明确的(如果是冗长的)映射器(不使用通用映射器库),该映射器从一开始就转换这些实体。但是,我想知道是否有更好的方法。(例如,是否有一种方法可以在运行时将对象“投射”为实现新接口?)