java设计模式
2019-08-05 11:21:21 136 举报
AI智能生成
Java设计模式是一种解决软件设计问题的优秀经验总结,它为开发人员提供了一套被广泛认可的解决方案。这些模式分为三大类:创建型、结构型和行为型。创建型模式关注对象的创建过程,如单例模式、工厂方法模式等;结构型模式关注对象的组合和关系,如适配器模式、代理模式等;行为型模式关注对象之间的交互,如观察者模式、策略模式等。通过使用这些设计模式,开发人员可以提高代码的可读性、可维护性和可扩展性,从而更好地应对软件设计和开发中的挑战。
作者其他创作
大纲/内容
常见的面向对象原则
单一职责原则SRP
开放-关闭原则OCP <br>
里氏替换原则LSP <br>
依赖倒置DIP<br>
接口隔离原则ISP
最少知识原则LKP<br>
面向接口编程<br>
优先使用组合,而非继承<br>
一个类需要的数据应该隐藏在类的内部
类之间应该零耦合或者只有传导耦合,换句话说,类之间要么没有关系,要么只使用另一个类的接口提供的操作
在水平方向上尽可能统一地分布系统功能
策略模式
定义
代码实现
Strategy
ConcreteStrategyA
ConcreteStrategyB
Context
功能
策略模式和if-else语句<br>
算法的平等性<br>
Context和Strategy的关系
优点<br>
定义一系列算法
避免多重条件语句
更好的扩展性
缺点
客户必须了解每种策略的不同
增加对象数目<br>
只适合扁平的算法结构
策略模式的本质<br>
<b>分离算法,选择实现</b>
对设计原则的体现
<b>开闭原则</b>
<b>里氏替换原则</b>
何时选用策略模式
模板方法模式<br>
定义
代码实现
AbstractClass
ConcreteClass
模板方法模式的功能<br>
抽象类和接口的关系<br>
接口是一种特殊的抽象类,所有接口的属性自动是常量,也就是public final static 的,而所有接口中方法必须是抽象的<br>
<font color="#c41230"><b>抽象类,</b></font>简单点就是用abstract修饰的类。<font color="#c41230"><b>抽象类不一定包含抽象方法,有抽象方法的类一定是抽象类</b></font>
抽象类和接口相比较,最大的特点就在于<font color="#c41230"><b>抽象类</b></font>中是可以有具体的实现方法的,而<font color="#c41230"><b>接口</b></font>中所有的方法是没有具体的实现的
<b><font color="#c41230">既要约束子类的行为,又要为子类提供公共功能的时候使用抽象类</font></b>
变与不变<br>
好莱坞法则
模板的写法
模板方法<br>
定义算法骨架的方法
具体的操作
具体的AbstractClass操作<br>
原语操作<br>
钩子操作
Factory Method<br>
完整的模板定义<br>
典型应用<br>
排序 <br>
优点<br>
实现代码复用<br>
缺点
算法骨架不容易固定<br>
本质
固定算法骨架
对设原则的体现
开闭原则
里氏替换原则
何时选用模板方法模式
需要固定定义 算法骨架,实现一个算法的不变的部分,把可变的行为留给子类 来 实现的情况<br>
各个子类中具有公共行为,应该抽取出来,集中在一个公共类中去实现,从而避免代码重复
需要控制子类扩展情况,模板方法模式会在特定的点来调用子类的方法,这样只允许在这些点进行扩展
观察者模式
定义
代码实现<br>
Subject
ConcreteSubject
Observer
ConcreteObserver
目标与观察者之间的关系<br>
命名建议<br>
触发通知的时机<br>
java 中的观察者模式<br>
本质
<font color="#c41230"><b>触发联动</b></font>
何时选用观察者模式
原型模式
定义
代码示例
Prototype
ConcretePrototype1
ConcretePrototype2
Client
原型模式的功能<br>
通过克隆来创建新的对象实例<br>
为克隆出来的新的对象实例复制原型实例属性的值
原型与new
浅度克隆<br>
只负责克隆按值传递的数据(比如基本数据类型、String类型)<br>
java浅度克隆<br>
深度克隆
除了浅度克隆要克隆的值外,还负责克隆引用类型的数据,基本上就是被克隆的实例所有的属性数据都会被克隆出来
java中的深度克隆<br>
本质<br>
克隆生成对象
单例模式
实现方式<br>
懒汉式
饿汉式
双重加锁<br>
静态内部类<br>
枚举<br>
本质<br>
控制实例数目
何时使用单例模式
代理模式<br>
定义
代码实现
Subject
RealSubject
Proxy
代理分类<br>
虚代理
远程代理
copy-on-write
保护代理<br>
Cache代理
防火墙代理
同步代理
智能指引<br>
java中的代理<br>
Proxy<br>
InvocationHandler
本质
控制对象访问
桥接模式
定义<br>
将抽象部分和它的实现部分分离,使他们可以独立的变化<br>
什么是桥接:<br>
为被分离了的抽象部分和实现部分来搭桥
为何需要桥接
让抽象部分和实现部分分开
如何桥接?
让抽象部分拥有实现部分的接口对象
独立变化
使得抽象和实现可以独立变化,都可以分别扩充<br>
动态变化功能
由于桥接模式中的抽象部分和实现部分是完全分离的,因此可以在运行时动态组合具体的真实实现,从而达到动态变换功能的目的。
本质
分离抽象和实现
对设计原则的体现
开闭原则
多用对象组合,少用对象继承
实现代码<br>
Abstacction
RefinedAbstraction
Implementor
ConcreteImplImplementorA
ConcreteImplImplementorB
简单工厂
接口
接口的概念<br>
接口是一种特殊的抽象类,接口中的所有方法都是抽象方法,接口里的属性都是常量,接口里只有方法定义没有任何方法实现
接口用来干什么
定义实现类的外观<br>
约束实现类的 行为<br>
接口的思想
封装隔离<br>
接口的好处<br>
接口是系统可插拔性的保证<br>
接口和抽象类的选择
优先选用接口<br>
在既要定义子类的行为,又要为子类提供公共的功能时应选择抽象类
定义
提供一个创建对象实例的功能,而无须关心 其具体实现。被创建的类型可以是接口、抽象类,也可以是具体类<br>
命名建议
类名称建议"模块名称+Factory"<br>
方法名称通常为"get+接口名称"或者是"create+接口名称"<br>
工厂选择 合适的类<br>
来源于客户端,由Client来传入参数
来源于配置文件,从配置文件获取用于判断的值
来源于程序运行期的某个值,比如从缓存中获取某个运行期的值<br>
优点
帮助封装<br>
解耦:实现客户端和具体实现类的解耦
缺点
可能增加客户端的复杂度<br>
不方便扩展子工厂
本质<br>
选择实现<br>
何时选用简单工厂
完全封装隔离具体实现,让外部只能通过接口来操作封装体
想要把对创建对象的职责集中管理和控制
代码实现
Api
ImplA
ImplB
Factory
Client
外观模式
定义<br>
为子系统中的一组接口提供一个一致的界面,Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用
角色<br>
Facade
定义子系统的多个模块对外的高层接口,通常需要调用内部多个模块,从而把客户的请求代理给适当的子系统对象<br>
模块
接受Facade对象的委派,真正实现功能,各个模块之间可能有交互<br>
Facade对象知道各个模块,各个模块不应该知道Facade对象。
代码实现<br>
AModuleApi
AModuleApiImpl
Facade
Client
优点<br>
松散耦合
简单易用<br>
更好地划分访问的层次 <br>
外观模式的本质<br>
封装交互,简化调用
对设计原则的体现
最少知识原则
职责链模式
定义<br>
使多个对象都有机会处理请求,从而避免请求的发送者和 接收者之间的耦合关系,将这些对象连接成一条链,并沿着这条 链传递该请求,直达有一个对象处理它<br>
代码实现
Handler
ConcreteHandler1
ConcreteHandler2
Client
如何构建链<br>
可以实现在客户端提交请求前组合链
在 Handler里面实现链的组合<br>
在各个职责对象中,由各个职责对象自行决定后续的处理对象。这种实现方式要求每个职责对象除了进行功能业务处理 外,还必须了解整个业务流程<br>
按照以下顺序来组合连的数据<br>
在程序中动态组合
通过外部组合,比如通过数据库来获取组合的数据<br>
通过配置文件传递进来,也可以是流程的配置文件
本质
分离职责、动态组合
状态模式
定义<br>
允许一个对象在其内部状态改变时 改变它的行为。对象看起来似乎修改了它的类<br>
状态和行为<br>
对象的状态
通常指的就是对象实例的属性的值<br>
行为
对象的功能。行为大多可以对应到方法上
状态转换的维护<br>
如果状态转换的规则是一定的,一般不需要进行什么扩展规则,那么就适合在上下文中统一进行 状态的维护<br>
如果状态的转换取决于前一个状态动态处理的结果,或者是依赖于外部数据,为了增强灵活性,这种情况下,一般是 在状态处理类中进行状态的维护<br>
代码实现<br>
State<br>
ConcreteStateA<br>
ConcreteStateB
Context
请假流程
1、申请人填写请假单,提出请假申请后,请假单的状态是等待项目经理审核状态
2、当项目项目经理完成审核巩工作,提交保存后,如果项目经理不同意,请假单的状态是审核结束状态;如果项目经理同意,请假天数又在3天以内,请假单的状态是审核技术状态;如果项目经理同意,请假天数大于3天,请假单的状态是等待部门经理审核状态。
当部门经理完成审核工作,提交保存后,无论是否同意,请假单的状态都是审核结束状态,
代码实现
StateMachine
LeaveRequestContext
State
ProjectManagerState
DepManagerState
AudioOverState
LeaveRequestModel
Client
优点<br>
简化应用逻辑控制
更好地分离状态和行为
更好的扩展性
显式化进行状态转换<br>
缺点<br>
一个状态对应一个类,会造成有很多状态类
本质
根据状态来分离和选择行为<br>
适配器模式
工厂方法<br>
定义
定义一个用于创建对象的借口,让子类决定实例化哪一个类,Factory Method使一个类的实例化延迟到子类<br>
模式的结构和说明
<b>Product:</b>定义工厂方法所创建的对象的接口,也就是实际需要使用的对象的接口
<b>ConcreteProduct</b>:具体的Product接口的实现对象
<b>Creator:</b>创建器,声明工厂方法,工厂方法通常会返回一个Product类的实例对象,而且多是抽象方法,
<b>ConcreteCreator:</b>具体的创建器对象,覆盖实现Creator定义的工厂方法,返回具体的Product实例
代码实现
Product
ConcreteProduct
Creator
ConcreteCreator
功能<br>
让父类不知道具体实现的情况下,完成自身的功能调用,而具体的实现延迟到子类来实现
工厂方法模式与IOC/DI <br>
IOC-Inversion of Control,控制反转<br>
依赖:谁依赖于谁?为什么需要依赖?<br>
某个对象依赖Ioc/DI容器<br>
注入:谁注入于谁?到底注入什么
控制反转:谁控制谁?控制什么、为何叫反转?
依赖注入和控制反转是同一概念吗
参与者都有谁
DI-Dependency Injection, 以来注入<br>
参与者都有谁
某个对象
Ioc/DI 的容器<br>
某个对象的外部资源
谁依赖谁<br>
某个对象依赖于Ioc/DI的容器
为什么需要依赖
对象需要Ioc/DI的容器来提供对象需要的外部资源<br>
谁注入于谁
很明显是Ioc/DI容器注入某个对象
到底注入什么
就是注入某个对象所需要的外部资源
谁控制谁
Ioc/DI的容器来控制对象
控制什么
主要是控制对象实例的创建
什么反转<br>
依赖的类依靠容器去注入
依赖和控制反转是统一概念吗
依赖注入
应用程序依赖容器创建并注入它所需要的外部资源
控制反转
容器控制应用程序,由容器反向地向应用程序注入其所需要的外部资源
本质
延迟到子类来选择实现<br>
何时选用工厂方法模式<br>
如果一个类需要创建某个接口的对象,但是又不知道具体的实现,这种情况可以选用选用工厂方法模式,把创建对象的工作延迟到子类中去实现。<br>
如果一个类希望由他的子类来创建所需的对象的时候,应该使用工厂方法模式
抽象工厂模式
生成器模式<br>
定义<br>
将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示<br>
功能
构建复杂的产品,而且是细化的、分步骤的的构建产品,也就是生成器模式一步一步构造复杂独享的问题
构成
Builder
定义了如何构建各个部件,也就是知道每个部件功能如何实现,以及如何装配到这些部件到产品中去<br>
Direct
知道如何来构建产品,也就是说Director负责整体的构建算法,而且通常是分步骤来执行<br>
生成器模式构建负责对象
0 条评论
下一页
为你推荐
查看更多