Java面试题-设计模式23(2024最新版),2024年最新二叉树 面试题

先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7

深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年最新Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以添加V获取:vip1024b (备注Java)
img

正文

//设置下一个处理者是谁

public void setNext(Handler _handler){

this.nextHandler = _handler;

}

//每个处理者都有一个处理级别

protected abstract Level getHandlerLevel();

//每个处理者都必须实现处理任务

protected abstract Response echo(Request request);

}

抽象的处理者实现三个职责:

一是定义一个请求的处理方法 handleMessage,唯一对外开放的方法;

二是定义一个链的编排方法 setNext,设置下一个处理者;

三是定义了具体的请求者必须实现的两个方法:定义自己能够处理的级别

getHandlerLevel 和具体的处理任务 echo。

注意事项:

链中节点数量需要控制,避免出现超长链的情况,一般的做法是在 Handler 中设置

一个最大节点数量,在 setNext 方法中判断是否已经是超过其阈值,超过则不允许

该链建立,避免无意识地破坏系统性能。

11.装饰模式(Decorator Pattern)

定义:Attach additional responsibilities to an object dynamically keeping the

same interface.Decorators provide a flexible alternative to subclassing for

extending functionality.(动态地给一个对象添加一些额外的职责。就增加功能来

说,装饰模式相比生成子类更为灵活。)

● Component 抽象构件Component 是一个接口或者是抽象类,就是定义我们最核心的对象,也就是最原

始的对象,如上面的成绩单。

注意:在装饰模式中,必然有一个最基本、最核心、最原始的接口或抽象类充当

Component 抽象构件。

● ConcreteComponent 具体构件

ConcreteComponent 是最核心、最原始、最基本的接口或抽象类的实现,你要装

饰的就是它。

● Decorator 装饰角色

一般是一个抽象类,做什么用呢?实现接口或者抽象方法,它里面可不一定有抽象

的方法呀,在它的属性里必然有一个 private 变量指向 Component 抽象构件。

● 具体装饰角色

ConcreteDecoratorA 和 ConcreteDecoratorB 是两个具体的装饰类,你要把你最核

心的、最原始的、最基本的东西装饰成其他东西,上面的例子就是把一个比较平庸

的成绩单装饰成家长认可的成绩单。

使用场景:

● 需要扩展一个类的功能,或给一个类增加附加功能。

● 需要动态地给一个对象增加功能,这些功能可以再动态地撤销。

● 需要为一批的兄弟类进行改装或加装功能,当然是首选装饰模式。

12.策略模式(Strategy Pattern)

定义:Define a family of algorithms,encapsulate each one,and make them

interchangeable.(定义一组算法,将每个算法都封装起来,并且使它们之间可以

互换。)

● Context 封装角色

它也叫做上下文角色,起承上启下封装作用,屏蔽高层模块对策略、算法的直接访

问,封装可能存在的变化。

● Strategy 抽象策略角色

策略、算法家族的抽象,通常为接口,定义每个策略或算法必须具有的方法和属

性。各位看官可能要问了,类图中的 AlgorithmInterface 是什么意思,嘿嘿,

algorithm 是“运算法则”的意思,结合起来意思就明白了吧。

● ConcreteStrategy 具体策略角色(多个)

实现抽象策略中的操作,该类含有具体的算法。

使用场景:

● 多个类只有在算法或行为上稍有不同的场景。

● 算法需要自由切换的场景。

● 需要屏蔽算法规则的场景。

注意事项:具体策略数量超过 4 个,则需要考虑使用混合模式

策略模式扩展:策略枚举public enum Calculator {

//加法运算

ADD(“+”){

public int exec(int a,int b){

return a+b;

}

},

//减法运算

SUB(“-”){

public int exec(int a,int b){

return a - b;

}

};

String value = “”;

//定义成员值类型

private Calculator(String _value){

this.value = _value;

}

//获得枚举成员的值

public String getValue(){

return this.value;

}

//声明一个抽象函数

public abstract int exec(int a,int b);

}

定义:

● 它是一个枚举。

● 它是一个浓缩了的策略模式的枚举。

注意:

受枚举类型的限制,每个枚举项都是 public、final、static 的,扩展性受到了一定

