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

网站系统建设需要什么资质七牛做网站

网站系统建设需要什么资质,七牛做网站,西乡县门户网站,注册功能的网站怎么做目录 前言 一、又臭又长的if...else 二、消除if...else的锦囊妙计 1、使用注解 2、动态拼接名称 3、模板方法判断 4.策略工厂模式 5.责任链模式 6、其他的消除if...else的方法 1.根据不同的数字返回不同的字符串 2.集合中的判断 3.简单的判断 4.spring中的判断 原文…目录 前言 一、又臭又长的if...else 二、消除if...else的锦囊妙计 1、使用注解 2、动态拼接名称 3、模板方法判断 4.策略工厂模式 5.责任链模式 6、其他的消除if...else的方法 1.根据不同的数字返回不同的字符串 2.集合中的判断 3.简单的判断 4.spring中的判断 原文9条消除if...else的锦囊妙计助你写出更优雅的代码 前言 最近在做代码重构发现了很多代码的烂味道。其他的不多说今天主要说说那些又臭又长的if...else要如何重构。 在介绍更更优雅的编程之前让我们一起回顾一下不好的if...else代码 一、又臭又长的if...else 废话不多说先看看下面的代码。 public interface IPay { void pay(); } Service public class AliaPay implements IPay { Override public void pay() { System.out.println(发起支付宝支付); } } Service public class WeixinPay implements IPay { Override public void pay() { System.out.println(发起微信支付); } } Service public class JingDongPay implements IPay { Override public void pay() { System.out.println(发起京东支付); } } Service public class PayService { Autowired private AliaPay aliaPay; Autowired private WeixinPay weixinPay; Autowired private JingDongPay jingDongPay; public void toPay(String code) { if (alia.equals(code)) { aliaPay.pay(); } else if (weixin.equals(code)) { weixinPay.pay(); } else if (jingdong.equals(code)) { jingDongPay.pay(); } else { System.out.println(找不到支付方式); } } }PayService类的toPay方法主要是为了发起支付根据不同的code决定调用用不同的支付类比如aliaPay的pay方法进行支付。 这段代码有什么问题呢也许有些人就是这么干的。 试想一下如果支付方式越来越多比如又加了百度支付、美团支付、银联支付等等就需要改toPay方法的代码增加新的else...if判断判断多了就会导致逻辑越来越多 很明显这里违法了设计模式六大原则的开闭原则 和 单一职责原则。 ❝ 开闭原则对扩展开放对修改关闭。就是说增加新功能要尽量少改动已有代码。 ❞ ❝ 单一职责原则顾名思义要求逻辑尽量单一不要太复杂便于复用。 ❞ 那有什么办法可以解决这个问题呢 二、消除if...else的锦囊妙计 1、使用注解 代码中之所以要用code判断使用哪个支付类是因为code和支付类没有一个绑定关系如果绑定关系存在了就可以不用判断了。 我们先定义一个注解。 Retention(RetentionPolicy.RUNTIME) Target(ElementType.TYPE) public interface PayCode { String value(); String name(); }在所有的支付类上都加上该注解 PayCode(value alia, name 支付宝支付) Service public class AliaPay implements IPay { Override public void pay() { System.out.println(发起支付宝支付); } } PayCode(value weixin, name 微信支付) Service public class WeixinPay implements IPay { Override public void pay() { System.out.println(发起微信支付); } } PayCode(value jingdong, name 京东支付) Service public class JingDongPay implements IPay { Override public void pay() { System.out.println(发起京东支付); } }然后增加最关键的类 Service public class PayService2 implements ApplicationListenerContextRefreshedEvent { private static MapString, IPay payMap null; Override public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) { ApplicationContext applicationContext contextRefreshedEvent.getApplicationContext(); MapString, Object beansWithAnnotation applicationContext.getBeansWithAnnotation(PayCode.class); if (beansWithAnnotation ! null) { payMap new HashMap(); beansWithAnnotation.forEach((key, value) -{ String bizType value.getClass().getAnnotation(PayCode.class).value(); payMap.put(bizType, (IPay) value); }); } } public void pay(String code) { payMap.get(code).pay(); } }PayService2类实现了ApplicationListener接口这样在onApplicationEvent方法中就可以拿到ApplicationContext的实例。我们再获取打了PayCode注解的类放到一个map中map中的key就是PayCode注解中定义的value跟code参数一致value是支付类的实例。 这样每次就可以每次直接通过code获取支付类实例而不用if...else判断了。如果要加新的支付方法只需在支付类上面打上PayCode注解定义一个新的code即可。 注意这种方式的code可以没有业务含义可以是纯数字只有不重复就行。 2、动态拼接名称 该方法主要针对code是有业务含义的场景。 Service public class PayService3 implements ApplicationContextAware { private ApplicationContext applicationContext; private static final String SUFFIX Pay; Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext applicationContext; } public void toPay(String payCode) { ((IPay) applicationContext.getBean(getBeanName(payCode))).pay(); } public String getBeanName(String payCode) { return payCode SUFFIX; } }我们可以看到支付类bean的名称是由code和后缀拼接而成比如aliaPay、weixinPay和jingDongPay。这就要求支付类取名的时候要特别注意前面的一段要和code保持一致。调用的支付类的实例是直接从ApplicationContext实例中获取的默认情况下bean是单例的放在内存的一个map中所以不会有性能问题。 特别说明一下这种方法实现了ApplicationContextAware接口跟上面的ApplicationListener接口不一样是想告诉大家获取ApplicationContext实例的方法不只一种。 3、模板方法判断 当然除了上面介绍的两种方法之外spring的源码实现中也告诉我们另外一种思路解决if...else问题。 我们先一起看看spring AOP的部分源码看一下DefaultAdvisorAdapterRegistry的wrap方法 public Advisor wrap(Object adviceObject) throws UnknownAdviceTypeException { if (adviceObject instanceof Advisor) { return (Advisor) adviceObject; } if (!(adviceObject instanceof Advice)) { throw new UnknownAdviceTypeException(adviceObject); } Advice advice (Advice) adviceObject; if (advice instanceof MethodInterceptor) { return new DefaultPointcutAdvisor(advice); } for (AdvisorAdapter adapter : this.adapters) { if (adapter.supportsAdvice(advice)) { return new DefaultPointcutAdvisor(advice); } } throw new UnknownAdviceTypeException(advice); }重点看看supportAdvice方法有三个类实现了这个方法。我们随便抽一个类看看 class AfterReturningAdviceAdapter implements AdvisorAdapter, Serializable { Override public boolean supportsAdvice(Advice advice) { return (advice instanceof AfterReturningAdvice); } Override public MethodInterceptor getInterceptor(Advisor advisor) { AfterReturningAdvice advice (AfterReturningAdvice) advisor.getAdvice(); return new AfterReturningAdviceInterceptor(advice); } }该类的supportsAdvice方法非常简单只是判断了一下advice的类型是不是AfterReturningAdvice。 我们看到这里应该有所启发。 其实我们可以这样做定义一个接口或者抽象类里面有个support方法判断参数传的code是否自己可以处理如果可以处理则走支付逻辑。 public interface IPay { boolean support(String code); void pay(); } Service public class AliaPay implements IPay { Override public boolean support(String code) { return alia.equals(code); } Override public void pay() { System.out.println(发起支付宝支付); } } Service public class WeixinPay implements IPay { Override public boolean support(String code) { return weixin.equals(code); } Override public void pay() { System.out.println(发起微信支付); } } Service public class JingDongPay implements IPay { Override public boolean support(String code) { return jingdong.equals(code); } Override public void pay() { System.out.println(发起京东支付); } }每个支付类都有一个support方法判断传过来的code是否和自己定义的相等。 Service public class PayService4 implements ApplicationContextAware, InitializingBean { private ApplicationContext applicationContext; private ListIPay payList null; Override public void afterPropertiesSet() throws Exception { if (payList null) { payList new ArrayList(); MapString, IPay beansOfType applicationContext.getBeansOfType(IPay.class); beansOfType.forEach((key, value) - payList.add(value)); } } Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext applicationContext; } public void toPay(String code) { for (IPay iPay : payList) { if (iPay.support(code)) { iPay.pay(); } } } }这段代码中先把实现了IPay接口的支付类实例初始化到一个list集合中返回在调用支付接口时循环遍历这个list集合如果code跟自己定义的一样则调用当前的支付类实例的pay方法。 4.策略工厂模式 这种方式也是用于code是有业务含义的场景。 策略模式定义了一组算法把它们一个个封装起来, 并且使它们可相互替换。 工厂模式用于封装和管理对象的创建是一种创建型模式。 public interface IPay {void pay(); }Service public class AliaPay implements IPay {PostConstructpublic void init() {PayStrategyFactory.register(aliaPay, this);}Overridepublic void pay() {System.out.println(发起支付宝支付);}}Service public class WeixinPay implements IPay {PostConstructpublic void init() {PayStrategyFactory.register(weixinPay, this);}Overridepublic void pay() {System.out.println(发起微信支付);} }Service public class JingDongPay implements IPay {PostConstructpublic void init() {PayStrategyFactory.register(jingDongPay, this);}Overridepublic void pay() {System.out.println(发起京东支付);} }public class PayStrategyFactory {private static MapString, IPay PAY_REGISTERS new HashMap();public static void register(String code, IPay iPay) {if (null ! code !.equals(code)) {PAY_REGISTERS.put(code, iPay);}}public static IPay get(String code) {return PAY_REGISTERS.get(code);} }Service public class PayService3 {public void toPay(String code) {PayStrategyFactory.get(code).pay();} }这段代码的关键是PayStrategyFactory类它是一个策略工厂里面定义了一个全局的map在所有IPay的实现类中注册当前实例到map中然后在调用的地方通过PayStrategyFactory类根据code从map获取支付类实例即可。 5.责任链模式 这种方式在代码重构时用来消除if...else非常有效。 责任链模式将请求的处理对象像一条长链一般组合起来形成一条对象链。请求并不知道具体执行请求的对象是哪一个这样就实现了请求与处理对象之间的解耦。 常用的filter、spring aop就是使用了责任链模式这里我稍微改良了一下具体代码如下 public abstract class PayHandler {GetterSetterprotected PayHandler next;public abstract void pay(String pay);}Service public class AliaPayHandler extends PayHandler {Overridepublic void pay(String code) {if (alia.equals(code)) {System.out.println(发起支付宝支付);} else {getNext().pay(code);}}}Service public class WeixinPayHandler extends PayHandler {Overridepublic void pay(String code) {if (weixin.equals(code)) {System.out.println(发起微信支付);} else {getNext().pay(code);}} }Service public class JingDongPayHandler extends PayHandler {Overridepublic void pay(String code) {if (jingdong.equals(code)) {System.out.println(发起京东支付);} else {getNext().pay(code);}} }Service public class PayHandlerChain implements ApplicationContextAware, InitializingBean {private ApplicationContext applicationContext;private PayHandler header;public void handlePay(String code) {header.pay(code);}Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {this.applicationContext applicationContext;}Overridepublic void afterPropertiesSet() throws Exception {MapString, PayHandler beansOfTypeMap applicationContext.getBeansOfType(PayHandler.class);if (beansOfTypeMap null || beansOfTypeMap.size() 0) {return;}ListPayHandler handlers beansOfTypeMap.values().stream().collect(Collectors.toList());for (int i 0; i handlers.size(); i) {PayHandler payHandler handlers.get(i);if (i ! handlers.size() - 1) {payHandler.setNext(handlers.get(i 1));}}header handlers.get(0);} }这段代码的关键是每个PayHandler的子类都定义了下一个需要执行的PayHandler子类构成一个链式调用通过PayHandlerChain把这种链式结构组装起来。 6、其他的消除if...else的方法 当然实际项目开发中使用if...else判断的场景非常多上面只是其中几种场景。下面再列举一下其他常见的场景。 1.根据不同的数字返回不同的字符串 public String getMessage(int code) { if (code 1) { return 成功; } else if (code -1) { return 失败; } else if (code -2) { return 网络超时; } else if (code -3) { return 参数错误; } throw new RuntimeException(code错误); }其实这种判断没有必要用一个枚举就可以搞定。 public enum MessageEnum { SUCCESS(1, 成功), FAIL(-1, 失败), TIME_OUT(-2, 网络超时), PARAM_ERROR(-3, 参数错误); private int code; private String message; MessageEnum(int code, String message) { this.code code; this.message message; } public int getCode() { return this.code; } public String getMessage() { return this.message; } public static MessageEnum getMessageEnum(int code) { return Arrays.stream(MessageEnum.values()).filter(x - x.code code).findFirst().orElse(null); } }再把调用方法稍微调整一下 public String getMessage(int code) { MessageEnum messageEnum MessageEnum.getMessageEnum(code); return messageEnum.getMessage(); }完美。 2.集合中的判断 上面的枚举MessageEnum中的getMessageEnum方法如果不用java8的语法的话可能要这样写 public static MessageEnum getMessageEnum(int code) { for (MessageEnum messageEnum : MessageEnum.values()) { if (code messageEnum.code) { return messageEnum; } } return null; }对于集合中过滤数据或者查找方法java8有更简单的方法消除if...else判断。 public static MessageEnum getMessageEnum(int code) { return Arrays.stream(MessageEnum.values()).filter(x - x.code code).findFirst().orElse(null); }3.简单的判断 其实有些简单的if...else完全没有必要写可以用三目运算符代替比如这种情况 public String getMessage2(int code) { if(code 1) { return 成功; } return 失败; }改成三目运算符 public String getMessage2(int code) { return code 1 ? 成功 : 失败; }修改之后代码更简洁一些。 4.spring中的判断 对于参数的异常越早被发现越好在spring中提供了Assert用来帮助我们检测参数是否有效。 public void save(Integer codeString name) { if(code null) {throw Exception(code不能为空); } else {if(name null) {throw Exception(name不能为空); } else {System.out.println(doSave);}}} 如果参数非常多的话if...else语句会很长这时如果改成使用Assert类判断代码会简化很多 public String save2(Integer codeString name) { Assert.notNull(code,code不能为空); Assert.notNull(name,name不能为空); System.out.println(doSave);} 当然还有很多其他的场景可以优化if...else我再这里就不一一介绍了感兴趣的朋友可以给我留言一起探讨和研究一下
http://www.yingshimen.cn/news/77008/

