java23种设计模式及其源代码演示实现

博主在CSDN已有三年,之前一直在看贴,受益颇多,不可多得的一个良好的学习平台,这一次,博主给大家分享一份传说中的java设计模式,源代码与其实现全部都有,希望有助于大家提高开发能力
全文代码全部手敲,不会存在侵权问题,纯原创
欢迎转载,但请附明出处
以下请欣赏全文:文字有点多,因为十分详细


java23种设计模式

1、设计模式是人们在面对同类型软件工程设计问题所总结出的一些有用经验。模式不是代码,而是某类问题的通用设计解决方案
2、4人组Erich Gamma、Richard Helm、Ralph Johnson、John Vlissides总结写了《设计模式》
3、设计模式的优点和用途
4、学习设计模式最好的方式:在你的设计和以往的工程里寻找何处可以使用它们
5、设计模式的本质目的是使软件工程在维护性、扩展性、变化性、复杂度方面成O(N)
6、OO是原则,设计模式是具体方法、工具

-------------------------------- 特别说明,以下案例皆是主类,将代码down下食用效果更佳! --------------------------------

类图图例:

Person1--eat() 代表Person类下面有一个eat() 方法1--eat(a,b,c) 代表Person类下面有一个eat方法,带3个参数1__name  __代表属性,Person下面有name属性-1__name __属性私有化1--Student  Person类下面有Student内部类2__name Student类下有name属性-->1--Student  Person类有子类Student,不在同一个文件2--run()  子类Student有run方法

策略模式01

1.分析项目中变化与不变部分
2.多用组合少用继承;用行为类组合,而不是行为的继承.更有弹性
案例:鸭子,不同种类的鸭子具有不同的组合行为
策略模式案例

观察者模式02

1.多对一的依赖关系,Subject
2.观察者注册,移除,通知
3.java内置观察者,Observable是类不是接口,不能多重继承,具体如下:
案例:天气预报项目,不同的公告板显示不同的公告内容
观察者模式案例
java内置观察者案例
传统模式案例
传统模式存在问题:一个需求新建一个变量,扩展性差,见传统模式

装饰者模式03

装饰者模式:动态的将新功能附加到对象上。在对象功能扩展方面,它比继承更有弹性。
对于源有的代码,不进行修改,维护方便

咖啡馆订单项目:传统面向对象开发,超类扩展,新调料,新单品,各自两两组合,类爆炸
new 单品() new Milk(order) …
装饰者模式案例
java内置装饰者案例

单例模式04

有些对象只需要一个:线程池,缓存,硬件设备等
如果多个实例会有造成冲突,结果的不一致性等问题
确保类只有一个实例,同时又有全局访问点

构造器私有化
多线程问题及优化
案例:巧克力工厂
单例模式案例

工厂模式05

pizza项目:有准备,烘焙,切割,打包4个步骤,要方便pizza品种的扩展,便于维护,运行同时也能扩展
传统模式:运行时,增加pizza品种,需要修改类,不满足运行同时扩展要求
传统模式案例

简单工厂模式:对象的实例化部分提取出来放入工厂类,满足了运行同时扩展要求
但仍然有些问题:店铺扩展,A地一个工厂 B地一个工厂…100个地方需要100个工厂,每个工厂的pizza种类文化均不同

