首页

分享基于标准化开发服务调用接口带来的MVC架构的重构优化(Controller层代码解耦)

标签:接口标准化,系统设计,解耦,重构,mvc,框架设计,framework     发布时间:2017-12-07   

一、前言

最近由于因接口标准化的项目需求,实现业务产品的接口层面的抽象标准化设计,需解决每次新产品渠道业务扩展造成接口层面对接调试(不同产品属性的差异化比较大,原有的接口都是面向具体化产品的),减少开发工作量,重复流程代码量。

二、重构目标

1.定义通用产品化接口文档 - 解决产品差异带来了开发新接口的重复代码

2.开发流程优化,提供抽象通用层和具体化代码解耦(实现差异化开发XML、DB配置),降低些重复代码,代码间耦合度

三、设计资料

1.接口文档

分享基于标准化开发服务调用接口带来的MVC架构的重构优化(Controller层代码解耦)

2.开发设计

重构前:接口联调、controller接口定义逻辑实现、servces层接口服务

重构后:xml用例报文配置、services服务层差异性开发

分享基于标准化开发服务调用接口带来的MVC架构的重构优化(Controller层代码解耦)

3.类设计

分享基于标准化开发服务调用接口带来的MVC架构的重构优化(Controller层代码解耦)

四、关键代码

1.GenericAssistServiceFactory 服务工厂类

public class GenericAssistServiceFactory { @b@@b@	private String sarName;@b@@b@	private ConcurrentMap<String, Appscene<?>> appscenemapping = new ConcurrentHashMap<String, Appscene<?>>();@b@@b@	protected Log logger = LogFactory.getLog(this.getClass());@b@@b@	private GenericAssistServiceFactory() {@b@	}@b@@b@	{@b@		List<Appscene<?>> _cfg_datas = new GenericXmlIFConfigure().getConfigures();@b@		for (Appscene<?> app : _cfg_datas) {@b@			if (app == null || StringUtils.isEmpty(app.getId())@b@					|| appscenemapping.containsKey(app.getId())) {@b@				logger.error("GenericConfigureException error,cause cfg  appsecne id  is null  or  id  repeated;detail>"@b@						+ app != null ? app.toString() : "app is null");@b@				continue;@b@			}@b@			logger.info("instance appscene;detail>" + app);@b@			appscenemapping.put(app.getId(), app);@b@		}@b@@b@		i @b@@b@	}@b@@b@	public static GenericAssistServiceFactory getEntry() {@b@		return InitialzationHolder.instance;@b@	}@b@@b@	public Appscene<?> getGuide(String accessId)@b@			throws GenericServiceInstanceException {@b@		return appscenemapping.get(accessId);@b@	}@b@@b@	@SuppressWarnings("rawtypes")@b@	public GenericAssistService getBean(String accessId)@b@			throws GenericServiceInstanceException {@b@		Appscene _appscene = appscenemapping.get(accessId);@b@		GenericAssistService serviceObj = null;@b@		try {@b@@b@			if (_appscene.getIsMock()) {@b@				serviceObj=new GenericAssistMockHooker(JSONStringUtils.filterChars(_appscene.getResBody()));@b@				logger.error("GenericAssistService instance @GenericAssistMockHooker"@b@						);@b@			} else {@b@				serviceObj = (GenericAssistService) PApp.getInstance()@b@						.getSARContext(sarName).getSpringContext()@b@						.getBean(Class.forName(_appscene.getServiceObj()));@b@				logger.error("GenericAssistService instance success@"@b@						+ serviceObj.getClass().getName());@b@			}@b@@b@		} catch (Exception e) {@b@			logger.error("GenericConfigureException error,cause cfg  appsecne id  is null  or  id  repeated;detail> "@b@					+ e.getMessage());@b@			throw new GenericServiceInstanceException(e.getMessage());@b@		}@b@		return serviceObj;@b@	}@b@@b@	protected static class InitialzationHolder {@b@		public static GenericAssistServiceFactory instance = new GenericAssistServiceFactory();@b@@b@	}@b@ @b@@b@}

2.GenericAssistService标准化服务接口

public interface GenericAssistService<T extends GenericVO> {@b@	@b@	public DataResult<?> getList(T valueObj) throws Exception;@b@	@b@	public DataResult<?> getList(String valueObj) throws Exception;@b@	@b@	public DataResult<?> getList(Map<String,?> valueObj) throws Exception;@b@	@b@	public DataResult<?> createOrUpdate(String valueObj) throws Exception;@b@	@b@	public DataResult<?> createOrUpdate(Map<String,?> valueObj) throws Exception;@b@	@b@@b@}

3.GenericAssistController通用接口定义