的约束,因此在系统开发中,策略枚举一般担当不经常发生变化的角色。

致命缺陷:

所有的策略都需要暴露出去,由客户端决定使用哪一个策略。

13.适配器模式(Adapter Pattern)

定义:Convert the interface of a class into another interface clients

expect.Adapter lets classes work together that couldn’t otherwise because of

incompatible interfaces.(将一个类的接口变换成客户端所期待的另一种接口,从

而使原本因接口不匹配而无法在一起工作的两个类能够在一起工作。)

类适配器:● Target 目标角色

该角色定义把其他类转换为何种接口,也就是我们的期望接口,例子中的

IUserInfo 接口就是目标角色。

● Adaptee 源角色

你想把谁转换成目标角色,这个“谁”就是源角色,它是已经存在的、运行良好的类

或对象,经过适配器角色的包装,它会成为一个崭新、靓丽的角色。

● Adapter 适配器角色

适配器模式的核心角色,其他两个角色都是已经存在的角色,而适配器角色是需要

新建立的,它的职责非常简单:把源角色转换为目标角色,怎么转换?通过继承或

是类关联的方式。

使用场景:

你有动机修改一个已经投产中的接口时,适配器模式可能是最适合你的模式。比如

系统扩展了,需要使用一个已有或新建立的类,但这个类又不符合系统的接口,怎

么办?使用适配器模式,这也是我们例子中提到的。

注意事项:

详细设计阶段不要考虑使用适配器模式,使用主要场景为扩展应用中。

对象适配器:

对象适配器和类适配器的区别:

类适配器是类间继承,对象适配器是对象的合成关系,也可以说是类的关联关系,

这是两者的根本区别。(实际项目中对象适配器使用到的场景相对比较多)。

14.迭代器模式(Iterator Pattern)

定义:Provide a way to access the elements of an aggregate object sequentially

without exposing its underlying representation.(它提供一种方法访问一个容器对

象中各个元素,而又不需暴露该对象的内部细节。)

● Iterator 抽象迭代器

抽象迭代器负责定义访问和遍历元素的接口,而且基本上是有固定的 3 个方法:

first()获得第一个元素,next()访问下一个元素,isDone()是否已经访问到底部

(Java 叫做 hasNext()方法)。

● ConcreteIterator 具体迭代器

具体迭代器角色要实现迭代器接口,完成容器元素的遍历。

● Aggregate 抽象容器容器角色负责提供创建具体迭代器角色的接口,必然提供一个类似 createIterator()

这样的方法,在 Java 中一般是 iterator()方法。

● Concrete Aggregate 具体容器

具体容器实现容器接口定义的方法,创建出容纳迭代器的对象。

ps:迭代器模式已经被淘汰,java 中已经把迭代器运用到各个聚集类

(collection)中了,使用 java 自带的迭代器就已经满足我们的需求了。

15.组合模式((Composite Pattern))

定义:Compose objects into tree structures to represent part-whole

hierarchies.Composite lets clients treat individual objects and compositions of

objects uniformly.(将对象组合成树形结构以表示“部分-整体”的层次结构,使得用

户对单个对象和组合对象的使用具有一致性。)

● Component 抽象构件角色

定义参加组合对象的共有方法和属性,可以定义一些默认的行为或属性,比如我们

例子中的 getInfo 就封装到了抽象类中。

● Leaf 叶子构件

叶子对象,其下再也没有其他的分支,也就是遍历的最小单位。

● Composite 树枝构件

树枝对象,它的作用是组合树枝节点和叶子节点形成一个树形结构。

树枝构件的通用代码:

public class Composite extends Component {

//构件容器

private ArrayList componentArrayList = new

ArrayList();

//增加一个叶子构件或树枝构件

public void add(Component component){

this.componentArrayList.add(component);

}

//删除一个叶子构件或树枝构件

public void remove(Component component){

this.componentArrayList.remove(component);

}

//获得分支下的所有叶子构件和树枝构件

public ArrayList getChildren(){

return this.componentArrayList;

}

}使用场景:

● 维护和展示部分-整体关系的场景,如树形菜单、文件和文件夹管理。

● 从一个整体中能够独立出部分模块或功能的场景。

注意:

只要是树形结构,就考虑使用组合模式。

