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

网站下载app连接怎么做nginx网站开发

网站下载app连接怎么做,nginx网站开发,安徽省建设业协会网站,长沙seo男团原文https://mp.weixin.qq.com/s/K8yesHkTCerRhS0HfB0LeA 单例模式 单例模式是指一个类在一个进程中只有一个实例对象#xff08;但也不一定#xff0c;比如Spring中的Bean的单例是指在一个容器中是单例的#xff09; 单例模式创建分为饿汉式和懒汉式#xff0c;总共大概…原文https://mp.weixin.qq.com/s/K8yesHkTCerRhS0HfB0LeA 单例模式 单例模式是指一个类在一个进程中只有一个实例对象但也不一定比如Spring中的Bean的单例是指在一个容器中是单例的 单例模式创建分为饿汉式和懒汉式总共大概有8种写法。但是在开源项目中使用最多的主要有两种写法 1、静态常量方式属于饿汉式以静态变量的方式声明对象。 这种单例模式在Spring中使用的比较多 举个例子在Spring中对于Bean的名称生成有个类AnnotationBeanNameGenerator就是单例的。 2、双端检锁dcl 除了上面一种还有一种双重检查机制在开源项目中也使用的比较多而且在面试中也比较喜欢问。双重检查机制方式属于懒汉式代码如下 public class Singleton {private volatile static Singleton INSTANCE;private Singleton() {}public static Singleton getInstance() {if (INSTANCE null) {synchronized (Singleton.class) {if (INSTANCE null) {INSTANCE new Singleton();}}}return INSTANCE;}}之所以这种方式叫双重检查机制主要是在创建对象的时候进行了两次INSTANCE null的判断。 疑问讲解 这里解释一下双重检查机制的三个疑问 外层判断null的作用内层判断null的作用变量使用volatile关键字修饰的作用 外层判断null的作用其实就是为了减少进入同步代码块的次数提高效率。你想一下其实去了外层的判断其实是可以的但是每次获取对象都需要进入同步代码块实在是没有必要。 内层判断null的作用防止多次创建对象。假设AB同时走到同步代码块A先抢到锁进入代码创建了对象释放锁此时B进入代码块如果没有判断null那么就会直接再次创建对象那么就不是单例的了所以需要进行判断null防止重复创建单例对象。 volatile关键字的作用防止重排序。因为创建对象的过程不是原子大概会分为三个步骤 第一步分配内存空间给Singleton这个对象 第二步初始化对象 第三步将INSTANCE变量指向Singleton这个对象内存地址 假设没有使用volatile关键字发生了重排序第二步和第三步执行过程被调换了也就是先将INSTANCE变量指向Singleton这个对象内存地址再初始化对象。这样在发生并发的情况下另一个线程经过第一个if非空判断时发现已经为不为空就直接返回了这个对象但是此时这个对象还未初始化内部的属性可能都是空值一旦被使用的话就很有可能出现空指针这些问题。 双重检查机制在dubbo中的应用 在dubbo的spi机制中获取对象的时候有这样一段代码 其实在sentinelnacos中也是非常常见的 建造者模式 将一个复杂对象的构造与它的表示分离使同样的构建过程可以创建不同的表示这样的设计模式被称为建造者模式。它是将一个复杂的对象分解为多个简单的对象然后一步一步构建而成。 通俗的说建造者模式就是将一个复杂对象的构建过程优雅的拆分按需构建目标对象 为什么有这种需求 当一个对象参数属性非常多时很多属性时不必要的那么为了简单优雅创建对象一般会采用建造者模式 上面的意思看起来很绕其实在实际开发中其实建造者模式使用的还是比较多的比如有时在创建一个pojo对象时就可以使用建造者模式来创建 PersonDTO personDTO PersonDTO.builder().name(三友的java日记).age(18).sex(1).phone(188****9527).build();上面这段代码就是通过建造者模式构建了一个PersonDTO对象所以建造者模式又被称为Budiler模式。 这种模式在创建对象的时候看起来比较优雅当构造参数比较多的时候适合使用建造者模式。 接下来就来看看建造者模式在开源项目中是如何运用的 1、在Spring中的运用 我们都知道Spring在创建Bean之前会将每个Bean的声明封装成对应的一个BeanDefinition而BeanDefinition会封装很多属性所以Spring为了更加优雅地创建BeanDefinition就提供了BeanDefinitionBuilder这个建造者类。 工厂模式 工厂模式在开源项目中也使用的非常多具体的实现大概可以细分为三种 简单工厂模式工厂方法模式抽象工厂模式 工厂模式跟建造者模式的主要区别 建造者模式是将复杂对象通过简单优雅的方式显示的进行按需创建对象工厂模式是将复杂对象的创建过程封装调用者无需了解具体创建流程直接调用 1、简单工厂模式 简单工厂模式就跟名字一样的确很简单。比如说现在有个动物接口Animal具体的实现有猫Cat、狗Dog等等而每个具体的动物对象创建过程很复杂有各种各样地步骤此时就可以使用简单工厂来封装对象的创建过程调用者不需要关心对象是如何具体创建的。 通俗的讲简单工厂模式将复杂对象创建的过程封装调用者可以方便的通过工程生产对象不需要了几次创建的过程 public class SimpleAnimalFactory {public Animal createAnimal(String animalType) {if (cat.equals(animalType)) {Cat cat new Cat();//一系列复杂操作return cat;} else if (dog.equals(animalType)) {Dog dog new Dog();//一系列复杂操作return dog;} else {throw new RuntimeException(animalType animalType 无法创建对应对象);}}}当需要使用这些对象调用者就可以直接通过简单工厂创建就行。 SimpleAnimalFactory animalFactory new SimpleAnimalFactory(); Animal cat animalFactory.createAnimal(cat);需要注意的是一般来说如果每个动物对象的创建只需要简单地new一下就行了那么其实就无需使用工厂模式工厂模式适合对象创建过程复杂的场景。 2、工厂方法模式 上面说的简单工厂模式看起来没啥问题但是还是违反了七大设计原则的OCP原则也就是开闭原则。所谓的开闭原则就是对修改关闭对扩展开放。 什么叫对修改关闭就是尽可能不修改的意思。就拿上面的例子来说如果现在新增了一种动物兔子那么createAnimal方法就得修改增加一种类型的判断那么就此时就出现了修改代码的行为也就违反了对修改关闭的原则。 所以解决简单工厂模式违反开闭原则的问题就可以使用工厂方法模式来解决。 /*** 工厂接口*/ public interface AnimalFactory {Animal createAnimal(); }/*** 小猫实现*/ public class CatFactory implements AnimalFactory {Overridepublic Animal createAnimal() {Cat cat new Cat();//一系列复杂操作return cat;} }/*** 小狗实现*/ public class DogFactory implements AnimalFactory {Overridepublic Animal createAnimal() {Dog dog new Dog();//一系列复杂操作return dog;} }这种方式就是工厂方法模式。他将动物工厂提取成一个接口AnimalFactory具体每个动物都各自实现这个接口每种动物都有各自的创建工厂如果调用者需要创建动物就可以通过各自的工厂来实现。 AnimalFactory animalFactory new CatFactory(); Animal cat animalFactory.createAnimal();此时假设需要新增一个动物兔子那么只需要实现AnimalFactory接口就行对于原来的猫和狗的实现其实代码是不需要修改的遵守了对修改关闭的原则同时由于是对扩展开放实现接口就是扩展的意思那么也就符合扩展开放的原则。 3、抽象工厂模式 工厂方法模式其实是创建一个产品的工厂比如上面的例子中AnimalFactory其实只创建动物这一个产品。而抽象工厂模式特点就是创建一系列产品比如说不同的动物吃的东西是不一样的那么就可以加入食物这个产品通过抽象工厂模式来实现。 4、工厂模式在Mybatis的运用 在Mybatis中当需要调用Mapper接口执行sql的时候需要先获取到SqlSession通过SqlSession再获取到Mapper接口的动态代理对象而SqlSession的构造过程比较复杂所以就提供了SqlSessionFactory工厂类来封装SqlSession的创建过程。 对于使用者来说只需要通过SqlSessionFactory来获取到SqlSession而无需关心SqlSession是如何创建的。 5、工厂模式在Spring中的运用 BeanFactory就是Bean生成的工厂。一个Spring Bean在生成过程中会经历复杂的一个生命周期而这些生命周期对于使用者来说是无需关心的所以就可以将Bean创建过程的逻辑给封装起来提取出一个Bean的工厂。 策略模式 策略模式也比较常见就比如说在Spring源码中就有很多地方都使用到了策略模式。 通俗来讲策略模式就是减少代码中大量if-else的过程 假设现在有一个需求需要将消息推送到不同的平台。最简单的做法其实就是使用if else来做判断就行了。 public void notifyMessage(User user, String content, int notifyType) {if (notifyType 0) {//调用短信通知的api发送短信} else if (notifyType 1) {//调用app通知的api发送消息} }根据不同的平台类型进行判断调用对应的api发送消息。 虽然这样能实现功能但是跟上面的提到的简单工厂的问题是一样的同样违反了开闭原则。当需要增加一种平台类型比如邮件通知那么就得修改notifyMessage的方法再次进行else if的判断然后调用发送邮件的邮件发送消息。 此时就可以使用策略模式来优化了。 1、策略模式实现 定义一个接口 public interface MessageNotifier {/*** 是否支持改类型的通知的方式** param notifyType 0:短信 1:app* return*/boolean support(int notifyType);/*** 通知** param user* param content*/void notify(User user, String content);}邮件实现 Component public class SMSMessageNotifier implements MessageNotifier {Overridepublic boolean support(int notifyType) {return notifyType 0;}Overridepublic void notify(User user, String content) {//调用短信通知的api发送短信} }app通知实现 public class AppMessageNotifier implements MessageNotifier {Overridepublic boolean support(int notifyType) {return notifyType 1;}Overridepublic void notify(User user, String content) {//调用通知app通知的api} }最后notifyMessage的实现只需要要循环调用所有的MessageNotifier的support方法一旦support方法返回true说明当前MessageNotifier支持该类的消息发送最后再调用notify发送消息就可以了。 Resource private ListMessageNotifier messageNotifiers;public void notifyMessage(User user, String content, int notifyType) {for (MessageNotifier messageNotifier : messageNotifiers) {if (messageNotifier.support(notifyType)) {messageNotifier.notify(user, content);}} }那么如果现在需要支持通过邮件通知只需要实现MessageNotifier接口注入到Spring容器就行其余的代码根本不需要有任何变动。 到这其实可以更好的理解策略模式了。就拿上面举的例子来说短信通知app通知等其实都是发送消息一种策略而策略模式就是需要将这些策略进行封装抽取共性使这些策略之间相互替换。 2、策略模式在消息推送组件中使用 详情看message-push 3、策略模式在SpringMVC中的运用 比如说我们经常在写接口的时候会使用到了PathVariable、RequestParam、RequestBody等注解一旦我们使用了注解SpringMVC会处理注解从请求中获取到参数然后再调用接口传递过来而这个过程就使用到了策略模式。 对于这类参数的解析SpringMVC提供了一个策略接口HandlerMethodArgumentResolver 这个接口的定义就跟我们上面定义的差不多不同的参数处理只需要实现这个解决就行比如上面提到的几个注解都有对应的实现。 比如处理RequestParam注解的RequestParamMethodArgumentResolver的实现。 SpringMVC对于返回值的处理也是基于策略模式来实现的。 HandlerMethodReturnValueHandler接口定义跟上面都是同一种套路。 比如说常见的对于ResponseBody注解处理的实现RequestResponseBodyMethodProcessor。 模板方法模式 模板方法模式是指在父类中定义一个操作中的框架而操作步骤的具体实现交由子类做。其核心思想就是对于功能实现的顺序步骤是一定的但是具体每一步如何实现交由子类决定。 通俗来讲 模板方法模式就是将一个功能的实现步骤顺序进行规定但功能节点具体如何实现交由子类定义 比如说对于旅游来说一般有以下几个步骤 做攻略选择目的地收拾行李乘坐交通工具去目的地玩耍、拍照乘坐交通工具去返回 但是对于去哪收拾什么东西都乘坐什么交通工具都是由具体某个旅行来决定。 那么对于旅游这个过程使用模板方法模式翻译成代码如下 public abstract class Travel {public void travel() {//做攻略makePlan();//收拾行李packUp();//去目的地toDestination();//玩耍、拍照play();//乘坐交通工具去返回backHome();}protected abstract void makePlan();protected abstract void packUp();protected abstract void toDestination();protected abstract void play();protected abstract void backHome();}对于某次旅行来说只需要重写每个步骤该做的事就行比如说这次可以选择去杭州西湖下次可以去长城但是对于旅行过程来说是不变了对于调用者来说只需要调用暴露的travel方法就行。 可能这说的还是比较抽象我再举两个模板方法模式在源码中实现的例子。 1、模板方法模式在HashMap中的使用 HashMap我们都很熟悉可以通过put方法存元素并且在元素添加成功之后会调用一下afterNodeInsertion方法。 而afterNodeInsertion其实是在HashMap中是空实现什么事都没干。 这其实就是模板方法模式。HashMap定义了一个流程那就是当元素成功添加之后会调用afterNodeInsertion子类如果需要在元素添加之后做什么事那么重写afterNodeInsertion就行。 正巧JDK中的LinkedHashMap重写了这个方法。 2、模板方法模式在Spring中的运用 我们都知道在Spring中ApplicationContext在使用之前需要调用一下refresh方法而refresh方法就定义了整个容器刷新的执行流程代码。 在整个刷新过程有一个onRefresh方法 而onRefresh方法默认是没有做任何事并且在注释上有清楚两个单词Template method翻译过来就是模板方法的意思所以onRefresh就是一个模板方法 并且方法内部的注释也表明了这个方法是为了子类提供的。 在Web环境下子类会重写这个方法然后创建一个Web服务器。 3、模板方法模式在Mybatis中的使用 在Mybatis中是使用Executor执行Sql的。 而Mybatis一级缓存就在Executor的抽象实现中BaseExecutor实现的。如图所示红圈就是一级缓存 责任链模式 在责任链模式里很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递由该链上的某一个对象或者某几个对象决定处理此请求每个对象在整个处理过程中值扮演一个小小的角色。 通俗来讲责任链模式主要是将处理流程构成一条顺序执行链链上每个节点有各自不同的责任对请求进行处理 举个例子现在有个请假的审批流程根据请假的人的级别审批到的领导不同比如有有组长、主管、HR、分管经理等等。 先需要定义一个处理抽象类抽象类有个下一个处理对象的引用提供了抽象处理方法还有一个对下一个处理对象的调用方法。 责任链实现 定义一个抽象类保存下一个执行节点 public abstract class ApprovalHandler {/*** 责任链中的下一个处理对象*/protected ApprovalHandler next;/*** 设置下一个处理对象** param approvalHandler*/public void nextHandler(ApprovalHandler approvalHandler) {this.next approvalHandler;}/*** 处理** param approvalContext*/public abstract void approval(ApprovalContext approvalContext);/*** 调用下一个处理对象** param approvalContext*/protected void invokeNext(ApprovalContext approvalContext) {if (next ! null) {next.approval(approvalContext);}}}几种审批人的实现 //组长审批实现 public class GroupLeaderApprovalHandler extends ApprovalHandler {Overridepublic void approval(ApprovalContext approvalContext) {System.out.println(组长审批);//调用下一个处理对象进行处理invokeNext(approvalContext);} }//主管审批实现 public class DirectorApprovalHandler extends ApprovalHandler {Overridepublic void approval(ApprovalContext approvalContext) {System.out.println(主管审批);//调用下一个处理对象进行处理invokeNext(approvalContext);} }//hr审批实现 public class HrApprovalHandler extends ApprovalHandler {Overridepublic void approval(ApprovalContext approvalContext) {System.out.println(hr审批);//调用下一个处理对象进行处理invokeNext(approvalContext);} }有了这几个实现之后接下来就需要对对象进行组装组成一个链条比如在Spring中就可以这么玩。 Component public class ApprovalHandlerChain {Autowiredprivate GroupLeaderApprovalHandler groupLeaderApprovalHandler;Autowiredprivate DirectorApprovalHandler directorApprovalHandler;Autowiredprivate HrApprovalHandler hrApprovalHandler;public ApprovalHandler getChain() {//组长处理完下一个处理对象是主管groupLeaderApprovalHandler.nextHandler(directorApprovalHandler);//主管处理完下一个处理对象是hrdirectorApprovalHandler.nextHandler(hrApprovalHandler);//返回组长这样就从组长开始审批一条链就完成了return groupLeaderApprovalHandler;}}之后对于调用方而言只需要获取到链条开始处理就行。 一旦后面出现需要增加或者减少审批人只需要调整链条中的节点就行对于调用者来说是无感知的。 1、在SpringMVC中的使用 在SpringMVC中可以通过使用HandlerInterceptor对每个请求进行拦截。实际上就是责任链拦截器 2、在sentinel中使用 Sentinel是阿里开源的一个流量治理组件而Sentinel核心逻辑的执行其实就是一条责任链。 在Sentinel中有个核心抽象类AbstractLinkedProcessorSlot 这个组件内部也维护了下一个节点对象这个类扮演的角色跟例子中的ApprovalHandler类是一样的写法也比较相似。这个组件有很多实现 比如有比较核心的几个实现 DegradeSlot熔断降级的实现FlowSlot流量控制的实现StatisticSlot统计的实现比如统计请求成功的次数、异常次数为限流提供数据来源SystemSlot根据系统规则来进行流量控制 代理模式 代理模式分为动态代理和静态代理 代理模式也是开源项目中很常见的使用的一种设计模式这种模式可以在不改变原有代码的情况下增加功能。 举个例子比如现在有个PersonService接口和它的实现类PersonServiceImpl //接口 public interface PersonService {void savePerson(PersonDTO person);}//实现 public class PersonServiceImpl implements PersonService{Overridepublic void savePerson(PersonDTO person) {//保存人员信息} }这个类刚开始运行的好好的但是突然之前不知道咋回事了有报错需要追寻入参所以此时就可以这么写。 public class PersonServiceImpl implements PersonService {Overridepublic void savePerson(PersonDTO person) {log.info(savePerson接口入参:{}, JSON.toJSONString(person));//保存人员信息} }这么写就修改了代码万一以后不需要打印日志了呢岂不是又要修改代码不符和之前说的开闭原则那么怎么写呢可以这么玩。 public class PersonServiceProxy implements PersonService {private final PersonService personService new PersonServiceImpl();Overridepublic void savePerson(PersonDTO person) {log.info(savePerson接口入参:{}, JSON.toJSONString(person));personService.savePerson(person);} }1、代理模式在Mybtais中的使用 其实不光是一级缓存是通过Executor实现的二级缓存其实也是只不过不在BaseExecutor里面实现而是在CachingExecutor中实现的。 适配器模式 适配器模式使得原本由于接口不兼容而不能一起工作的哪些类可以一起工作将一个类的接口转换成客户希望的另一个接口。 通俗来讲将两个乃至多个不兼容的接口技术进行适配兼容 1、适配器模式在日志中的使用 在日常开发中日志是必不可少的可以帮助我们快速快速定位问题但是日志框架比较多比如Slf4j、Log4j等等一般同一系统都使用一种日志框架。 但是像Mybatis这种框架来说它本身在运行的过程中也需要产生日志但是Mybatis框架在设计的时候无法知道项目中具体使用的是什么日志框架所以只能适配各种日志框架项目中使用什么框架Mybatis就使用什么框架。 不同日志框架只要实现该接口即可 观察者模式 当对象间存在一对多关系时则使用观察者模式Observer Pattern。比如当一个对象被修改时则会自动通知依赖它的对象。 这是什么意思呢举个例子来说假设发生了火灾可能需要打119、救人那么就可以基于观察者模式来实现打119、救人的操作只需要观察火灾的发生一旦发生就触发相应的逻辑。 观察者的核心优点就是观察者和被观察者是解耦合的。就拿上面的例子来说火灾事件被观察者根本不关系有几个监听器观察者当以后需要有变动只需要扩展监听器就行对于事件的发布者和其它监听器是无需做任何改变的。 观察者模式实现起来比较复杂这里我举一下Spring事件的例子来说明一下 在spring中使用观察中模式 Spring事件的实现比较简单其实就是当Bean在生成完成之后会将所有的ApplicationListener接口实现监听器添加到ApplicationEventMulticaster中。 ApplicationEventMulticaster可以理解为一个调度中心的作用可以将事件通知给监听器触发监听器的执行。 retrieverCache中存储了事件类型和对应监听器的缓存。当发布事件的时候会通过事件的类型找到对应的监听器然后循环调用监听器。 发布订阅模式 通俗来讲发布订阅模式是将发布方生产方订阅方消费方进行分离接耦当有数据时通知消费方消费或主动去消费即可 生产中常见于webfluxreactor-stream模型nacos服务注册和发现队列 总结 常见设计模式 策略模式责任链模式代理模式建造者模式工厂模式适配器模式模版方法模式观察者模式
http://www.hkea.cn/news/14387004/

