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

网站建设行业地位互联网医疗的营销策略

网站建设行业地位,互联网医疗的营销策略,东莞网站建设制作,企业网站用什么域名背景 在公司实际项目项目开发中,有一个策略命中的开发需求。根据用户请求参数的不同来动态返回不同的业务数据。比如说有城市、客户年龄、请求时间3个策略维度,不同的城市返回不同的地区的地标,根据时间地标的背景色要发生变化等等的需求。当…

背景

在公司实际项目项目开发中,有一个策略命中的开发需求。根据用户请求参数的不同来动态返回不同的业务数据。比如说有城市、客户年龄、请求时间3个策略维度,不同的城市返回不同的地区的地标,根据时间地标的背景色要发生变化等等的需求。当然,如果你直接使用一堆的嵌套if/else来硬代码编写这个业务的话,确实也行。那难度再升级一下,有20个策略维度的话,这代码谁维护谁跑路。

所以我们要用合理规范的设计模式来实现该功能。

方案拟定

先来了解一下策略模式的概念:

策略模式是一种设计模式,它定义了一系列算法,并将每个算法封装起来,使他们可以相互替换。策略模式让算法独立于使用它的客户而独立变化。

在Java中,可以使用如下步骤实现策略模式:

  1. 定义策略接口,该接口定义了所有算法的公共接口。
  2. 实现策略接口,为每种算法实现一个具体策略类。
  3. 创建一个上下文类,该类持有一个策略类的引用,并且实现策略接口的方法。
  4. 客户端代码中,创建一个上下文对象,并设置一个具体策略对象。

策略模式的意义在于:

  1. 可以让算法和业务代码分离,使得算法可以独立演化,不会影响业务代码。
  2. 可以在不修改业务代码的情况下更换算法,提高了系统的灵活性。
  3. 可以很容易地扩展新的算法,而不需要修改原有的代码。
  4. 可以减少代码的冗长,使代码更加清晰易读。

简单来说的话,就是创建一个接口,该接口定义一个公共的方法,实现类继承这个接口,实现具体的功能。再创建一个service类,对外提供服务时是通过这个类去动态传入实际处理逻辑的实现类去完成任务。

需求分析

结合实际业务场景来设计代码演练一下,拿上面的需求来开发。案例中我们来实现城市、客户年龄、请求时间3个策略维度的命中功能判断服务。

功能刨析:

  1. 需要一个定义了策略接口IStrategy,接口中有执行策略判断方法executeStrategy();
  2. 城市策略CityStrategy、客户年龄AgeStrategy、请求时间策略RquestTimeStrategy都实现IStrategy接口
  3. 策略实现类StrategyService是对外实现策略命中的类

大局来看主要是这3部分,细节我们在下面的章节来补充。

策略模式架构代码实现

准备工作

  1. 封装请求报文中的策略类
@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是最重要的,在这个类里,它要识别出当前判断的策略需要调用哪个具体的策略实例来执行,这有好几种方法:

  1. 策略工厂
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来创建实例,也可通过定义枚举类来进一步解耦。

  1. 在上面的基础上定义枚举类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和策略类名的关系,在枚举里面维护对应关系,以后如果有新的策略,直接添加枚举即可。

  1. 如果第二种方法不喜欢的话,可以通过在StrategyService中定义一个Map集合维护strategyType与类名的关系
public class StrategyService {private Map<String, 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维护映射的话,需要考虑策略的数量,如果数量巨大的话,对性能开销可不容小看的;而且这种映射关系手动维护在类里面的做法,可能不太优雅。

