我创建了一个简单的API,可以将任意对象转换为人类可读的字符串。将其视为一种通用的String.valueOf()
功能。
API通过选择
来实现这一目标 public interface ObjectFormatter {
public String format(Object object);
public Class getObjectClass();
public boolean offer(Object object);
}
取决于特定对象的getClass()
方法,然后将对象传递给format()
方法。通过简单的查找完成映射:
Class clazz = object.getClass();
ObjectFormatter formatter = this.formatters.get(clazz);
if(formatter != null)
return formatter;
但是,这当然仅适用于对象类和键类完全相同的情况,但API也必须能够映射关键类派生(或实现,如果键是interface
)对于相同的格式化程序,否则我最终会将Throwable
格式化程序映射到我的应用程序中的每个可能的异常类。
因此,当上面的查找失败时,我当前的解决方案是遍历整个地图并询问每个格式化程序是否能够格式化我的对象。 然而,我对此并不满意,我想知道是否有更好的方法。
嗯,简单地覆盖toString()
并忘记格式化程序的严格OOP方式可以在我自己的类上工作但在第三方库中失败,特别是当特定的toString()
实现不包括关于该对象的所需信息。
答案 0 :(得分:0)
基本上,这是一个小小的反思可以帮助的地方。
Class.getSuperclass()
浏览对象类的所有超类,但不要忘记在到达Object时停止超导,因为Object超类是Object。Class.getInterfaces()
来获取您的类实现的接口列表。显然,在接口上调用它将返回它扩展的接口...... 然后,您可以选择,您可以调用(1),然后调用(2)或(最好)调用(2)并聚合其结果,并且仅当(2)失败时,调用(1)。这样,你就会更尊重你所遵守的各种合同。
答案 1 :(得分:0)
我的快速而肮脏的想法是你可以遍历“clazz”的继承树,看看格式化程序是否包含它们。这样你可以添加一个Throwable格式化程序,所有异常都可以得到它。
从正确的OOP /继承角度来看,假设你不能修改实际的类,因为它是第三方,我可能会在第三方类中添加一个适配器,它有我想要的方法。在之前的项目中,我们拒绝这样做了一段时间,认为它太笨重/丑陋,但这只会导致很多hacky变通方法。当我们最终咬紧牙关并做到这一点时,我们可以回到常规的好设计。我的2美分。
答案 2 :(得分:0)
您可以使用java.lang.Class
的isAssignableFrom API另外如果我不是自己做整个框架,我会使用Spring的“PropertyEditor支持类”(将bean转换/格式化为字符串属性,反之亦然)http://static.springsource.org/spring/docs/2.5.x/reference/validation.html