策略模式+工厂方法 实现多分支操作(代替多个if else)或是Switch Case情况。
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
*
*
*/
@Service
public class CommonSyncService implements ICommonSyncService{
/** 日志打印 */
private static final Logger LOGGER = LoggerFactory.getLogger(CommonSyncService.class);
/** 对应base_bdm表的service处理层 */
@Autowired
private IBaseBdmService baseBdmService;
/** 对应base_dad表的service处理层 */
@Autowired
private IBaseDadService baseDadService;
/** 对应base_net表的service处理层 */
@Autowired
private IBaseNetService baseNetService;
/** 对应base_sys表的service处理层 */
@Autowired
private IBaseSysService baseSysService;
/** 对应product表的service处理层 */
@Autowired
private IProductService productService;
/** 对应wms表的service处理层 */
@Autowired
private IWmsService wmsService;
/** 对应user表的service处理层 */
@Autowired
private IUserSysEmployeeService userSysEmployeeService;
/** 对应route表的service处理层 */
@Autowired
private IRouteService routeService;
/**
* 数据同步-移动端
* 公共的服务层处理方法
* @param tableName 表名
* @param lastTime 最后修改时间
* @param startIndex 页数
* @param pageSize 当前页显示的条数
* @param cdstatus 查询条件comp_code(公司编码,默认值为all)
* @return
*/
public SyncServerResult commonCallSyncService(String tableName ,String lastTime,
int startIndex, int pageSize,String cdstatus){
SyncServerResult result = null;
//通过表名调用service层
switch (tableName) {
case Constants.TableConstants.BASE_NET_DEPT_BASE_INFO:
/**
* hanyg
* 部门网点信息base_net_dept_base_info
*/
result = baseNetService.getDeptBaseInfoSyncServerData(tableName,lastTime, startIndex, pageSize, cdstatus);
break;
case Constants.TableConstants.BASE_BDM_QC_TYPE:
/**
* hanyg
* 问题件异常类型base_bdm_qc_type
*/
result = baseBdmService.getQcTypeSyncServerData(tableName,lastTime, startIndex, pageSize, cdstatus);
break;
case Constants.TableConstants.BASE_SYS_COMPANY:
/**
* 账号base_sys_company
*/
result = baseSysService.getSyncSysCompanyServerData(tableName,lastTime, startIndex, pageSize, cdstatus);
break;
case Constants.TableConstants.BASE_NET_DISTRICT:
/**
* 行政区域base_net_district
*/
result = baseNetService.getSyncNetDistrictServerData(tableName,lastTime, startIndex, pageSize, cdstatus);
break;
case Constants.TableConstants.BASE_BDM_FORWARD_ZONE:
/**
* 查询 转寄地base_bdm_forward_zone表
*/
result = baseBdmService.getForwardZoneSyncData(tableName,lastTime, startIndex, pageSize, cdstatus);
break;
case Constants.TableConstants.BASE_DAD_DICTIONARY_VALUE:
/**
* 查询 数据字典base_dad_dictionary_value表
*/
result = baseDadService.getDictionarySyncData(tableName,lastTime, startIndex, pageSize, cdstatus);
break;
case Constants.TableConstants.BASE_BDM_PRODUCT_TYPE:
/**
* 查询 货物品类维护base_bdm_product_type表
*/
result = baseBdmService.getProductTypeSyncData(tableName,lastTime, startIndex, pageSize, cdstatus);
break;
case Constants.TableConstants.BASE_BDM_PRODUCT_TYPE_APPLY:
/**
* 查询 货物品类管理base_bdm_product_type_apply表
*/
result = baseBdmService.getProductTypeApplySyncData(tableName,lastTime, startIndex, pageSize, cdstatus);
break;
case Constants.TableConstants.BASE_BDM_PRINT_CONFIG:
/**
* 查询 (打印配置)base_bdm_print_config表数据
*/
result = baseBdmService.getPrintConfigSyncServerData(tableName ,lastTime, startIndex, pageSize, cdstatus);
break;
case Constants.TableConstants.BASE_BDM_WEIGHT_VOLUMN_RATIO:
/**
* 查询 (重量体积比率)base_bdm_weight_volumn_ratio表数据
*/
result = baseBdmService.getWeightVolumnRatioSyncServerData(tableName, lastTime, startIndex, pageSize, cdstatus);
break;
case Constants.TableConstants.BASE_DAD_DICTIONARY_CONFIG_VALUE:
/**
* 查询 (数据字典适用)base_dad_dictionary_config_value表数据
*/
result = baseBdmService.getDictConfValSyncServerData(tableName, lastTime, startIndex, pageSize, cdstatus);
break;
case Constants.TableConstants.BASE_EACH_COMPANY:
/**
* 查询 (经营属性配置)base_each_company表数据
*/
result = baseBdmService.getEachCompanySyncServerData(tableName, lastTime, startIndex, pageSize, cdstatus);
break;
case Constants.TableConstants.PRODUCT_PRO_MANAGE:
/**
* 查询(产品类型)product_pro_manage表数据
*/
result = productService.getProManageSyncServerData(tableName, lastTime, startIndex, pageSize, cdstatus);
break;
case Constants.TableConstants.PRODUCT_LINE_MAINTENANCE:
/**
* 查询(产品类型时效)product_line_maintenance表数据
*/
result = productService.getProLineSyncServerData(tableName, lastTime, startIndex, pageSize, cdstatus);
break;
case Constants.TableConstants.PRODUCT_SAL_SERVICE_FEE:
/**
* 查询(增值服务)product_sal_service_fee表数据
*/
result = productService.getProSalFeeSyncServerData(tableName, lastTime, startIndex, pageSize, cdstatus);
break;
case Constants.TableConstants.PRODUCT_SAL_SERVICE_ZONE:
/**
* 查询(增值服务适用网点)product_sal_service_zone表数据
*/
result = productService.getProSalZoneSyncServerData(tableName, lastTime, startIndex, pageSize, cdstatus);
break;
case Constants.TableConstants.PRODUCT_SAL_SPECIAL_GOODS:
/**
* 查询(货物品类价格)product_sal_special_goods表数据
*/
result = productService.getProSalGoodsSyncServerData(tableName, lastTime, startIndex, pageSize, cdstatus);
break;
case Constants.TableConstants.ROUTE_LINE_CODE:
/**
* 查询(线路编码)route_line_code表数据
*/
result = routeService.queryRouteLineCodeByparameter(tableName, lastTime, startIndex, pageSize, cdstatus);
break;
case Constants.TableConstants.ROUTE_LINE:
/**
* 查询 线路route_line表数据
*/
result = routeService.queryRouteLineByparameter(tableName, lastTime, startIndex, pageSize, cdstatus);
break;
case Constants.TableConstants.USER_SYS_EMPLOYEE:
/**
* 查询员工(user_sys_employee)表数据
*/
result = userSysEmployeeService.queryUserSysEmployeeByparameter(tableName, lastTime, startIndex, pageSize, cdstatus);
break;
case Constants.TableConstants.WMS_STORAGE:
/**
* 查询(库区)wms_storage表数据
*/
result = wmsService.queryWmsStorageByparameter(tableName, lastTime, startIndex, pageSize, cdstatus);
break;
case Constants.TableConstants.WMS_STORAGE_DETAIL:
/**
* 查询(库区详情)wms_storage_detail表数据
*/
result = wmsService.queryWmsStorageDetailByparameter(tableName, lastTime, startIndex, pageSize, cdstatus);
break;
default:
LOGGER.error("APP移动端传入的表名{}不存在!",tableName);
}
return result;
}
}
策略+工厂模式优化:
枚举类:
import org.apache.commons.lang3.StringUtils;
/**
* 策略枚举(增加新策略时需要添加数据)
* 保存具体策略类类型
*
* @author 000125
*
*/
public enum StrategyTypeEnum {
BASE_NET_DEPT_BASE_INFO("base_net_dept_base_info", "BaseNetDeptBaseInfoStrategy", "部门网点信息"),
BASE_BDM_QC_TYPE("base_bdm_qc_type", "BaseBdmQcTypeStrategy", "问题件异常类型"),
BASE_SYS_COMPANY("base_sys_company", "BaseSysCompanyStrategy", "账号"),
BASE_NET_DISTRICT("base_net_district", "BaseNetDistrictStrategy", "行政区域"),
BASE_BDM_FORWARD_ZONE("base_bdm_forward_zone", "BaseBdmForwardZoneStrategy", "转寄地"),
BASE_DAD_DICTIONARY_VALUE("base_dad_dictionary_value", "BaseDadDictionaryValueStrategy", "数据字典"),
BASE_DAD_DICTIONARY_CONFIG_VALUE("base_dad_dictionary_config_value", "BaseDadDictionaryConfigValueStrategy", "数据字典适用"),
BASE_BDM_PRODUCT_TYPE("base_bdm_product_type", "BaseBdmProductTypeStrategy","货物品类维护"),
BASE_BDM_PRODUCT_TYPE_APPLY("base_bdm_product_type_apply", "BaseBdmProductTypeApplyStrategy", "货物品类管理"),
BASE_BDM_PRINT_CONFIG("base_bdm_print_config", "BaseBdmPrintConfigStrategy", "打印配置"),
BASE_BDM_WEIGHT_VOLUMN_RATIO("base_bdm_weight_volumn_ratio", "BaseBdmWeightVolumnRatioStrategy", "重量体积比率"),
BASE_EACH_COMPANY("base_each_company", "BaseEachCompanyStrategy", "经营属性配置"),
PRODUCT_PRO_MANAGE("product_pro_manage", "ProductProManageStrategy", "产品类型"),
PRODUCT_LINE_MAINTENANCE("product_line_maintenance", "ProductLineMaintenanceStrategy", "产品类型时效"),
PRODUCT_SAL_SERVICE_FEE("product_sal_service_fee", "ProductSalServiceFeeStrategy", "增值服务表"),
PRODUCT_SAL_SERVICE_ZONE("product_sal_service_zone", "ProductSalServiceZoneStrategy", "增值服务适用网点"),
PRODUCT_SAL_SPECIAL_GOODS("product_sal_special_good", "ProductSalSpecialGoodStrategy", "货物品类价格"),
ROUTE_LINE_CODE("route_line_code", "RoutLineCodeStrategy", "线路编码"),
ROUTE_LINE("route_line", "RouteLineStrategy", "线路"),
USER_SYS_EMPLOYEE("user_sys_employee", "UserSysEmployeeStrategy", "员工表"),
WMS_STORAGE("wms_storage", "WmsStorageDetailStrategy", "库区"),
WMS_STORAGE_DETAIL("wms_storage_detail", "WmsStorageStrategy", "库区详情"),
NOT_EXITS_ENUM("", "", "");
/**
* 编码,此处为同步的表名
*/
private String code;
/**
* 具体的策略实现类的名称,类名
*/
private String value;
/**
* 描述
*/
private String description;
private StrategyTypeEnum(String code, String value, String description) {
this.code = code;
this.value = value;
this.description = description;
}
public String getCode(){
return this.code;
}
public String getValue(){
return this.value;
}
public String getDescription(){
return this.description;
}
public static StrategyTypeEnum getByCode(String code) {
if (StringUtils.isBlank(code)) {
return StrategyTypeEnum.NOT_EXITS_ENUM;
}
for(StrategyTypeEnum type : StrategyTypeEnum.values()) {
if(type.getCode().equals(code)) {
return type;
}
}
return null;
}
public static StrategyTypeEnum getByValue(String value) {
if (StringUtils.isBlank(value)) {
return StrategyTypeEnum.NOT_EXITS_ENUM;
}
for(StrategyTypeEnum type : StrategyTypeEnum.values()) {
if(type.getValue().equals(value)) {
return type;
}
}
return null;
}
}
策略接口:
/**
* 策略模式
* 解决数据同步时需要提供多个类似重复的对外接口,
* 通过策略模式+工厂模式基本上可以解决多个判断分支情况
*
*
* @author 000125
*
*/
public interface SyncStrategy {
/**
* 策略执行方法,即需要处理的每个业务单元逻辑
*
* @param tableName - 需同步数据的表名
* @param lastTime - 增量同步时,上一次同步时间
* @param startIndex - 页数
* @param pageSize - 当前页显示的条数
* @param cdstatus - 查询条件comp_code(公司编码,默认值为all)
* @return
*/
public Object doOperate(String tableName, String lastTime, int startIndex, int pageSize, String cdstatus);
}
策略具体实现类:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* 实现策略接口中的方法,实现具体的策略方案(业务逻辑)
*
* @author 000125
*
*/
public class BaseBdmForwardZoneStrategy implements SyncStrategy {
/** 日志打印 */
private static final Logger LOGGER = LoggerFactory.getLogger(BaseBdmForwardZoneStrategy.class);
/**
* 查询 转寄地base_bdm_forward_zone表
*/
@Override
public Object doOperate(String tableName, String lastTime, int startIndex, int pageSize, String cdstatus) {
// TODO 业务逻辑 此处较简单只需要调用一下具体业务方法
IBaseBdmService baseBdmService = SpringContextUtil.getBean("baseBdmServiceImpl", BaseBdmServiceImpl.class);
if (baseBdmService == null){
LOGGER.error("获取Spring Bean对象失败!");
return null;
}
return baseBdmService.getForwardZoneSyncData(tableName, lastTime, startIndex, pageSize, cdstatus);
}
}
工厂类:
import org.apache.commons.lang3.StringUtils;
/**
* 生成具体策略工厂方法
*
* @author 000125
*
*/
public class StrategyFactory {
private StrategyFactory() {
}
public static SyncStrategy getStrategy(String code){
String clazzPrefix = "com.appsync.core.gof.strategy.impl.";
String clazzName = StrategyTypeEnum.getByCode(code).getValue();
SyncStrategy strategy = null;
if (StringUtils.isNotBlank(clazzName)) {
try {
//通过反射获取策略对象
strategy = (SyncStrategy) Class.forName(clazzPrefix + clazzName).newInstance();
} catch (Exception e) {
e.printStackTrace();
System.out.println("生成策略出错");
}
}
return strategy;
}
}
客户端类(单元测试用例):
public class BaseTest extends SpringTestCase{
@Test
public void queryPrintConfigSql(){
String tableName="base_bdm_forward_zone",
lastTime="2018-01-10 00:00:00",
cdstatus="all";
int startIndex=1; int pageSize=10;
try {
HystrixRequestContext.initializeContext();
//策略模式
SyncServerResult result = SyncStrategyFacade.sync(tableName, lastTime, startIndex, pageSize, cdstatus);
String jsonResult = JSONObject.toJSONString(result);
System.out.println("jsonResult="+jsonResult);
} catch (Exception e) {
e.printStackTrace();
}
}
}
上面代码可以看出,策略模式把具体的算法封装到了具体策略角色内部,增强了可扩展性,隐蔽了实现细节;它替代继承来实现,避免了if- else这种不易维护的条件语句。当然我们也可以看到,策略模式由于独立策略实现,使得系统内增加了很多策略类;对客户端来说必须知道兜友哪些具体策略, 而且需要知道选择具体策略的条件