相关文章:

  • 湖南省建设工程网站哪个网站开发是按月付费的
  • 湘西 网站 建设 公司沧州网站建设选网龙
  • 装修设计网站免费美工设计网页培训
  • 全景旅游网站项目建设杭州微官网设计公司
  • 福州专业网站制作桂林做网站的公司
  • 网站服务器++免费网络网站租
  • 电商网站建设实验原理深圳做公司网站的公司
  • 承德建设网站公司注册城乡规划师报名入口
  • 网站后台有哪些西安网站建设交易
  • 花都有沒有网站建设的有没有什么做h5的网站
  • 首页优化排名seo领导屋
  • 网站做好怎么开始做推广国外网页设计分享网站
  • 在线教学的网站开发方案商场网站方案
  • 网站排名外包河北百度竞价优化
  • 网站建设培训哪个好h5网站建设代理
  • 东坑镇网站建设企业网站建设平台
  • jsp网站建设电子商务平台是什么
  • 请人做网站 我需要知道哪几点edu网站一般谁做的
  • 手机网站模板 html域名排名查询
  • 天门网站定制百度不收录网站文章
  • 深圳市网站设计公司商城网站建设浩森宇特
  • 重庆可作为推广的网站做a小视频免费观看网站
  • 有没有网站可以做地图网站内链的作用
  • 网站导购话术天猫网上购物商城购物
  • wordpress建站博客园门户网站英文版建设
  • 北京建设网站哪里好福州网络推广
  • 电子商务的网站建设过程wordpress百度经验
  • 个人注册网站怎么注册网站设计可以吗
  • 镇江网站建设优化网站改版 总结
  • 建设银行遵义分行网站网站源码官网