public class SimplePizzaFactory {public Pizza CreatePizza(String ordertype) {Pizza pizza = null;if (ordertype.equals("cheese")) {pizza = new CheesePizza(); //多地工厂,B地pizza为CCPizza,则100个工厂需要100个不同的类} else if (ordertype.equals("greek")) {pizza = new GreekPizza();} else if (ordertype.equals("pepper")) {pizza = new PepperPizza();}return pizza;}
}

简单工厂模式案例

工厂方法模式设计方案:将pizza项目里的pizza对象实例化功能抽象成抽象方法,在不同加盟店具体实现功能

工厂方法模式案例

抽象工厂模式:定义了一个接口用于创建相关或有依赖关系的对象族,而无需明确指定具体类
工厂抽象成接口,指定工厂接入,子工厂与工厂无需在类里面直接修改代码增加变量,代码复用极高
依赖抽象原则:
1.变量不要持有具体类的引用
2.不要让类继承自具体类,要继承自抽象类或接口
3.不要覆盖基类中已实现的方法
抽象工厂模式案例

命令模式06

家电自动化遥控器API项目:背景:一个遥控器两排按钮,如图示:
● ○
● ○
● ○
● ○
● ○
左边●这一竖排自上而下分别控制灯,音响,增加音量…
右边○这一竖排自上而下分别控制关灯,关闭音响,减小音量…
要求自动化遥控器:扩展性好(当有新设备进来:扫地机器人,也接入该遥控器,要求极少量修改遥控器代码),维护性好

传统模式方案问题:当新设备进来,代码耦合度极高,维护困难
传统模式案例
传统模式存在的问题

命令模式:将请求,命令,动作等封装成对象,这样可以让项目使用这些对象来参数化其他对象.使得命令的请求者和执行者解耦
命令模式案例
宏命令,即一键功能

适配器模式07

插头与插座,汽车点烟器转usb充电器

火鸡冒充鸭子项目
背景:火鸡类,叫声AAA飞行:BBB 鸭子类叫声YYY,飞行FFF.调用适配器,使得某只火鸡调用适配器接口之后发出YYY叫声和FFF飞行

适配器模式:将一个类的接口转换成另一种接口,让原本接口不兼容的类可以兼容
从用户的角度看不到被适配者,是解耦的
用户调用适配器转化出来的目标接口方法
适配器调用被适配者的相关接口方法

类适配器:通过多重继承目标接口和被适配者类方式实现适配
目标

适配器

被适配者
多重继承,其中继承的目标接口部分达到适配目的,而继承被适配者类的部分达到通过调用被适配者类里的方法实现目标接口的功能

对象适配器和类适配器使用了不同的方法实现适配,对象适配器使用组合,类适配器使用继承

适配器模式案例

低版本java枚举器与高版本java迭代器适配案例

外观模式08

家庭影院项目:
如下案例,现在要看电影:步骤为,打开爆米花机->打开投影仪->放下屏幕->放好CD->拿爆米花->关闭爆米花机…
对象与对象之间没有关联,但必须同步方可进行事务
如果每一个设备都有各自的按钮,操作过程将极其繁琐
为此,引出外观模式:提供一个统一的接口,来访问子系统中一群功能相关接口
其定义了一个高层接口,让子系统更容易使用

与命令模式的区别:侧重点不一样:命令模式,将命令封装成对象,外观模式,将子系统功能暴露成为一个接口

外观模式案例

最少知识原则:尽量减少对象之间的交互,只留几个关系密切的对象,项目设计中不要让太多的类耦合在一起
如何遵循:1.对象方法调用范围,调用自己,作为参数传进来的对象,此方法创建合实例化的对象,对象的组件但方法返回值例外
最少知识原则Demo

模板模式09

咖啡和泡茶算法:
模板模式:封装了一个算法步骤,并允许子类为一个或多个步骤方法提供实现
模板模式可以使子类在不改变算法结构的情况下,重新定义算法中的某些步骤
钩子函数:超类里面定义,子类重写,若不重写,则调用钩子函数,若重写,调用子类重写的函数,实现各自功能
抽取完全相同的功能到超类案例
部分子类实现不同的功能案例
通用模板模式案例

好莱坞原则:别调用我们,我们会调用你. 高层无需知道调用底层细节,解耦
扩展性能和维护性能提高

与策略模式的差异:模板封装步骤,策略模式针对行为等功能进行组合,如鸭子会飞,会叫,会用一个接口对其进行组合.而模板模式:会叫之后再会飞,抽象方法,子类进行实现

迭代器模式10

餐厅菜单合并项目:有两个餐厅,蛋糕餐厅使用ArrayList维护菜单,中餐厅使用数组维护菜单,现两个餐厅需要合并为一个餐厅,菜单如何维护?

传统方案:每个餐厅自己的菜单,暴露出来给外部使用
存在问题:
1.扩展性能差,未来业务扩大,新增一个餐厅合并,该餐厅使用Hash表维护菜单,则必须新增类,暴露该hash菜单
2.耦合度增加:案例中女招待类打印菜单方法使用了暴露的菜单,所以该方法必须修改

详:
传统模式案例

迭代器模式:提供一种方法顺序访问一个聚合对象中的各个对象
1.使用迭代器模式,餐厅的增加不影响Waitress类的修改,解耦
2.餐厅未来修改菜单个数,仅需三方服务商修改其内部源码,直接调用迭代器接口即可,维护性强
迭代器模式案例

java内置迭代器:数组没有迭代器,自行实现.ArrayList有自己的迭代器,直接使用
现有一使用hash表管理菜单的咖啡馆合并入两家餐馆,使用java内置迭代器实现以上项目,详:
java内置迭代器

单一责任原则:一个类应该只有一个引起变化的原因

组合模式11

餐馆增加新需求:给菜单某一项添加子菜单
组合模式:将对象聚合成树形结构来表现"整体/部分"的层次结构
组合模式能让客户以一致的方式来处理个别对象(菜单项)以及对象组合(子菜单),忽略对象组合与>个体对象之间的差别

类结构如下:(最右边是超类)
Waitress                              <Abstract>1--CakeHouseMenu                   MenuComponent1--DinerMenu                      ---------------2--Item                           operation()2--Item                           print()2--SubMenu                        remove()3--Item3--Item3--Item1--CafeMenu2--Item2--Item2--Item

总结:餐厅合并之后,菜单含子菜单,总体菜单项如何进行遍历??
1.数据结构不一样如何放一起?
2.树形节点结构进行统一遍历
3.菜单,子菜单,菜单项目全部继承一个超类,即组合模式,整体和局部区别通过超类抹去,解耦,屏蔽内部实现
4.遍历:使用组合迭代器,巧妙利用堆栈遍历,获取菜单的同时又获取其迭代器,深层遍历
具体案例如下:

组合模式案例

状态模式12

项目:智能糖果机,用Java软件控制糖果机:待机,投入一元硬币,转动把手,滑落一颗糖果,
待机(根据机器内糖果库存情况,是否提示售罄)
糖果机根据状态的不同,行为结果就不同(如,没有塞入硬币转动把手不掉糖果一种结果和塞入硬币转动把手掉出糖果一种结果)

传统设计方案:一个状态对应一个动作,采用switch case 强行进行功能实现
则,如果公司增加新需求,加入游戏元素:有10%的概率可以拿到2粒糖果
1.增加一个新状态赢家状态,每一个动作的所有switch均要修改,修改开放,耦合大,维护难
2.基于接口开发,不应基于功能开发
传统模式案例

对于新需求,引入状态模式,如下:

糖果机项目,状态和动作之间的关系可以形成如下表格