@Controller@b@public class GenericAssistController extends BaseController{@b@	@b@	@ResponseBody @b@	@RequestMapping("/getAccessGuide.do")@b@	public ModelMap getAccessGuide(@Valid GenericAssistGuideForm form) {@b@		logger.info("getAccessGuide_GenericAssistForm=" + form);@b@		ModelMap model=new ModelMap();@b@		try {@b@			model.put("responseCode", Constants.GENERIC_SUCCESS_CODE);@b@			model.put("responseMsg",  toGuideString(form.getAccessId()));@b@		}catch (Exception e) {@b@			model.put("responseCode", Constants.GENERIC_ERR_UNDEFINED_CODE);@b@			model.put("responseMsg",  Constants.GENERIC_ERR_UNDEFINED_MSG);@b@			model.put("data", "");@b@			logger.error("getGenericArchiveData_error=" + e.getMessage(), e);@b@		}@b@		logger.info("getAccessGuide_result=" + model);@b@		return model;@b@	}@b@	@b@	@b@	@ResponseBody @b@	@RequestMapping("/getGenericData.do")@b@	public ModelMap getGenericData(@Valid GenericAssistForm form) {@b@		logger.info("getGenericArchiveData_GenericAssistForm=" + form);@b@		ModelMap model=new ModelMap();@b@		try {@b@			DataResult<?>  dataResult=null;@b@			if(GenericReqTypes.getType(form.getReqType())==GenericReqTypes.t1){@b@				dataResult =GenericAssistServiceFactory.getEntry().getBean(form.getAccessId()).getList(toGenericJson(form));@b@			}else if(GenericReqTypes.getType(form.getReqType())==GenericReqTypes.t2){@b@				dataResult =GenericAssistServiceFactory.getEntry().getBean(form.getAccessId()).getList(toGenericString(form));@b@			}@b@			model.put("responseCode", Constants.GENERIC_SUCCESS_CODE);@b@			model.put("responseMsg", Constants.GENERIC_SUCCESS_MSG);@b@			model.put("data", JSON.toJSONString(dataResult, SerializerFeature.WriteNullStringAsEmpty));@b@		}catch (Exception e) {@b@			model.put("responseCode", Constants.GENERIC_ERR_UNDEFINED_CODE);@b@			model.put("responseMsg",  Constants.GENERIC_ERR_UNDEFINED_MSG);@b@			model.put("data", "");@b@			logger.error("getGenericArchiveData_error=" + e.getMessage(), e);@b@		}@b@		logger.info("getGenericArchiveData_result=" + model);@b@		return model;@b@	}@b@	@b@	@b@	@ResponseBody @b@	@RequestMapping("/postGenericData.do")@b@	public ModelMap postGenericData(@Valid GenericAssistForm form) {@b@		logger.info("postGenericData_GenericAssistForm=" + form);@b@		ModelMap model=new ModelMap();@b@		try {@b@			DataResult<?>  dataResult=null;@b@			if(GenericReqTypes.getType(form.getReqType())==GenericReqTypes.t1){@b@				dataResult =GenericAssistServiceFactory.getEntry().getBean(form.getAccessId()).createOrUpdate(toGenericJson(form));@b@			}else if(GenericReqTypes.getType(form.getReqType())==GenericReqTypes.t2){@b@				dataResult =GenericAssistServiceFactory.getEntry().getBean(form.getAccessId()).createOrUpdate(toGenericString(form));@b@			}@b@			model.put("responseCode", Constants.GENERIC_SUCCESS_CODE);@b@			model.put("responseMsg", Constants.GENERIC_SUCCESS_MSG);@b@			model.put("data", JSON.toJSONString(dataResult, SerializerFeature.WriteNullStringAsEmpty));@b@		}catch (Exception e) {@b@			model.put("responseCode", Constants.GENERIC_ERR_UNDEFINED_CODE);@b@			model.put("responseMsg",  Constants.GENERIC_ERR_UNDEFINED_MSG);@b@			model.put("data", "");@b@			logger.error("postGenericData_error=" + e.getMessage(), e);@b@		}@b@		logger.info("postGenericData_result=" + model);@b@		return model;@b@	}@b@	@b@	private  Map<String,?>  toGenericJson(GenericAssistForm form){@b@		return (Map<String,?>)JSONObject.parseObject(form.getReqBody());@b@	}@b@	@b@	private  String  toGenericString(GenericAssistForm form){@b@		return form.getReqBody();@b@	}@b@	@b@	 @b@}

4.配置化xml模板

<?xml version="1.0" encoding="UTF-8"?>@b@<appscenes>@b@	<appscene  id="gs00001"  name="产品A获取列表接口"  desc="产品A"    serviceObj="com.xwood.service.impl.GenericAssistServiceImpl"   requestType="json"  responseType="json"  isMock="true"  >@b@		 	<requestBody>@b@				<![CDATA[@b@				{@b@						 "startTime":"2017-09-10",@b@						 "endTime":"2017-11-10",@b@						 "source":"",@b@						 "managerCode":"",@b@						 "status:"10",@b@						 "limit":"20",@b@						 "page":"1"@b@				} @b@				]]>@b@			</requestBody>@b@			<responseBody>@b@				<![CDATA[@b@				{@b@						 @b@						"productType":"产品A",@b@						"mobile":"1562365263",@b@						"name":"测试test",@b@						"realCityName":"上海",@b@						"globalId":"41048245656239564"@b@				} @b@				]]>@b@			</responseBody> @b@	</appscene>@b@</appscenes>