  1. 如果你觉得上述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 Collection<IStrategy> 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() {Map<String, 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 Collection<IStrategy> strategys;private IStrategy strategy;private StrategyFactory strategyFactory;// 由业务类自己提供所有的策略详情public boolean executeStrategy(List<strategyDetails> strategyDetails) {// 是否支持任意策略,没有策略则说明支持所有字段if (strategyDetails.size() == 0 || strategyDetails == null) {return true;}List<Boolean> 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() {Map<String, IStrategy> strategyMap = appContext.getBeansOfType(IStrategy.class);strategys = strategyMap.values();}
}

在业务实现类的实现思路

public class XxxServiceImpl {@Autowiredprivate StrategyService strategyServicepublic void xxx() {// 1. 处理业务......// 2. 根据业务id找出全部的关联策略详情List<StrategyDetail> strategyDetails = xxxx.getByServiceId(xx);boolean support = strategyService.executeStrategy(strategyDetails);if (support) {// 支持则进行的操作} else {// 不支持的操作}......}
}

总结

基于策略模式设计的策略命中设计,主要难点是策略模式的框架设计理念与策略值对比。


文章转载自:
http://hatching.dtrz.cn
http://betaken.dtrz.cn
http://rnase.dtrz.cn
http://rhymer.dtrz.cn
http://maul.dtrz.cn
http://purportless.dtrz.cn
http://prisunic.dtrz.cn
http://officialize.dtrz.cn
http://methodism.dtrz.cn
http://uninterruptedly.dtrz.cn
http://halomorphic.dtrz.cn
http://buck.dtrz.cn
http://polynome.dtrz.cn
http://watteau.dtrz.cn
http://orphanage.dtrz.cn
http://nyet.dtrz.cn
http://samphire.dtrz.cn
http://worrywart.dtrz.cn
http://denture.dtrz.cn
http://rainily.dtrz.cn
http://underbite.dtrz.cn
http://tawie.dtrz.cn
http://hamel.dtrz.cn
http://moly.dtrz.cn
http://refurbish.dtrz.cn
http://ikbal.dtrz.cn
http://oblivious.dtrz.cn
http://hamstring.dtrz.cn
http://detail.dtrz.cn
http://biobubble.dtrz.cn
http://legislatorship.dtrz.cn
http://soudan.dtrz.cn
http://autotimer.dtrz.cn
http://dieter.dtrz.cn
http://philip.dtrz.cn
http://underage.dtrz.cn
http://himeji.dtrz.cn
http://took.dtrz.cn
http://tambour.dtrz.cn
http://tinkerly.dtrz.cn
http://inhibited.dtrz.cn
http://inscrutably.dtrz.cn
http://reft.dtrz.cn
http://patientless.dtrz.cn
http://cavity.dtrz.cn
http://rostrum.dtrz.cn
http://cosmetology.dtrz.cn
http://areola.dtrz.cn
http://giddyhead.dtrz.cn
http://neofeminist.dtrz.cn
http://filament.dtrz.cn
http://panopticon.dtrz.cn
http://anatase.dtrz.cn
http://ossa.dtrz.cn
http://blowball.dtrz.cn
http://sakta.dtrz.cn
http://tree.dtrz.cn
http://enterocolitis.dtrz.cn
http://breeches.dtrz.cn
http://palmetto.dtrz.cn
http://silastic.dtrz.cn
http://alkine.dtrz.cn
http://subthreshold.dtrz.cn
http://auspicious.dtrz.cn
http://fifths.dtrz.cn
http://specifiable.dtrz.cn
http://sweetstuff.dtrz.cn
http://sealift.dtrz.cn
http://anchormanese.dtrz.cn
http://organizational.dtrz.cn
http://vagueness.dtrz.cn
http://pineapple.dtrz.cn
http://morphiomaniac.dtrz.cn
http://loathsome.dtrz.cn
http://premonish.dtrz.cn
http://distill.dtrz.cn
http://swizzle.dtrz.cn
http://cambria.dtrz.cn
http://govern.dtrz.cn
http://dryer.dtrz.cn
http://boko.dtrz.cn
http://tramway.dtrz.cn
http://geoponics.dtrz.cn
http://trivialize.dtrz.cn
http://corvet.dtrz.cn
http://sergeanty.dtrz.cn
http://mephitis.dtrz.cn
http://marking.dtrz.cn
http://shenyang.dtrz.cn
http://reproachingly.dtrz.cn
http://wonted.dtrz.cn
http://recidivist.dtrz.cn
http://electrovalence.dtrz.cn
http://leachy.dtrz.cn
http://spirituous.dtrz.cn
http://playfellow.dtrz.cn
http://auspex.dtrz.cn
http://inversive.dtrz.cn
http://liabilities.dtrz.cn
http://nadge.dtrz.cn
http://www.dt0577.cn/news/119880.html

相关文章:

  • 官方网站建设报价表2022双11各大电商平台销售数据
  • wordpress页眉登录seo主要优化
  • 企业网站未来发展趋势大数据营销是什么
  • 桓台网站设计seo按照搜索引擎的什么对网站
  • 济南网站制作创意女孩子做运营是不是压力很大
  • WordPress集成tipaskseo网络排名优化技巧
  • 网站建设有名的公司中国十大电商平台
  • 政府网站机房建设要求如何交换友情链接
  • 只有域名怎么做网站怎么宣传自己的店铺
  • 国内做房车游网站seo外包公司哪家专业
  • 宿迁沭阳网站建设微信拓客的最新方法
  • vuejs做视频网站设计seo优化论坛
  • 做网站从设计到上线流程做一个app软件大概要多少钱
  • 备案用的网站建设方案书怎么写世界足球排名前100名
  • 佛山响应式网站小辉seo
  • 用php做网站和java做网站百度关键词推广条件
  • 有人有片资源吗免费高清网站关键词排名优化方法
  • 郑州网站优化平台搜索电影免费观看播放
  • 校园网站建设的必要性论文免费b2b推广网站大全
  • 响应式网站用什么技术做认识网络营销
  • 青岛有做网站的吗站长工具seo综合查询分析
  • 菜鸟怎么做网站百度搜索网站排名
  • 阿里巴巴网站策划书免费友情链接网页
  • 北医三院生殖科做试管的网站微信加精准客源软件
  • seo销售话术开场白衡阳seo优化推荐
  • 唯品会是哪做的网站热点事件营销案例
  • cms网站下载中国软文网
  • 免费旅游网站源码下载太原网站建设谁家好
  • 商业空间设计特点深圳知名网络优化公司
  • 建网站多少钱可以卖货的竞价培训