                                insertCoin      returnCoin      turnCrank       dispense
OnReadyStateHasCoinSoldStateSoldOutStateWinnerState(新增需求,赢家状态)

面向接口进行开发,所有状态抽象成一个状态接口
类结构如下

interface State                                     <interface>1--WinnerState                                     State1--OnReadyState                                 insertCoin()1--HasCoin                                      returnCoin()1--SoldOutState                                 trunCrank()1--SoldState                                    dispense()

状态模式:根据内部状态的变化,改变对象的行为,看起来似乎修改了类

状态模式案例
策略模式一般情况下可以作为状态模式的基础,模板模式:部分拼接形成一个整体,状态模式:每一个状态都是整体

代理模式13

糖果机监控项目:你是公司上市老板:需要知道各个地方的糖果机运行情况,监控运行
首先,本地糖果机监控,只需要设计一个监控类,类里面放糖果机集合,实现监控情况即可,具体案例如下:
本地监控糖果机案例

好,现公司壮大,糖果卖得火爆,为进行市场分析,需要进行远程监控糖果机,如何实现?
由此引入代理监控方案–远程代理:远程对象(如其他地方糖果机)的本地代表(该糖果机的代表对象),通过它可以让远程对象当本地对象来调用
远程代理通过网络和真正的远程对象沟通信息:

Monitor <-> Agent ------------>Machine    Monitor访问Agent,Agent网络访问Machine,将结果返回给Monitor,相当于Monitor通过Agent代理,访问了Machine
Java RMI实现远程代理:Monitor <-> RMI STUB ------------> RMI SKELET <-> Machine

代理模式原理:为一个对象提供一个替身,控制对这个对象的访问

Java RMI:计算机之间通过网络实现对象调用的一种通讯机制
该机制可以让一台计算机上的对象可以调用另外一台计算机上的对象来获取远程数据

Java RMI 案例如下:

RMIHelloWord服务端
RMIHelloWord客户端

糖果机项目RMI服务端
糖果机项目RMI客户端

#####几种常见代理模式
虚拟代理:虚拟代理为创建开销大的对象提供代理服务,真正的对象在创建前和创建中时,由虚拟代理扮演替身,如:浏览网页在线图片加载
动态代理:运行时动态的创建代理类对象,并将方法调用转发到指定类
保护代理:看一个找对象项目,个人信息,兴趣爱好,打分,只可以访问部分等

使用 Proxy 类进行代理模式之保护代理设计:链接如下
权限设置保护代理案例

与装饰者模式的区别:装饰者模式,装饰之后会添加新功能;而代理模式是对目标对象访问的控制和管理

复合模式14

复合模式能解决一般性或一系列问题

复杂鸭子项目:
多种鸭子,不同鸭子叫声,飞行,游泳方式不同–策略模式
鹅,需要加入几只普通的鹅–适配器模式(用鸭子模拟鹅)
要统计鸭子叫声的次数–装饰者模式(动态的过程中增加新功能)
统一产生鸭子–工厂模式
管理一群鸭子–组合模式(迭代器)
追踪某个鸭子的行为–观察者模式(注册,反注册,通知)

MVC:模式与模式进行组合
MVC:Model,View,Controller
MVC解决什么类型的项目需求?
为什么采用MVC结构?
–结构复杂度降低,耦合度降低,不同部分独立升级

Model:程序主体,代表业务数据和业务逻辑
View:是与用户交互的界面,显示数据,接收输入但不参与实际业务逻辑
Controller:接收用户输入,并解析反馈给Model

MVC里的模式:
Model与View和Controller是观察者模式
View以组合模式管理控件(各种歌曲列表,弹窗等)
View与Controller是策略模式关系,Controller提供策略

以上很拗口,很难理解,以下作具体分析:

分析一个播放器软件
Model   播放器内部业务__Songs //属性,歌曲信息列表__State //属性,状态(按钮状态,播放状态,歌曲状态等)--start() //播放--pause() //暂停--stop() //停止--next() //下一首--previous() //上一首--getInfo() //获取歌曲信息View用户界面显示屏   按钮1,按钮2,按钮3,按钮4你好:这是一个Mp4图片,请自行想象Controller 策略,行为集,给按钮增加功能--Button1() --Button2()--Button3()--Button4()模拟:用户按下了按钮3,想要切换下一首歌1.通过Controller解析出来该按钮的功能为切换下一首歌曲2.调用业务逻辑,Model.next()方法被调用,采用观察者模式通知View,信息变了,View采取相应措施3.歌曲播放完毕,Model观察者通知View歌曲结束,View相应进行响应,比如弹出一个窗口,歌曲播放完毕或者自动播放下一首歌等4.3这个也可以让Model通知Controller,具体业务具体分析

Android App就是一个很典型的例子–>
生命周期–模板模式
整体上是MVC
电池电量,观察者
列表,模板

桥接模式15

桥接目的,分离抽象与实现,使抽象和实现可以独立变化
系统多维度角度分类,而每一种分类又有可能变化,考虑使用桥接模式

遥控器项目:索尼公司遥控器,厂家提供接口,遥控器调用接口实现遥控各种家电
极简设计方案:类图如下:

<interface Control>--On()--Off()--setChannel() //设置频道--setVolume() //设置音量SonyControl implements Control 实现各自方法--On()--Off()--setChannel()--setVolume()
LGControl implements Control  实现各自方法--On()--Off()--setChannel()--setVolume()现有一TvControl想对Sony和LG进行控制,则有SonyTvControl和LGTvControl两个类

极简设计方案

该方案存在问题:新需求带来的设计问题,电视机厂家,新功能的遥控器出来,则新遥控器重新继承每一个类,类爆炸

桥接模式:将实现与抽象放在两个不同的类层次重,使两个层次可以独立改变
类图如下:

<abstract>
TvControlabs1__Control mControl __代表属性1--Onoff()          -- 代表方法1--nextChannel()1--preChannel()-->2\\TvControl \\代表类 -->代表子类,不属于同一个文件3--Onoff()3--nextChannel()3--preChannel()-->2\\newTvControl  3--Onoff()3--nextChannel()3--preChannel()3--setChannel()3--Back()mControl∈ 属于<interface>    Control1--On()1--Off()1--setChannel()1--setVolume()-->1\\SonyControl -->代表子类,但不属于同一个文件2--On()2--Off()2--setChannel()2--setVolume()-->1\\LGControl-->1\\SharpControl

桥接模式案例

生成器模式16

生成器模式:

将复杂对象创建过程封装
隐藏类的内部结构
允许对象通过几个步骤创建,并且可以改变工程(工厂模式只有一个步骤)

度假计划项目:有3天度假计划,4天度假计划(每个计划都是不同对象),如何生成?使用生成器模式:
生成器模式:封装一个复杂对象构造过程,并允许按步骤构造
具体案例:生成器模式案例

省略抽象生成器类
省略指导者类

与抽象工厂的差异:主要用于创建复杂,大的对象

责任链模式17

购买请求决策项目:决策因素:价格
决策级别:组长,部长,副总,总裁
考虑扩展性
如果多个对象都有机会处理请求,责任链可使请求的发送者和接受者解耦,请求沿着责任链传递,直到有一个对象处理了它为止.
该模式简化了对象,因为无须知道链结构
该模式可以动态增加或删减处理请求的链结构
该模式请求从链开头进行遍历,对性能有一定损耗
该模式并不一定保证请求被处理

项目类图如下:

PurchaseRequest->A类(请求没处理,抛!)->B类(请求没处理,抛!)->C类(请求没处理,抛!)->D类(请求被处理)

责任链模式案例
适用于:有多个对象可以处理一个请求,不明确接收者情况

与状态模式的差异:责任链,注重请求的传递,状态模式,注重对象状态的转换

蝇量模式18

景观设计软件项目:
树:XY坐标,树的大小,外观,需要很多树;1000W棵树,需要对象Tree 1000W 个,小对象大量级的问题解决

传统方案设计:传统模式

分析:

Tree1__xCoord1__yCoord1__age1--display()
1000W个Tree对象实在太多,影响性能,该如何做?引入蝇量模式TreeManager1__xArray1__yArray1__AgeArray1--displayTrees()Tree1--display()

蝇量模式案例1

蝇量模式:通过共享的方式高效地支持大量细粒度的对象,适用于大量细粒度对象(上千万),且这些对象的外部状态不多
优缺点分析:
优点:
–减少运行时对象实例个数,节省创建开销和内存
–许多虚拟对象状态集中管理
缺点:
–系统设计更加复杂
–专门维护对象外部状态

项目有新需求:增加一些草 类图如下:

PlantFactory1--getPlant()  (PlantManager、Plant类通过该方法显示具体结果)PlantManager1__xArray1__yArray1__AgeArray1__typeArray1--displayTrees() -> Plant.display()<abstract> Plant1--display()-->1\\Grass2--display()-->1\\Tree2--display()

如何才能实现内存最佳化利用??
引入草对象按蝇量模式设计案例2

解释器模式19

大数据统计项目:按照计算模型对现有数据统计,分析,预测,计算模型需要运行期编辑,如何设计??写函数,写sql?
最好能有一个通用方案,各部门都能通用,维护也方便,扩展也方便,引入解释器模式:
解释器模式:计算模型按正常算式方式书写,解释器处理语法逻辑;定义一个语法,定义一个解释器,该解释器处理该语法句子

计算模式里有两类符号:数据和计算符(±*/语法规则,优先级等)
逆波兰算法分析算式语法
用解释器模式处理数据

优点:
–容易修改,修改语法规则只要修改相应非终结符即可
–扩展方便,扩展语法,增加非终结符类即可
缺点:
–复杂语法,类结构巨复杂,不便管理和维护,尽量不要在重要的模块中使用
–采用递归方式,效率会受影响

可以仅作了解:实际系统开发中使用的非常少
使用场合:数据分析工具,报表设计工具,科学计算工具

原理类图如下:将某些复杂问题,表达为某种语法规则,然后构建解释器解释处理这类句子

用户Client发出一个算式Context,定义解释器:
AbstractExpression1--Interpret(Context)-->1\\TerminalExpression  子类2--Interpret(Context)-->1\\NoterminalExpression  子类2--Interpret(Context)

回到大数据统计项目,该项目采用解释器模式进行:类图如下

<abstract>
AbstractExpresstion1--Interpret()-->1--VarExpresstion 变量表达式子类2--Interpret()-->1--SymbolExpresstion 符号表达式子类2--Interpret()-->2--AddExpresstion +3--Interpret()-->2--SubExpresstion -3--Interpret()-->2--MutilExpresstion *3--Interpret()-->2--DivExpresstion /3--Interpret()

解释器模式案例

中介者模式20

中介者模式,用一个中介对象来封装一系列的对象交互
中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互

优点:

–彼此解耦对象,增加对象复用
–控制逻辑集中,简化系统维护
–对象之间传递消息变得简单而且大幅减少
–提高系统灵活,易于扩展和维护

缺点:

–中介是中心,出现问题则会影响整个系统
–中介者本身对象可能会变得过于复杂源于设计不当

智慧房屋项目:公司专业生产各种房子,房子里有智慧闹钟,咖啡机,电视机,窗帘等,实现以下需求
某一时刻,闹钟响起,咖啡机自动泡咖啡,同时自动打开电视机,等待咖啡机泡咖啡结束窗帘自动落下,房间灯自动亮起…
传统设计逻辑:Alarm—1号,TV—2号,CoffeeMachine—3号,Curtains—4号
1给2,3发消息,3给2,4发消息…
对象之间耦合性过强,扩展复用性能差,维护难,不好调试

中介者模式:引入一个中介,Mediator,对象之间省去互相沟通,各对象仅与中介沟通,由中介对结果进行反馈
逻辑:1–中介,2–中介,3–中介,4–中介,中介–1,2,3,4

中介者模式案例

中介者模式与观察者模式:观察者模式广播,中介者定向

适用场合:一组对象之间通信方式比较复杂,导致相互依赖,结构混乱;一个对象引用许多其他对象并直接与这些对象通信,导致难以复用该对象

备忘录模式21

备忘录模式:在不破坏封装的前提下,存储关键对象的重要状态,从而可以把对象还原到存储的那个状态
游戏项目:游戏进度状态保存问题.对象状态,场景状态,大型项目,每个人开发自己的保存功能,这个效率将十分低
引入备忘录模式:统一功能,每一个人开发的保存功能用一个类进行管理,设计MemetoIF接口,别人开发的细节自己将看不到,保证信息安全

优点:

–状态存储在外面,不和关键对象混一起,可以帮助维护内聚
–提供容易实现的恢复能力
–保持关键对象的数据封装

缺点:

–资源消耗上面备忘录对象会很昂贵
–存储和还原比较耗时

场合:必须保存一个对象在某一个时刻的整体或部分状态,在对象以外的地方进行恢复

备忘录模式案例

原型模式22

电子账单项目:银行的电子账单,广告信,特点,量大,时间要求紧
传统设计模式案例
问题来了:500万用户发送邮件,一封邮件0.1s发出,需要50Ws…6天!

那么解决方案:SendMail多线程并发进行,需要在每一封邮件发送前新创建对象,每次new,内存资源浪费
引入原型模式:一个对象,通过内存复制创建新一模一样对象,该对象指向其他内存区域,无须知道相应类的信息
优点:

–使用原型模式创建对象比直接new一个对象更有效
–隐藏制造新实例复杂性
–重复创建相似对象时可以考虑使用

缺点

–深层复制比较复杂
–每一个类必须配备一个克隆方法

注意事项:

1.使用原型模式复制对象不会调用类的构造方法!!!所以单例模式与原型模式是冲突的
2.final 对象由于不能改动(其内存空间固定),故采用原型模式的类无法使用final声明的对象
3.Object类的clone方法只会拷贝对象中的基本数据类型,对于数组,容器,引用对象等都不会拷贝,这就是浅拷贝
4.实现深拷贝必须将原型模式中的数组,容器对象,引用对象等另外拷贝

原型模式案例深拷贝
适用场合:

1.复制对象结构和数据
2.希望对目标对象的修改不影响既有的原型对象
3.创建对象成本较大的情况下

访问者模式23

雇员管理系统项目:Employee,需要添加一些新的操作功能,具体案例如下:
传统模式案例 违背开闭原则

访问者模式:对于一群对象,在不改变数据结构的前提下,增加作用于这些结构元素新的功能,适用于数据结构相对稳定,
数据结构和作用于其上的操作解耦,使得操作集合可以相对自由地演化

优点:

1.一个访问者一个功能,符合单一职责原则
2.扩展性良好
3.有益于系统的管理和维护

缺点:

1.增加新的元素类变得很困难,修改算法
2.破坏封装性

访问者模式案例

注意事项:

1.系统有比较稳定的数据结构
2.与迭代器的关系:迭代器提供访问者注入的一种方式,访问者对对象进行处理

适用场合:数据结构比较稳定,需求又经常变化,那么访问者模式比较适合

写在最后:

模式:在某些场景下,针对某类问题的某种通用解决方案,其中,场景是项目环境,问题是约束条件,项目目标;解决方案:通用可以复用的设计,解决约束达到目标
(实际经验的总结)
设计模式的三个分类--创建型模式:对象实例化的模式,解耦了对象的实例化过程--结构型模式:把类或对象结合一起形成更大的结构--行为型模式:类和对象如何交互,及划分责任和算法

简单工厂:一个工厂类根据传入的参量决定创建出哪一种产品类的实例
工厂方法:定义一个创建对象的接口,让子类决定实例化哪一个类
抽象工厂:创建相关或依赖对象的家族,而无需明确指定具体类
单例模式:类只有一个实例,提供一个全局访问点
生成器模式:封装一个复杂对象的构建过程,可以按步骤构造
原型模式:通过复制现有的实例来创建新的实例
适配器模式:将一个类的方法接口转换成客户希望的另外一个接口
组合模式:将对象组合成树形结构以表示"部分-整体"的层次结构
装饰模式:动态地给对象添加新的功能
代理模式:为其他对象提供一个代理以控制对这个对象的访问
蝇量模式:通过共享技术有效地支持大量细粒度的对象
外观模式:提供统一的方法来访问子系统的一群接口
桥接模式:将抽象部分与它的实现部分分离,使它们都可以独立地变化
模板模式:定义一个算法结构,而将一些步骤延迟到子类中实现
解释器模式:给定一个语言,定义它的文法的一种表示,并定义一个解释器
策略模式:定义一系列的算法,把它们封装起来,并且使它们可相互替换
状态模式:允许一个对象在其内部状态改变时改变它的行为
观测者模式:对象间的一对多的依赖关系
备忘录模式:在不破坏封装性的前提下,保存对象的内部状态
中介者模式:用一个中介对象来封装一系列的对象交互
命令模式:将命令请求封装为一个对象,使得可用不同的请求来进行参数化
访问者模式:在不改变数据结构的前提下,增加作用于一组对象元素新的功能
责任链:请求发送者和接收者之间解耦,使得多个对象都有机会处理这个请求
迭代器:一种遍历访问聚合对象中各个元素的方法,不暴露该对象的内部结构

对象设计的六大原则:
组合复用原则:多用组合,少用继承,找到变化部分,抽象,封装变化(has A 与 is A).鸭子项目01

依赖倒置原则:

依赖:成员变量,方法参数,返回值,依赖于抽象,不要依赖于具体
高层模块不应该依赖低层,且都应该依赖其抽象
具体应该依赖抽象,抽象不应该依赖具体
针对接口编程,不要针对实现编程
项目架构:以抽象为基础搭建

开闭原则:对扩展开放,对修改关闭,通过扩展已有软件系统,提供新功能,对修改的关闭,保证稳定性和延续性

里氏替换原则:

引用基类的地方必须能透明地使用其子类对象
子类扩展父类功能,不能破坏父类原有的功能
设计继承,子类可以实现父类的抽象方法,但不能覆盖父类的非抽象方法
子类重载父类方法,方法的形参要比父类方法的参数更宽松
子类实现父类抽象方法,方法的返回值要比父类更严格

迪米特法则:

一个对象应该与其他对象保持最少了解尽量降低类与类之间的耦合

接口隔离原则:一个类对另一个类的依赖应该建立在最小的接口上

单一职责原则:实际工作中很难达到,即一个类只负责一项职责

用模式来思考:
保持简单:

尽可能用最简单的方式解决问题

设计模式非万能:

模式是通用问题的经验总结
考虑它对其他部分影响
不需要预留任何弹性时,删除掉模式

何时需要模式:

设计中会变化的部分,通常就是需要考虑模式的地方
重构时,带进模式

重构的时间就是模式的时间:

利用模式来重构

java设计模式:23种设计模式及其源代码演示实现相关推荐