16.观察者模式(Observer Pattern)

定义:Define a one-to-many dependency between objects so that when one

object changes state,all its dependents are notified and updated automatically.

(定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于

它的对象都会得到通知并被自动更新。)

● Subject 被观察者

定义被观察者必须实现的职责,它必须能够动态地增加、取消观察者。它一般是抽

象类或者是实现类,仅仅完成作为被观察者必须实现的职责:管理观察者并通知观

察者。

● Observer 观察者

观察者接收到消息后,即进行 update(更新方法)操作,对接收到的信息进行处

理。

● ConcreteSubject 具体的被观察者

定义被观察者自己的业务逻辑,同时定义对哪些事件进行通知。

● ConcreteObserver 具体的观察者

每个观察在接收到消息后的处理反应是不同,各个观察者有自己的处理逻辑。

被观察者通用代码:

public abstract class Subject {

//定义一个观察者数组

private Vector obsVector = new Vector();

//增加一个观察者

public void addObserver(Observer o){

this.obsVector.add(o);

}

//删除一个观察者

public void delObserver(Observer o){

this.obsVector.remove(o);

}

//通知所有观察者

public void notifyObservers(){

for(Observer o:this.obsVector){

o.update();

} }

}

使用场景:

● 关联行为场景。需要注意的是,关联行为是可拆分的,而不是“组合”关系。

● 事件多级触发场景。

● 跨系统的消息交换场景,如消息队列的处理机制。

注意:

● 广播链的问题

在一个观察者模式中最多出现一个对象既是观察者也是被观察者,也就是说消息最

多转发一次(传递两次)。

● 异步处理问题

观察者比较多,而且处理时间比较长,采用异步处理来考虑线程安全和队列的问

题。

17.门面模式(Facade Pattern)

定义:Provide a unified interface to a set of interfaces in a subsystem.Facade

defines a higher-level interface that makes the subsystem easier to use.(要求一

个子系统的外部与其内部的通信必须通过一个统一的对象进行。门面模式提供一个

高层次的接口,使得子系统更易于使用。)

● Facade 门面角色

客户端可以调用这个角色的方法。此角色知晓子系统的所有功能和责任。一般情况

下,本角色会将所有从客户端发来的请求委派到相应的子系统去,也就说该角色没

有实际的业务逻辑,只是一个委托类。

● subsystem 子系统角色

可以同时有一个或者多个子系统。每一个子系统都不是一个单独的类,而是一个类

的集合。子系统并不知道门面的存在。对于子系统而言,门面仅仅是另外一个客户

端而已。

使用场景:

● 为一个复杂的模块或子系统提供一个供外界访问的接口

● 子系统相对独立——外界对子系统的访问只要黑箱操作即可

● 预防低水平人员带来的风险扩散

注意:

●一个子系统可以有多个门面

●门面不参与子系统内的业务逻辑

18.备忘录模式(Memento Pattern)

定义:Without violating encapsulation,capture and externalize an object’s internal

state so that the object can be restored to this state later.(在不破坏封装性的前提

下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该

对象恢复到原先保存的状态。)

● Originator 发起人角色

记录当前时刻的内部状态,负责定义哪些属于备份范围的状态,负责创建和恢复备

忘录数据。

● Memento 备忘录角色(简单的 javabean)

负责存储 Originator 发起人对象的内部状态,在需要的时候提供发起人需要的内部

状态。

● Caretaker 备忘录管理员角色(简单的 javabean)

对备忘录进行管理、保存和提供备忘录。

使用场景:

● 需要保存和恢复数据的相关状态场景。

● 提供一个可回滚(rollback)的操作。

● 需要监控的副本场景中。

● 数据库连接的事务管理就是用的备忘录模式。

注意:

●备忘录的生命期

●备忘录的性能

不要在频繁建立备份的场景中使用备忘录模式(比如一个 for 循环中)。

clone 方式备忘录:

● 发起人角色融合了发起人角色和备忘录角色,具有双重功效

多状态的备忘录模式

● 增加了一个 BeanUtils 类,其中 backupProp 是把发起人的所有属性值转换到

HashMap 中,方便备忘录角色存储。restoreProp 方法则是把 HashMap 中的值返

回到发起人角色中。

