我有一个类集合,将它们称为 Derived1、Derived2、...、Derived6
,每个类都是基类 Base
的子类。这些类是在第三方 Java 包中定义的。
我正在编写一个类,它将写出这些对象的人类可读的表示形式。我按如下方式处理该问题:为每个 i=1,2,...,6
和 String 变换定义方法
。String transform(Derivedi object)
(基础对象)
例如,当 Base obj = new Derived3(...)
并且我想要计算 obj
的表示时,就会出现问题。表达式 transform(obj)
调用带有签名 String transform(Base)
的方法,该方法必须调用“正确”的方法(在本例中是带有签名 字符串变换(Derived3)
)。
方法String transform(Base object)
通过一系列if (obj instanceof Derivedi)
形式的条件语句为每个将工作委托(delegate)给适当的方法>i=1,2,...,6
。 (如果我可以控制包,我将在基类上有一个抽象方法 String toReadable()
,每个派生类都必须实现该方法;不幸的是,在这种情况下,我无法控制包.)
我不喜欢这个解决方案(很容易看出原因)。 String transform(Base)
的这种实现的替代方案是什么?
最佳答案
您可以尝试为每个类提供转换器(包含 transform(...)
的对象)。然后维护一个将变压器映射到这些类的映射(假设变压器本身是无状态的)。
示例:
class Transformer {
Class<? extends Base> getTransformableClass() { ... }
String transform( Base obj ){
//check and cast obj to the actual type then create the string
}
}
Map<Class<?>, Transformer> transformers = ...;
Transformer base = new BaseTransformer(); //the same for derived
transformers.put( base.getTransformableClass(), base );
请注意,使用 CDI/Reflection,您可以自动执行查找(即查找实现特定接口(interface)或使用特定注释进行注释的所有类)。
然后像这样使用它:
public String transform( Base obj) {
//add null checks etc.
return transformers.get(obj.getClass()).transform(obj);
}
进一步注意,泛型在实现变压器时可能会有所帮助,但是从 map 中使用它们会需要一些强制转换/原始类型,因为您不知道从 map 中获得的实际类型,即您作为开发人员知道transformers.get( Derived1.class )
应该返回一个能够处理 Derived1
实例的转换器,但编译器不知道这一点,因此需要您处理它并进行适当的转换.
关于java - 下面的OOP设计有更好的替代方案吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37786748/