  1. java 的23种设计模式 之单身狗和隔壁老王的故事

    2019独角兽企业重金招聘Python工程师标准>>> 觉得代码写的别扭了,回头翻翻java 的23种设计模式. today,额,这么晚了,困了.就弄个最简单的单例模式吧. 单例模式 ...

  2. 经典:从追MM谈Java的23种设计模式

    2019独角兽企业重金招聘Python工程师标准>>> 从追MM谈Java的23种设计模式1.FACTORY-追MM少不了请吃饭了,麦当劳的鸡翅和肯德基的鸡翅都是MM爱吃的东西,虽然 ...

  3. 从追MM谈Java的23种设计模式

    设计模式做为程序员的"内功心法",越来越受到.net 社区的重视,这种变化是很可喜的,Java社区走在了我们的前面,但这种状况 也许有一天会发生改变. {虽然有点长,但是相信相当经 ...

  4. Java进阶 23种设计模式 详解+应用+实例代码

    文章目录 前言 设计模式六大原则 1.单一原则 (1) 概念 (2) 优点 2.开闭原则 (1) 概念 3.里氏替换原则 (1) 概念 4.依赖倒置原则 (1) 概念 (2) 作用 5.接口隔离原则 ...

  5. 备战面试日记(3.3) - (设计模式.23种设计模式之结构型模式)

    本人本科毕业,21届毕业生,一年工作经验,简历专业技能如下,现根据简历,并根据所学知识复习准备面试. 记录日期:2022.1.9 大部分知识点只做大致介绍,具体内容根据推荐博文链接进行详细复习. 文章 ...

  6. 备战面试日记(3.4) - (设计模式.23种设计模式之行为型模式)

    本人本科毕业,21届毕业生,一年工作经验,简历专业技能如下,现根据简历,并根据所学知识复习准备面试. 记录日期:2022.1.12 大部分知识点只做大致介绍,具体内容根据推荐博文链接进行详细复习. 文 ...

  7. 备战面试日记(3.2) - (设计模式.23种设计模式之创建型模式)

    本人本科毕业,21届毕业生,一年工作经验,简历专业技能如下,现根据简历,并根据所学知识复习准备面试. 记录日期:2022.1.6 大部分知识点只做大致介绍,具体内容根据推荐博文链接进行详细复习. 文章 ...

  8. Java中23种设计模式(随时不定时更新)

    一.创建型模式 1.单例模式(Singleton Pattern) 单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一.这种模式涉及到一个单一的类,该类负责创建自己的对 ...

  9. java与23种设计模式

    1 23种设计模式分类 经典的<设计模式>一书归纳出23种设计模式,本文按<易学设计模式>一书归纳分类如下: 1.创建型模式 前面讲过,社会化的分工越来越细,自然在软件设计方面 ...

  10. java 的23种设计模式 单例模式

    23种设计模式友情链接: 点击打开链接 单例模式: A.饿汉式单例模式 具体步骤: 1.声明一个私有的静态的最终的本类类型的对象并实例化 private static final Person ins ...

最新文章

  1. java i18n 转换,Java的国际化支持(I18N问题)
  2. MobileNet Unet
  3. python 学习总结6 前端学习2
  4. C语言解决汉诺塔问题
  5. Cookie 解说(分类、用途、缺陷、功能 ...)
  6. 微软为 Chromium 版 Edge 浏览器推出新的 logo
  7. 华为哪个是鸿蒙,华为系统是鸿蒙还是安卓?有什么区别
  8. SQL Server 连接查询(内连接查询)
  9. 系统Model底层隐藏的坑
  10. 【eevee.cc】文章归档
  11. 关于不过洋节的通知_南阳市第十二小学关于禁止过洋节及规范节日文化的通知...
  12. Atitit Atitit 零食erp数据管理---世界著名零食系列数据.docx世界著名零食
  13. 怎么卸载虚拟机中的mysql_虚拟机卸载mysql数据库
  14. UG NX10.0软件安装教程
  15. Qt之QListView的简单使用(含源码+注释)
  16. SolrCloud 初体验
  17. Mysql(3):事务、锁及锁级别
  18. windows 定时任务:schtasks,定时关闭网易云音乐
  19. python怎么读取石墨表格_石墨这种多人文档编辑协作如何用开源软件实现?
  20. 计算机考博方向数学,2016华中科技大学考博:计算机数学考试大纲

热门文章

  1. 时序因果分析算法(THP)学习与代码分析
  2. 涂鸦智能CFO刘尧:谁说高速发展的创新型企业就不能用SAP?
  3. 计算机基础知识图谱,基于知识图谱的大学计算机基础习题推荐方法技术
  4. 如何定制手机QQ空间的小尾巴
  5. Python安装与卸载流程
  6. 萌新浅谈DHCP以及ospf
  7. Cream Finance 重入漏洞事件分析
  8. 全球与中国琴键式拨码开关市场现状及未来发展趋势
  9. VPC NAT(SANT,NANT)实验
  10. 项目_MySQL比较字符大小的小坑