Java 设计模式——工厂模式
一、什么是工厂模式
工厂模式(Factory Pattern)是 Java 中最常用的设计模式之一,它提供了一种创建对象的最佳方式。
在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
优点:
一个调用者想创建一个对象,只要知道其名称就可以了。
扩展性高,如果想增加一个产品,只要扩展一个工厂类就可以。
屏蔽产品的具体实现,调用者只关心产品的接口。屏蔽产品的具体实现,调用者只关心产品的接口。
缺点:
每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加了系统具体类的依赖。
工厂模式分为三种:简单工厂模式、工厂方法模式和抽象工厂模式。
这里以制造coffee的例子开始工厂模式设计之旅。我们知道coffee只是一种泛举,在点购咖啡时需要指定具体的咖啡种类:美式咖啡、卡布奇诺、拿铁等等。
12345678910111213141516171819202122232425abstract class Coffee { public ab ...
Java 设计模式——单例模式
一、单例模式的介绍
1.1 什么是单例模式
单例模式指的是一个类只会有一个实例,即一个类只有一个对象实例。它的特点有:
单例类只能有一个实例
单例类必须自己创建自己的唯一实例
单例类必须给所有其他对象提供这一实例
1.2 单例模式的应用场景
(1)一个系统中可以存在多个打印任务,但是只能有一个正在工作的任务;售票时,一共有100张票,可有有多个窗口同时售票,但需要保证不要超售(这里的票数余量就是单例,售票涉及到多线程)。
(2)在前端创建工具箱窗口,工具箱要么不出现,出现也只出现一个。
遇到问题:每次点击菜单都会重复创建“工具箱”窗口。
解决方案:使用 if 语句,在每次创建对象的时候首先进行判断是否为 null ,如果为 null 再创建对象。
(3)如果在 5 个地方需要实例出工具箱窗体。
遇到问题:这个小 bug 需要改动 5 个地方,并且代码重复,代码利用率低
解决方案:利用单例模式,保证一个类只有一个实例,并提供一个访问它的全局访问点。
二、传统单例模式的实现
传统的单例模式实现可以分为懒汉式和饿汉式:
懒汉式单例模式:在类加载时不初始化。
饿 ...
理解 HTTP、HTTPS 协议
一、主要特点
简单快速:客户向服务器请求服务时,只需传送请求方法和路径。请求方法常用的有GET、HEAD、POST。每种方法规定了客户与服务器联系的类型不同。由于HTTP协议简单,使得HTTP服务器的程序规模小,因而通信速度很快。
灵活:HTTP允许传输任意类型的数据对象。正在传输的类型由Content-Type加以标记。
无连接:无连接的含义是限制每次连接只处理一个请求。服务器处理完客户的请求,并收到客户的应答后,即断开连接。采用这种方式可以节省传输时间。
无状态:HTTP协议是无状态协议。无状态是指协议对于事务处理没有记忆能力。缺少状态意味着如果后续处理需要前面的信息,则它必须重传,这样可能导致每次连接传送的数据量增大。另一方面,在服务器不需要先前信息时它的应答就较快。
二、URL、URI、URN区别
(1)URI,是uniform resource identifier,统一资源标识符,用来唯一的标识一个资源。
Web上可用的每种资源如HTML文档、图像、视频片段、程序等都是一个来URI来定位的。URI一般由三部组成:
访问资源的命名机制
存放资源 ...
字符串的模式匹配(KMP)算法
一、背景
给定一个主串(以 S 代替)和模式串(以 P 代替),要求找出 P 在 S 中出现的位置,此即串的模式匹配问题。
Knuth-Morris-Pratt 算法(简称 KMP)是解决这一问题的常用算法之一,这个算法是由高德纳(Donald Ervin Knuth)和沃恩·普拉特在1974年构思,同年詹姆斯·H·莫里斯也独立地设计出该算法,最终三人于1977年联合发表。
在继续下面的内容之前,有必要在这里介绍下两个概念:真前缀 和 真后缀。
由上图所得, "真前缀"指除了自身以外,一个字符串的全部头部组合;"真后缀"指除了自身以外,一个字符串的全部尾部组合。
二、朴素字符串匹配算法
初遇串的模式匹配问题,我们脑海中的第一反应,就是朴素字符串匹配(即所谓的暴力匹配),代码如下:
123456789101112131415161718192021private static int simple(char[] S, char[] P) { // i为完整串S下标,j为模式串P下标 int i = 0, j = 0; ...
全面了解 Nginx 到底能做什么
1. 前言
本文只针对 Nginx 在不加载第三方模块的情况能处理哪些事情,由于第三方模块太多所以也介绍不完,当然本文本身也可能介绍的不完整,毕竟只是我个人使用过和了解到过的。
2. Nginx能做什么
反向代理
负载均衡
HTTP 服务器(包含动静分离)
正向代理
以上就是我了解到的 Nginx 在不依赖第三方模块能处理的事情,下面详细说明每种功能怎么做。
3. 反向代理
反向代理应该是 Nginx 做的最多的一件事了,什么是反向代理呢,以下是百度百科的说法:反向代理(Reverse Proxy)方式是指以代理服务器来接受 internet 上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给 internet 上请求连接的客户端,此时代理服务器对外就表现为一个反向代理服务器。
简单来说就是真实的服务器不能直接被外部网络访问,所以需要一台代理服务器,而代理服务器能被外部网络访问的同时又跟真实服务器在同一个网络环境,当然也可能是同一台服务器,端口不同而已。下面贴上一段简单的实现反向代理的代码:
12345678910server { ...
波兰表达式与逆波兰表达式
常见的算术表达式,称为中缀表达式,例如:
15 + ( 6 – 4 / 2 ) * 3
波兰表达式
波兰表达式也称为前缀表达式,以上面的例子为例,其波兰表达式为:
1+ 5 * - 6 / 4 2 3
中缀表达式转换前缀表达式的操作过程为:
(1)首先设定一个操作符栈,自右向左顺序扫描整个中缀表达式:
如果是操作数,则直接归入前缀表达式;
如果是括号:如果是右括号,则直接将其入栈;如果是左括号,则将栈中的操作符依次弹栈,归入前缀表达式,直至遇到右括号,将右括号弹栈,处理结束;
如果是其他操作符,则检测栈顶操作符的优先级与当前操作符的优先级关系,如果栈顶操作符优先级大于当前操作符的优先级,则弹栈,并归入前缀表达式,直至栈顶操作符优先级小于等于当前操作符优先级,这时将当前操作符压栈。
(2)当扫描完毕整个中缀表达式后,检测操作符栈是否为空,如果不为空,则依次将栈中操作符弹栈,归入前缀表达式。
(3)最后,将前缀表达式翻转,得到中缀表达式对应的前缀表达式。
逆波兰表达式
逆波兰表达式也称为后缀表达式,以上面的例子为例,其逆波兰表达式为:
15 6 4 2 / - 3 * ...
IDEA 下 SpringBoot 实现热部署
Step1: 按照下图所示,勾选Build project automatically:
Step2: 快捷键 Ctrl + shif + A,搜索Registry,选择第一个,如下图所示:
勾选下图中compiler.automake.allow.when.app.running,然后点击关闭。
Step3: 重启IDEA
Step4: 在项目中引入spring-boot-devtools依赖,即可:
123456<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> <scope>true</scope></dependency>
IDEA 配置注释模板
一、类注释
打开 IDEA 的 Settings,点击 Editor-->File and Code Templates,点击右边 File 选项卡下面的 Class,在其中添加图中红框内的内容:
1234/** * @author jitwxs * @date ${YEAR}年${MONTH}月${DAY}日 ${TIME} */
在我提供的示例模板中,说明了作者和时间,IDEA 支持的所有的模板参数在下方的 Description 中被列出来。
保存后,当你创建一个新的类的时候就会自动添加类注释。如果你想对接口也生效,同时配置上图中的 Interface 项即可。
二、方法注释
不同于目前网络上互相复制粘贴的方法注释教程,本文将实现以下功能:
根据形参数目自动生成 @param 注解
根据方法是否有返回值智能生成 @Return 注解
相较于类模板,为方法添加注释模板就较为复杂,首先在 Settings 中点击 Editor-->Live Templates。
点击最右边的 +,首 ...
Java8 Streams API 详解
一、为什么需要 Stream
Stream 作为 Java 8 的一大亮点,它与 java.io 包里的 InputStream 和 OutputStream 是完全不同的概念。它也不同于 StAX 对 XML 解析的 Stream,也不是 Amazon Kinesis 对大数据实时处理的 Stream。
Java 8 中的 Stream 是对集合(Collection)对象功能的增强,它专注于对集合对象进行各种非常便利、高效的聚合操作(aggregate operation),或者大批量数据操作 (bulk data operation)。
Stream API 借助于同样新出现的 Lambda 表达式,极大的提高编程效率和程序可读性。同时它提供串行和并行两种模式进行汇聚操作,并发模式能够充分利用多核处理器的优势,使用 fork/join 并行方式来拆分任务和加速处理过程。
通常编写并行代码很难而且容易出错, 但使用 Stream API 无需编写一行多线程的代码,就可以很方便地写出高性能的并发程序。所以说,Java 8 中首次出现的 java.util.stream 是一个函数式 ...
Java Web 中接入支付宝支付
注:因为没有企业账号,所以本篇文章为沙箱环境中,但是其逻辑和真实环境是一样的。
接入支付宝的步骤大致如下:
申请一个沙箱环境
生成签名,并在沙箱环境中设置好签名
下载官方的SDK结合API学习后开发
申请沙箱环境的网址是:沙箱环境
签名工具及它的使用方法的链接是:签名工具
官方的API链接是:API
官方的Demo是: Demo For Java
我自己写好了一个Demo,注释丰富,可以帮助大家学习,比官方的略微复杂一些,地址在文章开头。支付宝支付本质上就是使用它的API,根据上面提供的资料和我的Demo相信应该能够帮助大家学会了。
如果有疑问,欢迎评论留言。
特别提示
当你开始运行Demo程序时,可不要用你自己的支付宝进行测试哦,想想也不能用真实的支付宝扣钱啊。
官方提供了一个商家账号,一个买家账号,链接在这:沙箱账号
这个账号也不能在支付宝登录,而要使用沙箱钱包,暂时只支持Android版,链接在这:沙箱钱包
因为异步通知方法必须要公网能够访问,因此我推荐下我使用的软件,NatApp。能够实现内网穿透,开发用免费版就可以了。
如何使用例子
Step1: 找到 ...