当前位置: 首页 > news >正文

网站建设公司yu郑州网站建设哪家公司好

网站建设公司yu,郑州网站建设哪家公司好,免费无代码开发平台本地部署,中国商标注册网查询网官网背景 在公司实际项目项目开发中#xff0c;有一个策略命中的开发需求。根据用户请求参数的不同来动态返回不同的业务数据。比如说有城市、客户年龄、请求时间3个策略维度#xff0c;不同的城市返回不同的地区的地标#xff0c;根据时间地标的背景色要发生变化等等的需求。当…背景 在公司实际项目项目开发中有一个策略命中的开发需求。根据用户请求参数的不同来动态返回不同的业务数据。比如说有城市、客户年龄、请求时间3个策略维度不同的城市返回不同的地区的地标根据时间地标的背景色要发生变化等等的需求。当然如果你直接使用一堆的嵌套if/else来硬代码编写这个业务的话确实也行。那难度再升级一下有20个策略维度的话这代码谁维护谁跑路。 所以我们要用合理规范的设计模式来实现该功能。 方案拟定 先来了解一下策略模式的概念 策略模式是一种设计模式它定义了一系列算法并将每个算法封装起来使他们可以相互替换。策略模式让算法独立于使用它的客户而独立变化。 在Java中可以使用如下步骤实现策略模式 定义策略接口该接口定义了所有算法的公共接口。实现策略接口为每种算法实现一个具体策略类。创建一个上下文类该类持有一个策略类的引用并且实现策略接口的方法。客户端代码中创建一个上下文对象并设置一个具体策略对象。 策略模式的意义在于 可以让算法和业务代码分离使得算法可以独立演化不会影响业务代码。可以在不修改业务代码的情况下更换算法提高了系统的灵活性。可以很容易地扩展新的算法而不需要修改原有的代码。可以减少代码的冗长使代码更加清晰易读。 简单来说的话就是创建一个接口该接口定义一个公共的方法实现类继承这个接口实现具体的功能。再创建一个service类对外提供服务时是通过这个类去动态传入实际处理逻辑的实现类去完成任务。 需求分析 结合实际业务场景来设计代码演练一下拿上面的需求来开发。案例中我们来实现城市、客户年龄、请求时间3个策略维度的命中功能判断服务。 功能刨析 需要一个定义了策略接口IStrategy接口中有执行策略判断方法executeStrategy();城市策略CityStrategy、客户年龄AgeStrategy、请求时间策略RquestTimeStrategy都实现IStrategy接口策略实现类StrategyService是对外实现策略命中的类 大局来看主要是这3部分细节我们在下面的章节来补充。 策略模式架构代码实现 准备工作 封装请求报文中的策略类 Data public class RequestStrategyInfo {private String cityInfo;private String ageInfo;private String requestTime;.... }1. 定义策略统一接口 public interface IStrategy {boolean executeStrategy(); }2. 各个策略实现IStrategy接口 城市策略 public class CityStrategy implements IStrategy {Overridepublic boolean executeStrategy() {} }年龄策略 public class AgeStrategy implements IStrategy {Overridepublic boolean executeStrategy() {} }请求时间策略 public class RquestTimeStrategy implements IStrategy {Overridepublic boolean executeStrategy() {} }3. StrategyService 对外提供策略匹配服务 StrategyService是最重要的在这个类里它要识别出当前判断的策略需要调用哪个具体的策略实例来执行这有好几种方法 策略工厂 import java.lang.reflect.InvocationTargetException;public class StrategyFactory {Overridepublic IStrategy createStrategy(String strategyType) {try {Class? strategyClass Class.forName(strategyType);return (IStrategy) strategyClass.getDeclaredConstructor().newInstance();} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {e.printStackTrace();}return null;} } public class StrategyService {private IStrategy strategy;private StrategyFactory strategyFactory;public boolean executeStrategy() {// 是否支持任意策略if (strategyInfo.getIsAll()) {return true;}// 获取从数据库详细的策略信息StrategyItem si strategyItemService.qryStrategyItem(itemId);String strategyType si.getStrategyType();// 根据strategyType获得对应的策略实例strategy strategyFactory.createStrategy(strategyType);// 执行策略匹配规则return strategy.executeStrategy();} }这种方法可以完成动态找到需要的实现类不过要求strategyType与类名有强关联关系必须要通过strategyType来创建实例也可通过定义枚举类来进一步解耦。 在上面的基础上定义枚举类StrategyEnum进行解耦 public enum StrategyType {CityStrategy(city, CityStrategy.class),AgeStrategy(age, AgeStrategy.class),RequestTimeStrategy(requestTime, RequestTimeStrategy.class);private String strategyType;private Class? extends IStrategy strategyClass;SortType(String sortType, Class? extends IStrategy strategyClass) {this.strategyType strategyType;this.strategyClass strategyClass;}public Class? extends IStrategy getStrategyClassBySortType(String strategyType) {StrategyType[] values StrategyType.values();return Arrays.stream(values).filter(it - it.strategyType.equals(strategyType)).findFirst().get().strategyClass;} }StrategyService需要稍微改造 public class StrategyService {private IStrategy strategy;private StrategyFactory strategyFactory;public boolean executeStrategy() {// 是否支持任意策略if (strategyInfo.getIsAll()) {return true;}// 获取从数据库详细的策略信息StrategyItem si strategyItemService.qryStrategyItem(itemId);String strategyType si.getStrategyType();// 根据strategyType获得对应的策略实例// strategy strategyFactory.createStrategy(strategyType);try {strategy StrategyType.getStrategyClassBySortType(strategyType).newInstance();} catch (InstantiationException | IllegalAccessException e) {e.printStackTrace();}// 执行策略匹配规则return strategy.executeStrategy();} }使用枚举可以解耦strategyType和策略类名的关系在枚举里面维护对应关系以后如果有新的策略直接添加枚举即可。 如果第二种方法不喜欢的话可以通过在StrategyService中定义一个Map集合维护strategyType与类名的关系 public class StrategyService {private MapString, Class? extends IStrategy strategyMap;public StrategyService() {strategyMap new HashMap();strategyMap.put(city, CityStrategy.class);strategyMap.put(age, AgeStrategy.class);strategyMap.put(requestTime, RequestTimeStrategy.class);}private IStrategy strategy;private StrategyFactory strategyFactory;public boolean executeStrategy() {// 是否支持任意策略if (strategyInfo.getIsAll()) {return true;}// 获取从数据库详细的策略信息StrategyItem si strategyItemService.qryStrategyItem(itemId);String strategyType si.getStrategyType();// 根据strategyType获得对应的策略实例// strategy strategyFactory.createStrategy(strategyType);/*try {strategy StrategyType.getStrategyClassBySortType(strategyType).newInstance();} catch (InstantiationException | IllegalAccessException e) {e.printStackTrace();}*/Class? extends IStrategy strategyClass strategyMap.get(strategyType);if (Class? extends IStrategy strategyClass strategyMap.get(strategyType); null) {throw new IllegalArgumentException(Unsupported strategy type: strategyType);}try {strategy strategyClass.getDeclaredConstructor().newInstance();} catch (InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {e.printStackTrace();}// 执行策略匹配规则return strategy.executeStrategy();} }用Map维护映射的话需要考虑策略的数量如果数量巨大的话对性能开销可不容小看的而且这种映射关系手动维护在类里面的做法可能不太优雅。 如果你觉得上述3种方法的硬代码、耦合度都达不到你公司的标准你可以选择程序在初始化时动态加载全部 IStrategy 接口下的实现类实例到ArrayList中的方式 在自动选择策略时会遍历一遍所有的策略是否支持当前操作策略类型。在选择使用这种方式前需要对IStrategy接口进行改造 public interface IStrategy {boolean executeStrategy();// 当前实现类是否支持boolean support(String strategyType); }实现类中对support()方法进行完善举个例子比如城市策略 public class CityStrategy implements IStrategy {Overridepublic boolean executeStrategy() {}Overridepublic boolean support(String strategyType) {return CityStrategy.equals(strategyType);} }其余策略方式一致可考虑将字符串定义成常量在IStrategy接口中这样会更规范一点 在StrategyService中使用时需要在初始化时先将IStrategy接口下的所有实现类放到ArrayList中提供给executeStrategy()方法使用 public class StrategyService implements InitializingBean {Autowiredprivate ApplicationContext appContext;private CollectionIStrategy strategys;private IStrategy strategy;private StrategyFactory strategyFactory;public boolean executeStrategy() {// 是否支持任意策略if (strategyInfo.getIsAll()) {return true;}// 获取从数据库详细的策略信息StrategyItem si strategyItemService.qryStrategyItem(itemId);String strategyType si.getStrategyType();// 根据strategyType获得对应的策略实例IStrategy strategy strategys.parallelStream().filter(it - it.support(strategyType)).findFirst().get();// 执行策略匹配规则return strategy.executeStrategy();}Overridepublic void afterPropertiesSet() throws Exception() {MapString, IStrategy strategyMap appContext.getBeansOfType(IStrategy.class);strategys strategyMap.values();} }这种方法不需要保证strategyType和策略类名的一一对应关系是解耦最为激进的一种方式。但是如果策略数量非常多遍历整个列表可能带来性能问题。 没有最好的方法只有最适合的方法。如果策略数量不多那么使用Map来存储映射关系是一个好的选择。如果策略数量非常多而且不需要频繁地添加和移除策略那么使用抽象的策略工厂是一个不错的选择。如果策略数量非常多进一步考虑一定的解耦性可添加枚举类解耦。如果对解耦的需求更重要于性能考虑可考虑使用ArrayList遍历的方法。 业务绑定策略设计与代码实现 上一章节只讲述了策略模式架构的设计与不同场景选择策略实例的方式这一章相当于上一章节的前传。要先有业务绑定了策略之后请求业务才有策略匹配。 【根据用户请求参数的不同来动态返回不同的业务数据。】这个业务的场景是有一个管理后台去设定某个业务绑定某些策略。当客户端带着请求参数来访问该业务时我们要对请求参数的某些字段的值与该业务选择的策略值进行一一比较若全都符合时方可返回该业务数据。 实体类设计 城市、年龄、时间等这些定义为策略类型城市中包含广州、上海、北京、深圳年龄有18、19、20这些定义为策略值。 策略类型实体类为StrategyType Data public class StrategyType {private Long id; // 主键private String type; // 类型private String name; // 类型名称private String oper; // 支持的操作 }策略值实体类为StrategyValue public class StrategyValue {private Long id; // 主键private Long typeId; // 策略类型idprivate String value; // 策略值 }单单有策略类型与其具体的策略值是不够的业务如何绑定策略我们假设操作上是这样的一个流程在创建好一个业务之后选择关联策略城市选择广州年龄选择等于大于、小于18点击保存。捋一下这两者的关系不难发现业务与策略值之间是多对多的关系。数据库层面还需要要建一个关联表。 关键字段有业务id、策略值id、操作类型 操作类型有等于、大于、小于、不等于 这个思路去做可以实现灵活度非常高的策略配置但缺点就是如果每个业务都需要配置多个策略尤其是一些策略几乎每个都要配置的那每次都要进行相同的多次操作确实很烦人。 在这里我给出的优化建议有两个第一个是保存历史操作记录业务添加策略时读取操作记录表的数据操作记录保存多少条这个看具体情况而定第二个是新增一个复合策略表可以组合一些常用的复合策略比如广州市18岁策略在选择策略时可以选择复合策略。 业务绑定策略并没有什么复杂操作代码主要与业务代码镶嵌不方便举例。查找出业务绑定的策略时封装成一个对象。 Data public class StrategyDetail {private Long id;private String type;private String oper;private String value; }策略匹配设计 这一章节讲述客户端传入策略与数据库中的策略匹配的设计。你可以理解成这一章节将重点讲述IStrategy接口中的executeStrategy()的实现。 有些同学可能就认为就这有什么难的我在每个策略实现类中都用业务策略.equals(请求参数)不就无敌了如果说只有【等于】这么一种操作类型确实可以这么做但我们有多种操作类型不能在每个策略实现类都写一遍重复性的代码。 封装一个策略匹配工具 public class StrategyUtil {// 匹配public static boolean matchStrategy(RequestStrategyInfo requestInfo, StrategyDetail detail) {Object reqVal null;try {reqVal getReqVal(requestInfo, detail.getType());}return computeOper(detail.getOper(), detail.getValue(), reqVal);}// 获取请求对象中的值private Object getReqVal(RequestStrategyInfo requestInfo, String type) {// 利用反射来获取请求对象中的值但要求策略类型的值要与RequestStrategyInfo类的属性同名Field f RequestStrategyInfo.class.getDeclareField(type);f.setAccessible(true);return f.get(requestInfo);}// 对比值private boolean computeOper(String oper, String value, Object val) {boolean result false;switch (oper) {case 0:result value.equals(val);break;case 1: // 小于result Double.parseDouble(val) Double.parseDouble(value);break;case 2: // 大于result Double.parseDouble(val) Double.parseDouble(value);break;case 3:result !value.equals(val);break;}return result;} }我们来举个城市策略的调用例子 public class CityStrategy implements IStrategy {Overridepublic boolean executeStrategy(RequestStrategyInfo requestInfo, StrategyDetail detail) {boolean result StrategyUtil.matchStrategy(requestInfo, detail);// 若有特殊处理操作可在此加上return result;} }几乎所有的策略实现类都是这样的一行代码如果有特殊操作可以补充在后面。 与前面的选择策略实现类相结合 public class StrategyService implements InitializingBean {Autowiredprivate ApplicationContext appContext;private CollectionIStrategy strategys;private IStrategy strategy;private StrategyFactory strategyFactory;// 由业务类自己提供所有的策略详情public boolean executeStrategy(ListstrategyDetails strategyDetails) {// 是否支持任意策略没有策略则说明支持所有字段if (strategyDetails.size() 0 || strategyDetails null) {return true;}ListBoolean matchList new ArrayList();for (StrategyDetail sd : strategyDetails) {boolean b strategys.parallelStream().filter(it - it.support(sd.type)).findFirst().get().executeStrategy(requestInfo, sd);matchList.add(b);}boolean b matchList.stream().filter(it - it false).findFirst().orElse(null);return b null ? true : false;}Overridepublic void afterPropertiesSet() throws Exception() {MapString, IStrategy strategyMap appContext.getBeansOfType(IStrategy.class);strategys strategyMap.values();} }在业务实现类的实现思路 public class XxxServiceImpl {Autowiredprivate StrategyService strategyServicepublic void xxx() {// 1. 处理业务......// 2. 根据业务id找出全部的关联策略详情ListStrategyDetail strategyDetails xxxx.getByServiceId(xx);boolean support strategyService.executeStrategy(strategyDetails);if (support) {// 支持则进行的操作} else {// 不支持的操作}......} }总结 基于策略模式设计的策略命中设计主要难点是策略模式的框架设计理念与策略值对比。
http://www.hkea.cn/news/14385868/

