前言
以下是我在总结的复习内容,有需要可以参考借鉴一下。我的主页还有另外一篇《2024年考试回忆》,两者结合起来复习,帮助你轻松过考试😊。总的来说,考试不会太难,只要你了解了各类设计模式的含义即可(真的就是了解即可,能从含义确认出是什么设计模式就👌了。不需要学会默写,因为考试的时候这么多选择题选项可以参考😄。
如果需要资料的话可以私信我,我通过邮箱📮发送给各位💪。
资料总结也有错误❎,欢迎大家批评指正👏。
文章目录
- 前言
- 面向对象基础知识
- UML图
- UML图的分类
- 类图
- 序列图
- 面相对象设计原则
- 设计模式
- 创建型模式
- 工厂方法
- 抽象工厂
- 原型模式
- 单例模式
- 生成器模式
- 结构性设计模式
- 适配器模式
- 桥接模式
- 组合模式
- 聚合强制器模式
- 装饰器模式
- 外观模式
- 代理模式
- 享元模式
- 行为型设计模式
- 访问者模式
- 观察者模式
- 策略模式
- 中介者模式
- 命令模式
- 责任链模式
- 状态模式
- 备忘录模式
- 迭代器模式
- 模版方法
- 解释器模式
面向对象基础知识
抽象类和继承
面向对象的概念,用于实现代码的复用和继承关系的建立。
继承违反封装性
面向对象的基本原则,指的是将对象的状态和行为封装在一起,并限制对内部实现的访问。
接口模式
设计一组提供相同服务的服务提供者类,以使客户对象能够无缝地使用不同类型的服务提供者对象,而不需要修改客户对象的实现
私有方法模式:
将一个不打算对外提供的方法,通过private关键字标识起来,设计成私有方法,只对本类的其他方法或者内部类调用。
设计一个Person的类,其中具有用于访问其实例变量(姓名,年龄)的存取器方法
class Person{private String name;private int age;public void setName(String name){this.name = name;}public void getName(){return name;}public void setAge(int age){this.age = age;}public void getAge(){return age;}
}
简述在Java中的synchronized关键字的作用。
synchronized关键字是一种同步机制,用于控制对共享资源的访问。
常量数据管理器(final关键字)
将常量统一放在一个对象中供其他对象访问,该模式能为常量提供一个共同的仓库,便于维护。
说明在一个类被其子类继承的情况下使用存取器方法的效果
- 封装性:即使子类继承了父类的属性,他们仍然不能直接访问这些属性,而必须通过父类提供的存取器方法来访问和修改
- 控制访问:父类可以通过存取器方法来控制对属性的访问
- 保护继承属性:如果父类不希望子类以某种方式修改其属性,可以通过不提供相应的setter方法来实现
- 隐藏实现细节:存取器方法允许父类隐藏其属性的具体时限细节,只暴露一个接口供子类和其他对象使用。
- 接口一致性:即使子类重写了父类的方法,存取器方法仍然提供一个一致的接口,使得外部可以不关心内部实现的差异。
- 易于扩展:如果将来需要添加新的功能,可以在存取器方法中添加这些功能,而不需要修改使用这些属性的代码
总之:**使用存取器方法可以在类被继承的时候提供一种安全、灵活易于维护的方式来管理属性的访问。**使用存取器方法可以在类被继承的时候保护了继承属性,隐藏了实线细节,易于扩展,体现了面向对象的封装性。
Java中通过那些方法来主动释放资源?
finalize()方法finally语句
UML图
UML图的分类
- 结构图:类图、对象图、组件图和部署图(表现一个应用的静态结构)
- 行为图:用例图、序列图、活动图、交互图和状态图(表现一个应用的动态行为)
- 模型管理图:包、子系统和模型(表现应用模式组织和管理的差异性)
类图
类图的三个区域分别表示什么?
类名、属性、方法(操作)(+ public, # protected, - private)
类图的标记:
- 静态变量(static)拥有与类同等的范围,用下划线标记"_"
- 没有程序体的方法是一个抽象方法,用斜体字表示。一个类中有抽象方法,就是一个抽象类。抽象类的子类必须实现它父类的所有抽象方法,否则必须将自己声明为抽象类
- 异常用标有”throw“的虚线箭头指向
- 注释用右上为卷角的矩形表示,并用虚线指向需要注释的部分
- 继承:用实线、空心的三角形箭头表示,箭头指向父类
- 接口:在接口名称上写”interfce“
- 用虚线、空心三角形箭头表示,箭头指向接口
- 用实线和圆环表示,圆环表示接口(旁边写上接口名称,实线指向实现类
- 依赖:目标组件与源组件之间的依赖关系
- 联合关系:类之间的结构化关系
- 组合
- 聚合
在UML类图中,类与类之间的主要关系包括哪些?
- 单向关联、双向关联、
- 自身关联、多维关联、
- 泛化、依赖、聚合、组合
序列图
描述序列图的用图及其元素:
序列图描述了为获取某个对象而在对象之间相互多次交换信息的相互作用。元素:
- 对象:带有一个冒号前缀的类名和下划线的长方形表示
- 消息:水平实线,表示对象之间的通信,可标注消息/操作的名称和参数
- 自我调用:表示对象对自己有调用的请求
面相对象设计原则
- 开放封闭原则:对扩展开发,对修改关闭。
- 里氏替换原则:继承必须确保超类所拥有的性质在子类中仍然成立。
- 合成复用原则:如果需要使用其他类,那么两个类之间尽量使用合成/聚合的方式,而不是使用继承。
- 单一职责原则:一个类应该有且仅有一个引起它变化的的原因。
- 接口隔离原则:一个类对另一个类的依赖应该建立在最小的接口上。
- 依赖倒置原则:高层模块不应该依赖底层模块,两者都应该依赖其抽象,抽象不应该依赖细节,细节应该依赖抽象。
- 迪米特法则(最少知识原则):如果两个类没有直接到通信,那么两个类就不应当发生直接的相互作用。
设计模式
概念:一套被反复使用的、多人知晓的、经过分类编目的、代码设计经验总结。**目的:**为了提高代码的可重用性、可靠性、灵活性,让代码更加容易被理解。分类:
- 创建型模式:主要用于创建对象。
- 结构性模式:主要用于处理类或对象的组合。
- 行为型模式:主要用于描述类或对象如何交互和怎样分配职责。
组件的生命周期:组件的定义——>组件的创建——>组件的服役——>组件的销毁
- 组件的定义:结构型模式
- 组件的创建:创建型模式
- 组件的服役:行为型模式
列出你熟悉的开发框架中,你所了解的设计模式有那些,各有什么好处?
- 单例模式(Singleton)
- 好处:确保一个类只有一个实例,并提供一个全局访问点。
- 工厂模式(Factory Method)
- 好处:封装对象创建过程,允许子类决定实例化哪一个类。
- 抽象工厂模式(Abstract Factory)
- 好处:创建一系列相关或依赖对象的接口,而无需指定它们具体的类。
- 建造者模式(Builder)
- 好处:切分复杂的对象创建过程,以至于能够使用相同的代码模版创建不同参数的对象。
- 原型模式(Prototype)
- 好处:通过复制现有的实例来创建新的实例,而不是通过新建。
- 适配器模式(Adapter)
- 好处:允许不兼容的接口一起工作。
- 装饰器模式(Decorator)
- 好处:动态地给一个对象添加额外的职责。
- 外观模式(Facade)
- 好处:为子系统中的一组接口提供一个一致的高层接口。
- 代理模式(Proxy)
- 好处:为其他对象提供一个代替或占位符以控制对它的访问。
- 观察者模式(Observer)
- 好处:对象间的一对多依赖关系,当一个对象改变状态时,所有依赖于它的对象都会得到通知并自动更新。
- 迭代器模式(Iterator)
- 好处:顺序访问一个聚合对象中的各个元素,不暴露其内部的表示。
- 组合模式(Composite)
- 好处:将对象组合成树形结构以表示“部分-整体”的层次结构。
- 命令模式(Command)
- 好处:将请求封装为一个对象,从而使用户可用不同的请求对客户进行参数化。
- 备忘录模式(Memento)
- 好处:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。
- 状态模式(State)
- 好处:允许一个对象在其内部状态发生改变时改变其行为。
- 策略模式(Strategy)
- 好处:定义一系列算法,把它们一个个封装起来,并使它们可互换。
- 模板方法模式(Template Method)
- 好处:在方法中定义算法的框架,延迟到子类中实现。
- 访问者模式(Visitor)
- 好处:为一个对象结构(如组合结构)增加新能力。
创建型模式
工厂方法
- 定义了一个用于创建对象的接口,但是让子类来决定哪一个类被实例化。
- 满足了开闭原则
优点:
- 工厂方法用来创建客户所需要的产品,同事还可向客户隐藏了哪些具体产品类将被实例化这一细节。
- 能够让工厂自主确定创建何种产品对象,而如何创建这个对象的细节则完全封装在具体工厂内部。
缺点:
- 增加了系统的抽象性和理解难度
- 系统中类的个数将成对增加,在一定程度上增加了系统的复杂度,会给系统带来一些额外的开销
简述在程序中运用工厂方法创建对象的好处?
- 降低了代码之间的耦合度
- 对客户隐藏了创建对象的细节,用户在使用类的时候,不需要知道具体的类
- 当需要扩展的代码的时候,可以在不需要修改用户代码的基础上,直接修改创建对象的逻辑。体现了开闭原则
- 具有更好的描述性,满足不同需求的对象创建
- 无需了解类的层次结构关系,隐藏了类型
抽象工厂
- 提供一个创建一系列相关或相互依赖对象的接口,而无需指定具体的类。
优点:
- 隔离了具体类的生成,使得客户端并不需要知道什么被创建
- 当一个产品族中的多个对象被设计成一起工作时,它能够保证客户端始终只使用同一个产品族中的对象
- 增加新的产品族很方便,无须修改已有系统,符合开闭原则
缺点:
- 增加新的产品登记结构麻烦,需要对原有系统进行较大的修改,甚至需要修改抽象层代码,这显然会带来较大的不便
原型模式
- 将原型实例化当做模板,拷贝原型模板并创建所需要的对象。
优点:
- 简化对象的创建过程,通过复制一个已经有实例可以提高新实例的创建效率
- 扩展性较好
缺点:
- 需要为每一个类配备一个克隆方法,而且该克隆方法位于一个类的内部,当对已有的类进行改造时,需要修改源代码,违背了开闭原则。
单例模式
确保一个类只有一个实例,并提供一个全局访问点。
饿汉式:直接实例化懒汉式:在声明的时候不赋值
优点:
- 可以节约系统资源,提高系统的性能
缺点:
- 扩展困难(缺少抽象层)
- 单例类的职责过重
将数据连接类DataAccesser作为单例模式来设计
public class DataAccesser {// 私有静态变量,保存类的唯一实例private static DataAccesser instance;// 私有构造函数,防止外部通过new创建实例private DataAccesser() {// 初始化代码}// 公共静态方法,提供全局访问点public static DataAccesser getInstance() {// 双重检查锁定模式,确保线程安全if (instance == null) {synchronized (DataAccesser.class) {if (instance == null) {instance = new DataAccesser();}}}return instance;}
}
生成器模式
- 切分复杂的对象创建过程,以至于能够使用相同的代码模版创建不同参数的对象。
生成器模式的适用性:
一般适用于我们定制好一个构造规则,然后我们在对象的创建过程中能够有多种创建的方式买哦中创建方式最后创建出来的对象都有可能不同。
结构性设计模式
适配器模式
- 将一个类的接口转换成客户希望的另一个接口,适配器模式让那些原本不兼容的类可以一起工作。
优点:
- 将目标类和适配器解耦
- 增加了类的透明性和复用性
- 灵活性和扩展性非常好
桥接模式
- 将抽象部分他的实现部分分离,使得两者都能独立变化。
优点:
- 分离抽象接口及其实现部分
- 可以取代多层基础方案,极大的减少了子类的个数
- 提高了系统的可扩展性
缺点:
- 会增加系统的理解与设计难度
组合模式
- 组合多个对象形成树形结构来表示具有部分-整体关系的层次结构。
优点:
- 可以清楚地定义分层次的复杂对象,表示对象的全部或部分层次,让客户端胡忽略层次的差异,方便对整个层次结构进行控制
- 客户端可以一致的使用一个组合结构或其中单个对象,不必关心处理的是单个对象还是整个组合结构,简化了客户端代码
- 增加新的容器构建和叶子构建都很方便,复合开闭原则
缺点:
- 在增加新构建时很难对容器中的构件类型进行限制
简述合成模式的适用场景,并列举出3个事例组合模式组合了多个对象的树形结构来表示具有部分——整体的关系层次结构,组合模式使得客户端把一个个单独的成分对象和由他们复合而成的合成对象同等看待。事例:资源管理器、Java GUI容器层次图、Dom4j
聚合强制器模式
确保了一个对象在创建后其各个组成部分的属性、对象非空。
装饰器模式
动态的给一个对象增加一些额外的职责- 在不改变一个对象本身功能的基础上给对象增加额外的新行为
优点:
- 对于扩展一个对象的功能,装饰器模式比继承更加灵活,不会导致类的个数急剧增加
- 可以通过一种动态的方式来扩展一个对象的功能,通过配置文件可以在运行时选择不同的具体装饰器类,从而实线不同的行为
- 可以对一个对象进行多次装饰
- 具体构建类与具体装饰类可以独立变化,用户可以根据需要增加新的具体构建类和具体装饰类,且原有类代码库无须改变,复合开闭原则
缺点:
- 使用装饰器模式进行系统设计将产生很多小对象,大量小对象的产生势必会占用根多的系统资源
- 比继承更加易于出错
装饰器模式的适用性:
这种模式一般是我们在不想新的增加特别多的子类的情况下使用,并且能够对原有的类进行功能的扩展,体现了开闭原则。
装饰器模式主要涉及到了哪些角色,各有什么作用?
抽象装饰类:他主要是提供一个装饰之前的调用,并且通过子类来对这个抽象装饰类进行扩展的操作,从而达到一个装饰的目的。具体装饰类:它是抽象装饰类的子类,每一个具体装饰类都可以定义新的行为方法,从而达到扩展的目的,复合开闭原则。
装饰器模式和继承的区别:
设计方式不同:
- 继承是一种静态的代码复用技术,通过创建子类来扩展或者修改父类的行为。
- 装饰器是一种动态的对象组合技术,通过组合对象来动态地扩展功能。
实现方式不同:
- 继承通过创建新的子类来实现,子类自动获得父类的所有属性和方法。子类可以通过重写父类的方法来改变行为。
- 装饰器模式通过创建装饰类来实现,装饰类包装一个组件对象。装饰类实现与组件相同的接口,并持有组件的实例,可以在调用组件方法前后添加额外的功能。
总之:继承是一种静态的代码复用方式,适合于固定的类层次结构。装饰器摸出差是一种动态的对象组合方式,适用于需要灵活扩展功能的场景。
外观模式
- 定义了一个高层接口,这个接口使得子系统更加容易使用
优点:
- 对客户端屏蔽了子系统组件,减少了客户端所需处理的对象数目,并使得子系统使用起来更加容易。
- 实现了子系统与客户端之间的松耦合关系,这使得子系统的变化不影响到调用他的客户端,只需要调整外观类即可。
- 子系统的内部变化不会影响到外观对象,一个子系统的修改对其他子系统也没有任何影响。
缺点:
- 不能很好的限制客户端直接使用子系统类,如果对客户端访问子系统类做太多的限制则会减少了可变性和灵活性
- 如果设计不当,增加新的子系统可能需要修改外观类的源代码,违背了开闭原则
代理模式
- 给某一个对象提供一个代理,并有代理对象来控制对原对象的访问
优点:
- 在一定程度上降低了系统的耦合度
- 客户端可以针对抽象主题解决进行编程,增加和更换代理类无须修改代码,符合开闭原则,系统具有较好的灵活性和可扩展性
缺点:
- 由于增加了代理对象,所有速度变慢
- 实线代理模式需要额外的工作,而且有些代理模式的实现过程较为复杂
享元模式
- 运用共享技术有效的支持大量细粒度的对象
行为型设计模式
访问者模式
- 声明一个访问操作接口,该接口中的每个操作元素对应一个需要访问的对象类的元素。具体访问者则实现了这些操作。
观察者模式
- 定义对象之间的一种一对多的依赖关系,使得每当一个对象状态发生改变时,其相关依赖对象都能得到通过并自动更新
优点:
- 松耦合
- 符合开闭原则
策略模式
- 定义一系列算法,将每一个算法封装起来,并让他们可以相互替换
优点:
- 符合开闭原则
- 提供了管理相关算法族的办法
缺点:
- 客户端必须知道所有的策略类,并自行决定使用哪一个策略
- 将造成系统产生很多具体的策略类
- 无法同时在客户端使用多个策略类
中介者模式
-
用于封装一组对象之间的交互,使其更加松散耦合。
命令模式
-
将请求动作封装为一个对象,以让使用者参数化执行不同的请求或记录请求甚至支持撤销操作
责任链模式
-
使用一种链式处理请求,直到有处理者正确处理了请求,以此降低请求和处理的耦合
状态模式
-
将状态和行为封装为一个对象,允许对象根据内部状态决定对象的行为。
备忘录模式
-
在不破坏类的封装的前提下,记录对象的内部状态
迭代器模式
-
提供一种方法顺序访问一个聚合对象中的各个元素,而又无须暴露该对象的内部表示。
模版方法
-
自定义算法结构,将具体的某一步操作委托给子类实线,子类可以修改算法的行为而不需要修改算法的结构。
解释器模式
-
将一个语言按照语法规则进行解释执行