暂时未有相关云产品技术能力~
咕泡科技联合创始人。著有畅销书《Spring 5核心原理与30个类手写实战》、《Netty 4核心原理与手写RPC框架实战》、《设计模式就该这样学》、《Java面试八股文》。一个从美术生转型Java开发的程序员,3年内做到架构师,5年内做到CTO。14年Java从业经验,6年线上教学经验。
近期一个 Apache Log4j 远程代码执行漏洞细节被公开,攻击者利用漏洞可以远程执行代码。经过分析,该组件存在Java JNDI注入漏洞,当程序将用户输入的数据进行日志,即可触发此漏洞,成功利用此漏洞可以在目标服务器上执行任意代码。
空对象模式(Null Object Pattern)不属于GoF设计模式,但是它作为一种经常出现的模式足以被视为设计模式了。其具体定义为设计一个空对象取代NULL对象实例的检查。NULL对象不是检查控制,而是反映一个不做任何动作的关系。这样的NULL对象也可以在数据不可用的时候提供默认的行为,属于行为型设计模式。
规格模式(Specification Pattern)可以认为是组合模式的一种扩展。很多时候程序中的某些条件决定了业务逻辑,这些条件就可以抽离出来以某种关系(与、或、非)进行组合,从而灵活地对业务逻辑进行定制。另外,在查询、过滤等应用场合中,通过预定义多个条件,然后使用这些条件的组合来处理查询或过滤,而不是使用逻辑判断语句来处理,可以简化整个实现逻辑。
每到年底,管理层就要开始评定员工一年的工作绩效,员工分为工程师和经理;管理层有CEO和CTO。那么CTO关注工程师的代码量、经理的新产品数量;CEO关注工程师的KPI、经理的KPI及新产品数量。
在现实生活中,中介者的存在是不可缺少的,如果没有了中介者,我们就不能与远方的朋友进行交流。各个同事对象将会相互进行引用,如果每个对象都与多个对象进行交互,则会形成如下图所示的网状结构。
大家都用过网页中的富文本编辑器,编辑器通常都会附带草稿箱、撤销等操作。下面用一段代码来实现一个这样的功能。假设,我们在GPer社区中发布一篇文章,文章编辑的过程需要花很长时间,中间也会不停地撤销、修改,甚至可能要花好几天才能写出一篇精品文章,因此可能会将已经编辑好的内容实时保存到草稿箱。
假如我们开发一个播放器,播放器有播放功能、拖动进度条功能、停止播放功能、暂停功能,我们在操作播放器的时候并不是直接调用播放器的方法,而是通过一个控制条去传达指令给播放器内核,具体传达什么指令,会被封装为一个个按钮。那么每个按钮就相当于对一条命令的封装。用控制条实现了用户发送指令与播放器内核接收指令的解耦。下面来看代码,首先创建播放器内核GPlayer类。
Design Patterns: Elements of Reusable Object-Oriented Software(以下简称《设计模式》),一书由Erich Gamma、Richard Helm、Ralph Johnson和John Vlissides合著(Addison-Wesley,1995)。这四位作者常被称为“四人组(Gang of Four)”,而这本书也就被称为“四人组(或 GoF)”书。他们首次给我们总结出一套软件开发可以反复使用的经验,帮助我们提高代码的可重用性、系统的可维护性等,解决软件开发中的复杂问题。
下面用解释器模式来实现一个数学表达式计算器,包含加、减、乘、除运算。 首先定义抽象表达式角色IArithmeticInterpreter接口。
当小伙伴们在社区提问时,如果有设置指定用户回答,则对应的用户就会收到邮件通知,这就是观察者模式的一种应用场景。有些小伙伴可能会想到MQ、异步队列等,其实JDK本身就提供这样的API。我们用代码来还原这样一个应用场景,首先创建GPer类。
迭代器模式的UML类图如下图所示。
一般的电商平台都是整合众多的子系统聚合到一起形成一个大型的购物平台,一般情况下,有很多现成的功能都不是重新开发的,而是要去对接已有的各个子系统,这些子系统可能涉及积分系统、支付系统、物流系统的接口调用。如果所有的接口调用全部由前端发送网络请求去调用现有接口,一则会增加前端开发人员的难度,二则会增加一些网络请求,影响页面性能。此时就可以发挥门面模式的优势了。将所有现成的接口全部整合到一个类中,由后端提供统一的接口供前端调用,这样前端开发人员就不需要关心各接口的业务关系,只需要把精力集中在页面交互上。我们用代码来模拟一个积分兑换礼品的业务场景。
工厂方法模式主要适用于以下应用场景。 (1)创建对象需要大量重复的代码。 (2)客户端(应用层)不依赖产品类实例如何被创建、实现等细节。 (3)一个类通过其子类来指定创建哪个对象。
通常的模板方法模式中会设计一个abstract的抽象方法,交给它的子类实现,这个方法称为模板方法。而钩子方法,是对于抽象方法或者接口中定义的方法的一个空实现,也是模板方法模式的一种实现方式。
首先你的JDK需要升级到1.8以上版本。从Spring 3.0开始,Spring源码采用GitHub托管,不再提供官网下载链接。这里不做过多赘述,大家可自行去GitHub网站下载,我使用的版本下载链接为 https://github.com/spring-projects/spring-framework/archive/v5.0.2.RELEASE.zip ,下载完成后,解压源码包会看到如下图所示的文件目录。
大家都知道,咕泡学院的架构师课程经常会有优惠活动,优惠策略有很多种可能,如领取优惠券抵扣、返现促销、拼团优惠等。下面用代码来模拟,首先创建一个促销策略的抽象PromotionStrategy。
我们使用适配模式来实现一个实际的业务场景,解决实际问题。年纪稍微大一点的小伙伴一定经历过这样的过程。很早以前开发的老系统应该都有登录接口,但是随着业务的发展和社会的进步,单纯地依赖用户名密码登录显然不能满足用户需求。现在,大部分系统都已经支持多种登录方式,如QQ登录、微信登录、手机登录、微博登录等,同时保留用户名密码的登录方式。虽然登录形式丰富,但是登录后的处理逻辑可以不必改,都是将登录状态保存到Session,遵循开闭原则。首先创建统一的返回结果ResultMsg类。
持续集成
来看这样一个场景,上班族大多有睡懒觉的习惯,每天早上上班都时间很紧张,于是很多人为了多睡一会儿,就用更方便的方式解决早餐问题,有些人早餐可能会吃煎饼。煎饼中可以加鸡蛋,也可以加香肠,但是不管怎么加码,都还是一个煎饼。再比如,给蛋糕加上一些水果,给房子装修,都是装饰器模式。
首先创建一个实体类Member。
我们在日常的Java开发中,经常需要处理一些字符串,这个时候正则表达式是非常有用的。几乎在所有的编程语言中都支持正则表达式。以下我将压箱底多年的干货搬出来给大家参考,都是我们日常使用频次比较高的正则表达式,希望能能大大提高你的工作效率。如果本文对大家有帮助,大家可以关注“Tom弹架构”,后续会连载正则表达式的基础知识。
合成复用原则(Composite/Aggregate Reuse Principle,CARP)是指尽量使用对象组合(has-a)/聚合(contanis-a)而不是继承关系达到软件复用的目的。可以使系统更加灵活,降低类与类之间的耦合度,一个类的变化对其他类造成的影响相对较少。
迪米特原则(Law of Demeter LoD)是指一个对象应该对其他对象保持最少的了解,又叫最少知道原则(Least Knowledge Principle,LKP),尽量降低类与类之间的耦合度。迪米特原则主要强调:只和朋友交流,不和陌生人说话。出现在成员变量、方法的输入、输出参数中的类都可以称为成员朋友类,而出现在方法体内部的类不属于朋友类。
接口隔离原则符合我们常说的高内聚、低耦合的设计思想,可以使类具有很好的可读性、可扩展性和可维护性。我们在设计接口的时候,要多花时间去思考,要考虑业务模型,包括对以后有可能发生变更的地方还要做一些预判。所以,对于抽象、对于业务模型的理解是非常重要的。下面我们来看一段代码,对一个动物行为进行抽象描述。
单一职责(Simple Responsibility Pinciple,SRP)是指不要存在多于一个导致类变更的原因。假设我们有一个类负责两个职责,一旦发生需求变更,修改其中一个职责的逻辑代码,有可能导致另一个职责的功能发生故障。这样一来,这个类就存在两个导致类变更的原因。如何解决这个问题呢?将两个职责用两个类来实现,进行解耦。后期需求变更维护互不影响。这样的设计,可以降低类的复杂度,提高类的可读性,提高系统的可维护性,降低变更引起的风险。总体来说,就是一个类、接口或方法只负责一项职责。
依赖倒置原则(Dependence Inversion Principle,DIP)是指设计代码结构时,高层模块不应该依赖低层模块,二者都应该依赖其抽象。抽象不应该依赖细节,细节应该依赖抽象。通过依赖倒置,可以减少类与类之间的耦合性,提高系统的稳定性,提高代码的可读性和可维护性,并且能够降低修改程序所造成的风险。接下来看一个案例,还是以Course(课程)为例,先来创建一个类Tom:
开闭原则(Open-Closed Principle,OCP)是指一个软件实体(如类、模块和函数)应该对扩展开放,对修改关闭。所谓的开闭,也正是对扩展和修改两个行为的一个原则。它强调的是用抽象构建框架,用实现扩展细节,可以提高软件系统的可复用性及可维护性。开闭原则是面向对象设计中最基础的设计原则,它指导我们如何建立稳定、灵活的系统。例如版本更新,我们尽可能不修改源代码,但是可以增加新功能。
常见软件的版本命名举例如下表所示。
1.局部变量能否和全局变量重名 点击空白处显示答案 ▼ 能,局部会屏蔽全局。
经过一周时间的Log4j2 RCE事件的发酵,事情也变也越来越复杂和有趣,就连 Log4j 官方紧急发布了 2.15.0 版本之后没有过多久,又发声明说 2.15.0 版本也没有完全解决问题,然后进而继续发布了 2.16.0 版本。大家都以为2.16.0是最终终结版本了,没想到才过多久又爆雷,Log4j 2.17.0横空出世。
循环依赖就是指循环引用,是两个或多个Bean相互之间的持有对方的引用。BeanA 类依赖了Bean B类,同时Bean B类又依赖了Bean A类。这种依赖关系形成了一个闭环,我们把这种依赖关系就称之为循环依赖。Bean A类依赖了Bean B类,Bean B类依赖了Bean C类,Bean C类依赖了Bean A类,如此,也形成了一个依赖闭环。自己引用了自己,自己和自己形成了依赖关系。同样也是一个依赖闭环。
Spring作为当前Java最流行、最强大的轻量级框架。Spring Bean的生命周期也是面试高频题,了解Spring Bean周期也能更好地帮助我们解决日常开发中的问题。程序员应该都知道Spring的基础容器是ApplicationContext。应很多粉丝的强烈建议,本文我来分析分析 ApplicationContext中Bean的生命周期。ApplicationContext是顶层容器接口BeanFactory的实现类,因此,我们了解了ApplicationContext的生命周期逻辑,也基本上了解了其他类型容器的生命周期逻辑。