BeanUtil 工具类代码:

public class BeanUtils {

//把 bean 的所有属性及数值放入到 Hashmap 中

public static HashMap<String,Object> backupProp(Object bean){

HashMap<String,Object> result = new

HashMap<String,Object>();

try { //获得 Bean 描述

BeanInfo

beanInfo=Introspector.getBeanInfo(bean.getClass());

//获得属性描述

PropertyDescriptor[]

descriptors=beanInfo.getPropertyDescriptors();

//遍历所有属性

for(PropertyDescriptor des:descriptors){

//属性名称

String fieldName = des.getName();

//读取属性的方法

Method getter = des.getReadMethod();

//读取属性值

Object fieldValue=getter.invoke(bean,new

Object[]{});

if(!fieldName.equalsIgnoreCase(“class”)){

result.put(fieldName, fieldValue);

}

}

} catch (Exception e) {

//异常处理

}

return result;

}

//把 HashMap 的值返回到 bean 中

public static void restoreProp(Object bean,HashMap<String,Object>

propMap){

try {

//获得 Bean 描述

BeanInfo beanInfo =

Introspector.getBeanInfo(bean.getClass());

//获得属性描述

PropertyDescriptor[] descriptors =

beanInfo.getPropertyDescriptors();

//遍历所有属性

for(PropertyDescriptor des:descriptors){

//属性名称

String fieldName = des.getName();

//如果有这个属性

if(propMap.containsKey(fieldName)){

//写属性的方法

Method setter = des.getWriteMethod();

setter.invoke(bean, new

Object[]{propMap.get(fieldName)}); }

}

} catch (Exception e) {

//异常处理

System.out.println(“shit”);

e.printStackTrace();

}

}

}

多备份的备忘录:略

封装得更好一点:保证只能对发起人可读

●建立一个空接口 IMemento——什么方法属性都没有的接口,然后在发起人

Originator 类中建立一个内置类(也叫做类中类)Memento 实现 IMemento 接口,

同时也实现自己的业务逻辑。

19.访问者模式(Visitor Pattern)

定义:Represent an operation to be performed on the elements of an object

structure. Visitor lets you define a new operation without changing the classes of

the elements on which it operates. (封装一些作用于某种数据结构中的各元素的

操作,它可以在不改变数据结构的前提下定义作用于这些元素的新的操作。)

● Visitor——抽象访问者

抽象类或者接口,声明访问者可以访问哪些元素,具体到程序中就是 visit 方法的

参数定义哪些对象是可以被访问的。

● ConcreteVisitor——具体访问者

它影响访问者访问到一个类后该怎么干,要做什么事情。

● Element——抽象元素

接口或者抽象类,声明接受哪一类访问者访问,程序上是通过 accept 方法中的参

数来定义的。

● ConcreteElement——具体元素

实现 accept 方法,通常是 visitor.visit(this),基本上都形成了一种模式了。

● ObjectStruture——结构对象

元素产生者,一般容纳在多个不同类、不同接口的容器,如 List、Set、Map 等,

在项目中,一般很少抽象出这个角色。使用场景:

● 一个对象结构包含很多类对象,它们有不同的接口,而你想对这些对象实施一些

依赖于其具体类的操作,也就说是用迭代器模式已经不能胜任的情景。

● 需要对一个对象结构中的对象进行很多不同并且不相关的操作,而你想避免让这

些操作“污染”这些对象的类。

20.状态模式(复杂)

定义:Allow an object to alter its behavior when its internal state changes.The

object will appear to change its class.(当一个对象内在状态改变时允许其改变行

为,这个对象看起来像改变了其类。)

● State——抽象状态角色

接口或抽象类,负责对象状态定义,并且封装环境角色以实现状态切换。

● ConcreteState——具体状态角色

每一个具体状态必须完成两个职责:本状态的行为管理以及趋向状态处理,通俗地

说,就是本状态下要做的事情,以及本状态如何过渡到其他状态。

● Context——环境角色

定义客户端需要的接口,并且负责具体状态的切换。

使用场景:

● 行为随状态改变而改变的场景

这也是状态模式的根本出发点,例如权限设计,人员的状态不同即使执行相同的行

为结果也会不同,在这种情况下需要考虑使用状态模式。

