我有一个抽象类,有些类扩展了抽象类。现在我想在子类中存在的每个函数之前进行一些预处理(例如,函数只是从DB中获取实体,所以在进行DB之前,只需检查缓存中的实体,如果实体存在于缓存然后返回else调用call()
或call(final Set<String> args)
获取实体将其存储在缓存中并返回)。所以我介绍了一个例如
interface PQRCallable <K> {
K call();
Set<K> call(final Set<String> args);
}
在call
函数内部,子类函数写入逻辑以从DB中获取实体。现在,子类中的每个函数都调用抽象类中存在的两个常见函数之一,即doProcessing(String k, ..., PQRCallable pQRCallable)
doProcessing(Set<k>, ..., PQRCallable pQRCallable)
和PQRCallable
,这样如果预处理将面临任何问题,它将回退到call()
或call(final Set<String> args)
。
我的问题是,现在子类中的每个函数都需要实现这两个函数。 doProcessing(Set<k>, ..., PQRCallable pQRCallable)
将始终致电Set<K> call(final Set<String> args);
,doProcessing(String k, ..., PQRCallable pQRCallable)
将始终致电K call();
。因此实际上子类只实现一个函数,而对于其他函数,它们应该抛出一些异常,如UnsupportedOperationException
。
是否有人可以建议我采取更好的方法。感谢。
答案 0 :(得分:0)
也许模式decorator可以帮助您解决这个问题。
很抱歉这个链接在C#中,但有一个很好的UML架构!
答案 1 :(得分:0)
包装doProcessing方法:
doProcessing(String k, ...){
this.pQRCallable.call();
//Your processing logic
//It could be useful to catch the UnsupportedOperationException
}
doProcessing(Set<K> k, ...){
this.pQRCallable.call(args);//you didn't specify how you are getting the args
//Your processing logic
}
您可以看到pQRCallable
现在是抽象类中的一个字段,您可以在运行时通过实用程序类或使用具体子类的构造函数来设置它。
子类不必实现您的界面,在运行时,您将确保设置正确的PQRCallable(实现所需呼叫的那个)
答案 2 :(得分:0)
您可以使用Dynamic Proxies包装数据库方法。在您的调用处理程序中,您可以检查所请求的对象是否已在缓存中。只有当它们不在您的缓存中时,您才能将调用转发到您的实际数据库访问对象。
例如代码签出:http://tutorials.jenkov.com/java-reflection/dynamic-proxies.html
答案 3 :(得分:0)
考虑使用具有缓存的成熟数据访问框架,例如Hibernate second-level cache。
如果失败,您的情况最适合GoF Template Method模式。请特别注意real world example for DataAccessObject。