Java 为我的类中使用的通用pojo建模
我正在尝试创建一个像通用POJO一样工作的对象,因为我必须通过不同的对象传递它,并且我需要一个接口,它们可以通过该接口访问它的属性 目前,我使用一个具有getField方法的基本对象执行此操作,在该方法中,我输入参数的名称,然后通过反射获得参数,如下所示:Java 为我的类中使用的通用pojo建模,java,design-patterns,pojo,dto,Java,Design Patterns,Pojo,Dto,我正在尝试创建一个像通用POJO一样工作的对象,因为我必须通过不同的对象传递它,并且我需要一个接口,它们可以通过该接口访问它的属性 目前,我使用一个具有getField方法的基本对象执行此操作,在该方法中,我输入参数的名称,然后通过反射获得参数,如下所示: public abstract class BasePOJO{ public Object getField(String fieldName){ try { return this.get
public abstract class BasePOJO{
public Object getField(String fieldName){
try {
return this.getClass().getField(fieldName).get(this);
} catch (NoSuchFieldException ex) {
Logger.getLogger(BaseRequest.class.getName()).log(Level.SEVERE, null, ex);
} catch (SecurityException ex) {
Logger.getLogger(BaseRequest.class.getName()).log(Level.SEVERE, null, ex);
} catch (IllegalArgumentException ex) {
Logger.getLogger(BaseRequest.class.getName()).log(Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
Logger.getLogger(BaseRequest.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
}
public class CredentialsPOJO extends BasePOJO{
public String username;
public String password;
}
credentialsPojo.getField("username");
String name = pojo.getProperty("name");
Integer age = pojo.getProperty("age");
我用它来扩展类,如下所示:
public abstract class BasePOJO{
public Object getField(String fieldName){
try {
return this.getClass().getField(fieldName).get(this);
} catch (NoSuchFieldException ex) {
Logger.getLogger(BaseRequest.class.getName()).log(Level.SEVERE, null, ex);
} catch (SecurityException ex) {
Logger.getLogger(BaseRequest.class.getName()).log(Level.SEVERE, null, ex);
} catch (IllegalArgumentException ex) {
Logger.getLogger(BaseRequest.class.getName()).log(Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
Logger.getLogger(BaseRequest.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
}
public class CredentialsPOJO extends BasePOJO{
public String username;
public String password;
}
credentialsPojo.getField("username");
String name = pojo.getProperty("name");
Integer age = pojo.getProperty("age");
并调用如下属性:
public abstract class BasePOJO{
public Object getField(String fieldName){
try {
return this.getClass().getField(fieldName).get(this);
} catch (NoSuchFieldException ex) {
Logger.getLogger(BaseRequest.class.getName()).log(Level.SEVERE, null, ex);
} catch (SecurityException ex) {
Logger.getLogger(BaseRequest.class.getName()).log(Level.SEVERE, null, ex);
} catch (IllegalArgumentException ex) {
Logger.getLogger(BaseRequest.class.getName()).log(Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
Logger.getLogger(BaseRequest.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
}
public class CredentialsPOJO extends BasePOJO{
public String username;
public String password;
}
credentialsPojo.getField("username");
String name = pojo.getProperty("name");
Integer age = pojo.getProperty("age");
我很快就创造了这个,这很可怕,但它很有效。但我想把它改成更合适的模型来模拟那个物体
También he creado el-siguiente:
public class BasePOJO{
private Map<String, Object> parameters = new HashMap<>();
public void addParameter(String paramName, Object value){
parameters.put(paramName, value);
}
public Object getParameter(String paramName){
return parameters.get(paramName);
}
}
公共类BasePOJO{
私有映射参数=new HashMap();
public void addParameter(字符串参数名、对象值){
parameters.put(paramName,value);
}
公共对象getParameter(字符串paramName){
返回参数.get(paramName);
}
}
我更喜欢这个对象,它的OO解决方案,问题是它只返回一种对象类型
其思想是,使用此POJO的对象可以以通用方式访问其属性。
如果有一个设计模式能更好地解决这个问题,那么我可以实现它。您即将创建一个新的设计模式。这通常是个坏消息 使用通用POJO,在调用方法时无法从IDE获得支持(因为它们根本不存在)。此外,如果您忘记了字段或拼写错误,您也会遇到问题。若不冒字符串中的名称出现问题的风险,重构也是不可能的 如果项目中不止您一人,您的同事是否能够理解并使用此解决方案?你能在6个月后、1年后、5年后再回来吗 尽可能简单地使用属性方法(getXyz、setXyz),并根据其用途对具有不同类的对象调用它们 查看您的IDE,它可能能够为您的字段自动生成getter和setter方法,因此本质上,您只需设置字段,然后按下按钮即可完成其余操作。(IntelliJ IDEA和Eclipse也做了这件事,我知道有两个。我很确定Netbeans也做了。) 如果你不确定你需要什么课程,那就为你的问题创建课程。一个好的开始是为用例文本中的名词创建类,为动词创建方法。之后,你就可以开始推广了。(尽管要小心API、框架和适合所有人的解决方案,即使它们很诱人……我也喜欢它们!直到我意识到我正在构建一个静态站点生成器,而不是打印一些HTML文件……通常是几周后……) 说到这里,可能有一些框架可以从数据库模式(Hibernate?)和web服务等生成类,也许这就是方法。无论如何,这些仍然是具有实际属性方法等的类
希望这有帮助 类似的东西在PHP中工作(例如Magento-magic方法),我真的认为这是一种糟糕的机制 为什么? 如果字段不存在,则没有IDE控件。您的类API不清楚,因此出错的风险非常高。您必须研究实现,以了解可以使用哪些字段。在您的示例中,您还通过公开字段来打破封装,这样任何人都可以直接使用它,而无需使用您的方法
在这些日子里,使用自动生成的getter/setter没有必要这样做。如果您想摆脱样板文件的getter/setter代码,可以使用例如。术语澄清 POJO=普通的旧Java对象,也就是说,它不使用一些用于“修饰”对象行为的第三方注释(Hibernate的实体注释,或者已经提到的生成方法的Lombok)。与您的案例相匹配的是Bean=类,每个类字段都有getter和setter 问题的解决方案
// derive type from left side of the assignement operator
public <T> T getProperty(String paramName){
return (T) parameters.get(paramName);
}
退税
由于给定的方法只是显式地将映射值强制转换为“赋值运算符左侧的任何类型”,因此无法实现编译时检查,从而在写入后立即发出警告:Integer age=getProperty(“name”)代码>。注意,在执行代码时,还存在运行时类型检查。这样的赋值将抛出一个ClassCastException
请记住,只要您将map定义为map
,就无法获得编译时检查-给定键下的值实际上可以是任何值。这也适用于反射方法,因为getField(String)
返回隐藏在Object
类型中的属性值
要进行编译时检查,请阅读建议部分
建议
我强烈建议您使用project,正如@Peteef已经提到的。确保在IDE中也安装了lombok插件,否则自动生成的方法将生成语法错误
注释将为每个字段生成getter,为每个非最终字段生成setter。此外,@Data
注释还将生成equals
和hashCode
方法,当对象存储在或集合中时,这些方法非常重要。如果要检查两个对象是否相同(相同的字段值),方法equals
可能也是可取的
注意,如果这些类被用作简单的数据保持器,那么您仍然可以使用带有公共字段的简单类,而不使用getter/setter。当然,这不是OOP,但你不必盲目地遵循每一个惯例(有时它们是有效率的)
在没有实际收益的情况下,为什么要进行推广?你需要实现什么?我需要概括它,因为那个对象必须经过几个过程