我必须完成的任务已经交付,但在我的脑海中仍然存在一个问题。
我定义了以下界面:
package dao;
import java.sql.SQLException;
/**
* Get / save / delete a single instance from the db in RESTful fashion on the object
* @author kimg
*
* @param <T>
*/
public interface IDao<T> {
public void fetch(int id);
public void save() throws SQLException;
public void delete() throws SQLException;
}
目的是让所有表示为数据库表实体的pojo实现这些方法,因此pojo的用户知道如何根据模式处理实例。我从Backbone(Javascript)采用了这种方法。
但是,还有其他方法我喜欢在Pojo类本身上强加类方法(静态)。最明显的方法是:
List<Person> list = Person.fetchAll();
List<Person> list = Person.fetchAll(offset, limit);
int i = Person.countAll();
...
我发现默认情况下定义这些方法会带来很大的好处,但是没有什么能迫使开发人员实现它们,因为默认情况下不能强制使用静态方法。此外,类的用户无法确定他们是否能够使用他们原本期望通过合同预期的静态方法(如果是接口);方法名称中的任何拼写错误,省略任何方法都可能导致平滑的应用程序工作流程中断。
抓住这个陷阱最优雅的解决方案是什么?
答案 0 :(得分:2)
我发现默认定义这些方法提供了很大的好处,但是没有什么能迫使开发人员实现它们,因为默认情况下不能强制使用静态方法。
如果这些方法非常有用,那么开发人员想要来实现它们是不是很有用?至少如果他们意识到所需的模式和实施它们的有用性呢?
此外,班级用户无法确定他们是否能够使用他们原本期望通过合同预期的静态方法(如果是接口)
这无关紧要,因为静态方法不是虚拟的。用户做确定他们想要调用其静态方法的类型是否确实具有该方法。如果他们忘了那么编译器会很乐意告诉他们。
方法名称中的任何拼写错误,省略任何方法都可能导致平滑的应用程序工作流程中断。
我不确定我是否跟着你。如果你在谈论开发人员未能实现这些静态方法或者错误地执行这些方法,那么那就是代码审查的目的。您还可以编写反映验证方法的自动化测试。存在。我真的不明白这是一个比使用所需签名实现的方法更大的问题但是实现不正确。
同样,静态方法不是虚拟的。每个静态方法调用的用户在编译时都知道正在调用哪个方法,因此是否可以使用这种方法。如果他们想要一个特定的方法并且没有它,那么他们可以选择添加它,自己添加它,或者不添加它。
抓住这个陷阱最优雅的解决方案是什么?
记录任何此类期望。让项目管理人员强制执行(如果他们拒绝这样做,那么也许它毕竟不是那么重要)。使用代码审查。编写自动化测试,也许是反思性测试。
答案 1 :(得分:0)
不要在Entity上使用这些方法,而是将它们放在repo / Dao上:
public interface IDao<T> {
void fetch(int id);
void save() throws SQLException;
void delete() throws SQLException;
List<T> list();
List<T> list(offset, limit);
int count();
}
public class Person {
//...getters/setters/fields...
}
public class PersonDao implements IDao<Person> {//todo make me a singleton
//implement the interface here
}