相关文章:

  • 网站免费的有没有影视传媒广告公司网站模板
  • 挂马网站现象网站架构价格
  • 网站建设常用软件jas2023网站seo
  • 儋州网站建设wordpress 4
  • 性做爰网站网页制作培训计划
  • 别人带做的网站关闭了权限咋办青岛网站建设哪家更好
  • 少儿英语做游戏网站推荐startup wordpress
  • 手机搭建网站企业机房建设公司
  • 福建南平网站建设杭州拱墅区网站建设
  • 有关于做茗茶的网站如何重视企业网站的建设
  • 国内优秀网站网页设计重庆承越网站建设公司
  • 酒店网站建设流程举报网站平台
  • 苏州外贸营销网站建设做的网站怎样更新
  • 如何建一个个人的网站企业融资顾问
  • 简述网站的制作步骤后台给网站做关键字
  • 牛天下网站建设免费网站重生九零做商女
  • 如何查询网站建设时间建网站需要注意什么
  • 阳江哪里做网站网站优化推广 视屏
  • 全国知名网百度seo网站优化 网络服务
  • 网页制作成品四川网络推广seo
  • 济南企业自助建站重庆李健做网站
  • 云南网站建设是什么网页标准化对网站开发维护所有者的好处
  • 百度商桥网站哪里的wordpress主题比较好
  • 北京企业建站程序wordpress更换IP
  • 上传图片的网站要怎么做易安卓开发app稳定吗
  • 乐清市网站建设旅游网站开发设计文档
  • 基础建设的网站有哪些内容做网站人员配置
  • 站长工具seo综合望野王绩拼音版
  • 网站用什么框架做中山精品网站建设流程
  • 廊坊网站搭建wordpress 幻灯片