● 条件、分支判断语句的替代者

注意:

状态模式适用于当某个对象在它的状态发生改变时,它的行为也随着发生比较大的

变化,也就是说在行为受状态约束的情况下可以使用状态模式,而且使用时对象的

状态最好不要超过 5 个。

21.解释器模式(Interpreter Pattern)

(少用)

定义:Given a language, define a representation for its grammar along with an

interpreter that uses the representation to interpret sentences in the language.

(给定一门语言,定义它的文法的一种表示,并定义一个解释器,该解释器使用该

表示来解释语言中的句子。)● AbstractExpression——抽象解释器

具体的解释任务由各个实现类完成,具体的解释器分别由 TerminalExpression 和

Non-terminalExpression 完成。

● TerminalExpression——终结符表达式

实现与文法中的元素相关联的解释操作,通常一个解释器模式中只有一个终结符表

达式,但有多个实例,对应不同的终结符。具体到我们例子就是 VarExpression

类,表达式中的每个终结符都在栈中产生了一个 VarExpression 对象。

● NonterminalExpression——非终结符表达式

文法中的每条规则对应于一个非终结表达式,具体到我们的例子就是加减法规则分

别对应到 AddExpression 和 SubExpression 两个类。非终结符表达式根据逻辑的

复杂程度而增加,原则上每个文法规则都对应一个非终结符表达式。

● Context——环境角色

具体到我们的例子中是采用 HashMap 代替。

使用场景:

● 重复发生的问题可以使用解释器模式

● 一个简单语法需要解释的场景

注意:

尽量不要在重要的模块中使用解释器模式,否则维护会是一个很大的问题。在项目

中可以使用 shell、JRuby、Groovy 等脚本语言来代替解释器模式,弥补 Java 编

译型语言的不足。

22.享元模式(Flyweight Pattern)

定义:Use sharing to support large numbers of fine-grained objects efficiently.

(使用共享对象可有效地支持大量的细粒度的对象。)

对象的信息分为两个部分:内部状态(intrinsic)与外部状态(extrinsic)。

● 内部状态

内部状态是对象可共享出来的信息,存储在享元对象内部并且不会随环境改变而改

变。

● 外部状态

外部状态是对象得以依赖的一个标记,是随环境改变而改变的、不可以共享的状

态。

● Flyweight——抽象享元角色

它简单地说就是一个产品的抽象类,同时定义出对象的外部状态和内部状态的接口

或实现。

● ConcreteFlyweight——具体享元角色

具体的一个产品类,实现抽象角色定义的业务。该角色中需要注意的是内部状态处

理应该与环境无关,不应该出现一个操作改变了内部状态,同时修改了外部状态,

这是绝对不允许的。● unsharedConcreteFlyweight——不可共享的享元角色

不存在外部状态或者安全要求(如线程安全)不能够使用共享技术的对象,该对象

一般不会出现在享元工厂中。

● FlyweightFactory——享元工厂

职责非常简单,就是构造一个池容器,同时提供从池中获得对象的方法。

享元工厂的代码:

public class FlyweightFactory {

//定义一个池容器

private static HashMap<String,Flyweight> pool= new

HashMap<String,Flyweight>();

//享元工厂

public static Flyweight getFlyweight(String Extrinsic){

//需要返回的对象

Flyweight flyweight = null;

//在池中没有该对象

if(pool.containsKey(Extrinsic)){

flyweight = pool.get(Extrinsic);

}else{

//根据外部状态创建享元对象

flyweight = new ConcreteFlyweight1(Extrinsic);

//放置到池中

pool.put(Extrinsic, flyweight);

}

return flyweight;

}

}

使用场景:

● 系统中存在大量的相似对象。

● 细粒度的对象都具备较接近的外部状态,而且内部状态与环境无关,也就是说对

象没有特定身份。

● 需要缓冲池的场景。

注意:

● 享元模式是线程不安全的,只有依靠经验,在需要的地方考虑一下线程安全,在

大部分场景下不用考虑。对象池中的享元对象尽量多,多到足够满足为止。

● 性能安全:外部状态最好以 java 的基本类型作为标志,如 String,int,可以提

高效率。

23.桥梁模式(Bridge Pattern)