相关文章:

  • 网站建设开发文档ui设计行业的现状和发展前景
  • 2019建一个什么网站最好滁州网站定制
  • 网站建设兼职挣多少钱聊城企业网站建设公司
  • 公司做网站推广有没有用免费在线观看电影电视剧网站
  • 网站建设是什么软件网页设计公司163企业邮箱
  • 有经验的常州手机网站定制家具网站源代码
  • 新乐企业网站建设wordpress批量倒入txt
  • 用vue框架做的pc端网站茂名网站建设公司哪个好
  • 北京网站优化步网站用 做有什么好处
  • wordpress仿站网做影视网站犯法吗
  • 酒店网站方案深圳网站建设 找猴王网络
  • 天津小型网站建设wordpress扁平化
  • 河南经贸一站式服务平台服务器搭建云电脑
  • 怎么开网站 第一步怎么做国外免费域名网站
  • 做商城网站的流程介绍wordpress运行环境要求
  • 网站规划中的三种常用类型深圳福田发现1例阳性
  • 全运会为什么建设网站新手怎么做企业网站
  • 教育系统网站建设北京画册设计制作公司
  • 杭州开发网站的公司哪家好好的 做网站的软件公司
  • 晋城网站制作公司怎么选wordpress 'wp-login.php'安全绕过漏洞
  • 胶州网站建设哪里有长春大学
  • 网站二级域名查询做网站是用什么软件
  • 明星网站怎么设计纯图片网站源码
  • 网站做百度推广有没有效果演示网站
  • 南湖网站建设公司动画设计好就业吗
  • 东莞网站建设收费网站开发href使用本地链接
  • 海米云网站建设邢台太行中学
  • 架设网站服务器怎样做网站的优化排名
  • 门户网站建设管理总则郑州小程序外包公司
  • 网站怎么做支付石家庄正定网站建设