【发布时间】:2016-09-28 17:46:41
【问题描述】:
我正在尝试设计一个映射器,它将一种对象类型转换为下图中显示的另一种对象类型:
对象的结构如下(不是 JSON):
{
"type": "DownloadAppComponent",
"name": "Download App",
"contentId": "download-app",
"properties": {
"iosUrl": "http://apple.com",
"androidUrl": "http: //google.com",
"promoText": "Download our app",
"hidden": false
}
我的第一个解决方案是为每种类型设置映射器,但这需要大量重复代码来映射公共属性(即名称、类型、contentId)。
public DownloadAppComponent map(CmsDocument cmsDocument) {
DownloadAppComponent downloadAppComponent = new DownloadAppComponent();
downloadAppComponent.setType(cmsDocument.getType()); // <-- this will be duplicated in each mapper
downloadAppComponent.setName(cmsDocument.getName()); // <-- this will be duplicated in each mapper
downloadAppComponent.setContentId(cmsDocument.getText(CONTENT_ID_PATH)); // <-- this will be duplicated in each mapper
downloadAppComponent.setIosURL(cmsDocument.getText(IOS_URL_PATH));
downloadAppComponent.setAndroidURL(cmsDocument.getText(ANDROID_URL_PATH));
downloadAppComponent.setHidden(Boolean.parseBoolean(cmsDocument.getText(HIDE_PATH)));
downloadAppComponent.setPromoText(cmsDocument.getText(DOWNLOAD_PROMO_TEXT_PATH));
return downloadAppComponent;
}
我一直在尝试重构该代码,并提出了通用 BaseDocumentMapper:
public BaseDocument map(CmsDocument cmsDocument) {
BaseDocument document = documentsMapperFactory.getMapper(cmsDocument.getType()).map(cmsDocument);
document.setType(cmsDocument.getType());
document.setName(cmsDocument.getName());
document.setContentId(cmsDocument.getText(CONTENT_ID_PATH));
return document;
}
documentsMapperFactory 返回特定的映射器,该映射器将仅映射类型相关的属性并返回该对象实例。
但是,继承还有更多级别,我只有一个类型值可以解析为具体的映射器。所以我必须在每个组件映射器中重复组件的特定字段映射。我在想,因为我知道层次结构,我可以创建一些映射器,将文档从上到下映射,即创建第一个 DownloadAppComponent,然后使用 Component 扩展它,然后使用 BaseDocument 特定属性。但是,除了在映射器中使用抽象类和继承之外,我还没有找到任何好的解决方案。
如果这是一种好方法,或者对于我的情况有任何问题或其他更好的解决方案,有人可以给我建议吗?
谢谢。
【问题讨论】:
-
好吧,我会先尝试使用现有的库,比如dozer.sourceforge.net。
标签: java inheritance mapping