定义:Decouple an abstraction from its implementation so that the two can vary

independently.(将抽象和实现解耦,使得两者可以独立地变化。)● Abstraction——抽象化角色

它的主要职责是定义出该角色的行为,同时保存一个对实现化角色的引用,该角色

一般是抽象类。

● Implementor——实现化角色

它是接口或者抽象类,定义角色必需的行为和属性。

● RefinedAbstraction——修正抽象化角色

它引用实现化角色对抽象化角色进行修正。

● ConcreteImplementor——具体实现化角色

它实现接口或抽象类定义的方法和属性。

使用场景:

● 不希望或不适用使用继承的场景

● 接口或抽象类不稳定的场景

● 重用性要求较高的场景

注意:

发现类的继承有 N 层时,可以考虑使用桥梁模式。桥梁模式主要考虑如何拆分抽

象和实现。

设计原则:

●Single Responsibility Principle:单一职责原则

单一职责原则有什么好处:

● 类的复杂性降低,实现什么职责都有清晰明确的定义;

● 可读性提高,复杂性降低,那当然可读性提高了;

● 可维护性提高,可读性提高,那当然更容易维护了;

●变更引起的风险降低,变更是必不可少的,如果接口的单一职责做得好,一个接

口修改只对相应的实现类有影响,对其他的接口无影响,这对系统的扩展性、维护

性都有非常大的帮助。

ps:接口一定要做到单一职责,类的设计尽量做到只有一个原因引起变化。

单一职责原则提出了一个编写程序的标准,用“职责”或“变化原因”来衡量接口

或类设计得是否优良,但是“职责”和“变化原因”都是不可度量的,因项目而异,因

环境而异。● Liskov Substitution Principle:里氏替换原则

定义:Functions that use pointers or references to base classes must be able to

use objects of derived classes without knowing it.

(所有引用基类的地方必须能透明地使用其子类的对象。)

通俗点讲,只要父类能出现的地方子类就可以出现,而且替换为子类也不会产生任

何错误或异常,使用者可能根本就不需要知道是父类还是子类。但是,反过来就不

行了,有子类出现的地方,父类未必就能适应。

定义中包含的四层含义:

1.子类必须完全实现父类的方法

2.子类可以有自己的个性

3.覆盖或实现父类的方法时输入参数可以被放大

如果父类的输入参数类型大于子类的输入参数类型,会出现父类存在的地

方,子类未必会存在,因为一旦把子类作为参数传入,调用者很可能进入子类的方

法范畴。

4. 覆写或实现父类的方法时输出结果可以被缩小

父类的一个方法的返回值是一个类型 T,子类的相同方法(重载或覆写)的返

回值为 S,那么里氏替换原则就要求 S 必须小于等于 T,也就是说,要么 S 和 T

是同一个类型,要么 S 是 T 的子类。

● Interface Segregation Principle:接口隔离原则

接口分为两种:

实例接口(Object Interface):Java 中的类也是一种接口

类接口(Class Interface): Java 中经常使用 Interface 关键字定义的接口

隔离:建立单一接口,不要建立臃肿庞大的接口;即接口要尽量细化,同时接口中

的方法要尽量少。

接口隔离原则与单一职责原则的不同:接口隔离原则与单一职责的审视角度是不相

同的,单一职责要求的是类和接口职责单一,注重的是职责,这是业务逻辑上的划

分,而接口隔离原则要求接口的方法尽量少。

● Dependence Inversion Principle:依赖倒置原则

原始定义:

①高层模块不应该依赖低层模块,两者都应该依赖其抽象;

②抽象不应该依赖细节(实现类);

③细节应该依赖抽象。

依赖倒置原则在 java 语言中的体现:

①模块间的依赖通过抽象发生,实现类之间不发生直接的依赖关系,其依赖关系是

通过接口或抽象类产生的;

②接口或抽象类不依赖于实现类;③实现类依赖接口或抽象类。

依赖的三种写法:

①构造函数传递依赖对象(构造函数注入)

②Setter 方法传递依赖对象(setter 依赖注入)

③接口声明依赖对象(接口注入)

使用原则:

依赖倒置原则的本质就是通过抽象(接口或抽象类)使各个类或模块的实现彼此独

立,不互相影响,实现模块间的松耦合,我们怎么在项目中使用这个规则呢?只要

遵循以下的几个规则就可以:

①每个类尽量都有接口或抽象类,或者抽象类和接口两者都具备

②变量的表面类型尽量是接口或者是抽象类

③任何类都不应该从具体类派生(只要不超过两层的继承是可以忍受的)

④尽量不要复写基类的方法

⑤结合里氏替换原则使用

●Open Closed Principle:开闭原则

定义:软件实体应该对扩展开放,对修改关闭。

其含义是说一个软件实体应该通过扩展来实现变化,而不是通过修改已有的代码来

实现变化。

软件实体:项目或软件产品中按照一定的逻辑规则划分的模块、抽象和类、方法。

变化的三种类型:

①逻辑变化

只变化一个逻辑,而不涉及其他模块,比如原有的一个算法是 a*b+c,现在需要修

改为 a*b*c,可以通过修改原有类中的方法的方式来完成,前提条件是所有依赖或

关联类都按照相同的逻辑处理。

②子模块变化

一个模块变化,会对其他的模块产生影响,特别是一个低层次的模块变化必然引起

高层模块的变化,因此在通过扩展完成变化时,高层次的模块修改是必然的。

③可见视图变化

可见视图是提供给客户使用的界面,如 JSP 程序、Swing 界面等,该部分的变化

结语

小编也是很有感触,如果一直都是在中小公司,没有接触过大型的互联网架构设计的话,只靠自己看书去提升可能一辈子都很难达到高级架构师的技术和认知高度。向厉害的人去学习是最有效减少时间摸索、精力浪费的方式。

我们选择的这个行业就一直要持续的学习,又很吃青春饭。

虽然大家可能经常见到说程序员年薪几十万,但这样的人毕竟不是大部份,要么是有名校光环,要么是在阿里华为这样的大企业。年龄一大,更有可能被裁。

送给每一位想学习Java小伙伴,用来提升自己。

在这里插入图片描述

本文到这里就结束了,喜欢的朋友可以帮忙点赞和评论一下,感谢支持!

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
img

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
的几个规则就可以:

①每个类尽量都有接口或抽象类,或者抽象类和接口两者都具备

②变量的表面类型尽量是接口或者是抽象类

③任何类都不应该从具体类派生(只要不超过两层的继承是可以忍受的)

④尽量不要复写基类的方法

⑤结合里氏替换原则使用

●Open Closed Principle:开闭原则

定义:软件实体应该对扩展开放,对修改关闭。

其含义是说一个软件实体应该通过扩展来实现变化,而不是通过修改已有的代码来

实现变化。

软件实体:项目或软件产品中按照一定的逻辑规则划分的模块、抽象和类、方法。

变化的三种类型:

①逻辑变化

只变化一个逻辑,而不涉及其他模块,比如原有的一个算法是 a*b+c,现在需要修

改为 a*b*c,可以通过修改原有类中的方法的方式来完成,前提条件是所有依赖或

关联类都按照相同的逻辑处理。

②子模块变化

一个模块变化,会对其他的模块产生影响,特别是一个低层次的模块变化必然引起

高层模块的变化,因此在通过扩展完成变化时,高层次的模块修改是必然的。

③可见视图变化

可见视图是提供给客户使用的界面,如 JSP 程序、Swing 界面等,该部分的变化

结语

小编也是很有感触,如果一直都是在中小公司,没有接触过大型的互联网架构设计的话,只靠自己看书去提升可能一辈子都很难达到高级架构师的技术和认知高度。向厉害的人去学习是最有效减少时间摸索、精力浪费的方式。

我们选择的这个行业就一直要持续的学习,又很吃青春饭。

虽然大家可能经常见到说程序员年薪几十万,但这样的人毕竟不是大部份,要么是有名校光环,要么是在阿里华为这样的大企业。年龄一大,更有可能被裁。

送给每一位想学习Java小伙伴,用来提升自己。

[外链图片转存中…(img-mHCwujez-1713419515633)]

本文到这里就结束了,喜欢的朋友可以帮忙点赞和评论一下,感谢支持!

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
[外链图片转存中…(img-DROjnV1g-1713419515634)]

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 4
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值