一文掌握设计模式(定义+UML类图+应用)
从学编程一开始就被告知,要想做一名优秀的程序员两大必要技能:1.源码阅读(JDK、C等底层语言封装) 2.设计模式(使用某种语言优雅的落地典型场景功能)。一般随着工作年限的增长,被迫对底层语言/框架源码阅读的越来愈多,但是设计模式如不刻意去学习,永远不会真正掌握。笔者把设计模式比喻成程序员的“绝世神功”,掌握了设计模式,对快速阅读源码、优雅地编写程序有极大的促进作用,可以说就像打通了任督二脉一样。
1.1 设计模式由来1995年,GoF(Gang of Four四人帮)合作出版了《设计模式:可复用面向对象软件的基础》(Design Patterns – Elements of Reusable Object-Oriented Software) 一书,书中总结了23种面向对象设计模式,也就是大名鼎鼎的GOF设计模式。
1.2 23种 VS 24种一直听说有24种设计模式(网上一大堆标题24种设计模式,然后列举的只有23种,也是无语),公认的GOF只有23种,还有一种是啥?大部分文章都说是简单工厂模式(Simple Factory)。笔者搜遍全网(连chatGPT也问了),没找到第24种设计模式谁提出的。这第24种设计模式,有说是简单工厂模式,也有说是静态工厂模式,也有说简单工厂模式=静态工厂模式,真是一塌糊涂,乱七八糟。神奇的是这些文章的作者都没深究过这个问题,估计大都是拿来主义。
【资料图】
到底几种?
---23种!!!即GOF的23种设计模式即可。还有2个模式:简单工厂、静态工厂,确实在后续应用比较多,但在1995年未列入GOF。
二、知识预备想要练成绝世武功,内功心法和外家套路缺一不可。要想练成“设计模式”这一绝世武功,“面向对象设计原则”就是内功心法(遵循的设计原则),“UML统一建模语言”就是外家套路(代码落地建模工具)。练功之前,咱们先简单学习下这2个必备的基础技能。
2.1 面向对象设计原则面向对象设计的目标之一就是支持可维护性复用,一方面需要实现设计方案的重用,另一方面要确保系统易于拓展和修改,具有较好的灵活性。7种面向对象设计原则,其中前5条是强约束性的建议都做到,后2条尽量做到即可。
1、单一职责原则(Single Responsibility Principle , SRP):一个对象应该只包含单一的职责,并且该职责被完整地封装在一个类中。--单一职责原则是实现高内聚低耦合的指导方针。
理解:
一个类只负责一个职责。2、开闭原则(Open Close Principle):对扩展开放,对修改关闭。--开闭原则是面向对象设计的目标。
理解:
使用接口和抽象类。实现不修改原代码,又可以拓展新方法。3、里氏代换原则(Liskov Substitution Principle):所有引用基类(父类)的地方必须能透明地使用其子类的对象。--里氏代换原则是实现开闭原则的基础。
理解:把父类设计为抽象类或者接口。子类必须实现父类的所有方法。4、依赖倒转原则(Dependence Inversion Principle):高层模块不应该依赖低层模块,它们都应该依赖抽象。抽象不依赖于细节,细节应该依赖于抽象。--依赖倒转原则就是面向对象设计的主要手段。
理解:
要针对接口编程,不要针对实现编程。依赖注入:将一个类的对象传入另一个类,注入时尽量注入父类对象,程序运行时通过子类对象覆盖父类对象。5、接口隔离原则(Interface Segregation Principle):客户端不应该依赖那些它不需要的接口(方法),--接口级的单一职责原则。
理解:
大接口要分割成小接口,接口专用。客户端使用专用接口。6、迪米特法则(Demeter Principle):即最少知道原则,一个实体应当尽量少的与其他实体之间发生相互作用,减少耦合。
理解:
依赖者只依赖该依赖的对象,被依赖者只暴露该暴露的对象。7、合成复用原则(Composite Reuse Principle):尽量使用合成/聚合的方式,而不是使用继承,降低耦合。
理解:
少用继承,降低耦合。2.2 UML建模UML1.X有9个图,UML2.0有12个图,具体如下图所示:
一般,我们掌握 UML1.X 常用的9种图即可,分为两类:
静态图:用例图、类图、包图、对象图、部署图动态图:顺序图(时序图),通信图(UML1.x 时称为协作图),状态机图,活动图本文需要使用静态图的一种:类图。关注类图中类之间的6种关系(耦合度大小排序):泛化 = 实现 > 组合 > 聚合 > 关联 > 依赖。
2.2.1 类图-关联关系1.泛化:指的是继承关系,表达一般和特殊。符号:空心三角箭头的实线,箭头指向父类。(注:UML中只有泛化,继承是开发角度的描述。)2.实现:指的是类与接口的关系,表达类实现了接口的特征行为。符号:带三角箭头的虚线,箭头指向接口。3.组合:指的是整体与部分的关系, 但部分不能离开整体而单独存在。符号:带实心菱形的实线,菱形指向整体。4.聚合:指的是整体和部分关系,且部分可以离开整体而单独存在。符号:空心菱形的实心线,菱形指向整体。5.关联:指的是类和类的关系,表达一个类知道另一个类的属性和方法。符号:带普通箭头(或实心三角形箭头)的实心线。6.依赖:指的是使用的关系, 即一个类的实现需要另一个类的协助, 所以要尽量不使用双向的互相依赖。符号:带箭头的虚线,指向被依赖的类。2.2.2 类图-表示方法从上到下分为3部分:类名、属性、方法。符号含义:+ public、- private、#protected三、设计模式本节列举24种设计模式,其中创建型模式6种、结构型模式7种、行为型模式11种。每个模式从3个角度进行分析:定义、UML类图、应用。
3.1 创建型模式创建型模式,就是用来创建对象的。包含3块:单例/原型模式、工厂模式(简单工厂、工厂方法、抽象工厂)、建造者模式。
1.单例模式(Singleton)定义:保证一个类仅有一个实例,并提供一个访问它的全局访问点。
UML类图:
应用:待补充
2.原型模式(Prototype)定义:用原型实例指定创建对象的种类,并且通过拷贝这个原型来创建新的对象。
UML类图:
3.简单工厂模式(Static Factory Method Pattern)定义:定义一个工厂类,使用static方法创建对象。根据不同参数返回不同实例,每增加一个对象需要修改工厂类,违背了“开闭原则”。--不推荐使用。
UML类图:
应用:
Calendar 类获取日历类对象,static getInstance方法,根据参数获取一个Calendar子类对象。Logback 中的 LoggerFactory日志工厂 ,static getLogger方法根据name/Class获取 Logger 对象。Spring的BeanFactory接口,getBean(),根据name/Class获取不同对象,但不是static修饰的,严格来说不算简单工厂。4.工厂方法模式(Factory Method)定义:定义一个用于创建对象的接口,让子类决定将哪一个类实例化。此模式使一个类的实例化延迟到其子类。
UML类图:
应用:
java.net.URLStreamHandlerFactory作为工厂方法接口,定义了抽象方法createURLStreamHandler创建产品URLStreamHandler。工厂方法实现类为sun.misc.Launcher内部类Factory。5.抽象工厂模式(Abstract Factory)定义:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。用于创建一个产品族的产品。
UML类图:
应用:
java.sql.Connection接口就是抽象工厂接口,定义了创建Statement产品族:Statement createStatement()、PreparedStatement prepareStatement(String sql)、CallableStatement prepareCall(String sql) 。PgConnection impl BaseConnection(extends Connection)就是一个具体工厂,专用于PostgreSql数据库的连接工厂。PgConnection复写了Statement产品族(3个创建)方法。6.建造者模式(Builder)定义:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
UML类图:
应用:
实际应用中,具体建造者Builder一般直接使用静态内部类实现。创建产品时类似:XXX.Builder(参数1,参数2,...).build()。Mybatis源码org.apache.ibatis.builder包下:MapperBuilderAssistant指挥者中,产品有:ParameterMap、ParameterMapping、ResultMap、、ResultMapping、Discriminator、MappedStatement等。每个产品都有自己的建造者静态内部类Builder(定义了build())。3.2 结构型模式1.适配器模式(Adapter)定义:将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
UML类图:
应用:
Spring AOP中,org.springframework.aop.framework.adapter包下的AdvisorAdapter接口,有3个适配器实现类:AfterReturningAdviceAdapter、MethodBeforeAdviceAdapter、ThrowsAdviceAdapter把每一个Advisor中的Advice都要适配成对应的MethodInterceptor对象。这里使用的是方式二对象适配器的变种。比如MethodBeforeAdviceAdapter适配器通过getInterceptor()获取到MethodBeforeAdviceInterceptor,最终结合拦截器模式(非GOF23),调用advice的advice.before()实现。
目标接口:AdvisorAdapter接口适配者:MethodBeforeAdvice接口适配器:MethodBeforeAdviceAdapter(advisor->advice)+MethodBeforeAdviceInterceptor(把适配者advice做入参构造,最终调用适配者方法执行)比较复杂,图示如下:
2.桥接模式(Bridge)定义:将抽象部分与它的实现部分分离,使它们都可以独立地变化。
UML类图:
拆出一个维度出来,进行聚合,可有效减少子类的个数。原本维度1个数*维度2个数->维度1个数的子类+维度2个数的聚合实现+1个聚合接口
应用:
java.sql包下的Driver和Connection接口,通过DriverManager进行桥接(不像图中的聚合实现)。DriverManager定义了registerDriver和getConnection方法。registerDriver可以注册各种驱动。Connection接口可实现连接多种数据库。2个维度分开进行拓展实现,进行了脱耦。
3.组合模式(Composite)定义:将对象组合成树形结构以表示“部分-整体”的层次结构。它使得客户对单个对象和复合对象的使用具有一致性。
UML类图:
组合模式分为透明式(树枝特有方法在抽象类中体现,树叶类复写空实现,客户端使用时无需区分树枝还是树叶)和安全式(树枝特有方法在树枝类中体现)。当节点具有一致行为时采用透明式,当各节点行为不一致较多或树枝节点较为健壮时采用安全式。
应用:
Map接口作为Component容器接口;HashMap作为Composite树枝、Node实现了Map接口下的唯一接口Entry定义:动态地给一个对象添加一些额外的职责。就扩展功能而言, 它比生成子类方式更为灵活。
UML类图:
应用:待补充
5.外观模式(Facade)定义:为子系统中的一组接口提供一个一致的界面,Facade模式定义了一个高层接口,这个接口使得这一子系统更加容易使用。
UML类图:
应用:待补充
6.享元模式(Flyweight)定义:运用共享技术有效地支持大量细粒度的对象。
UML类图:
应用:待补充
7.代理模式(Proxy)定义:为其他对象提供一个代理以控制对这个对象的访问。
UML类图:
应用:待补充
3.3 行为型模式1.责任链模式(Chain of Responsibility)定义:解除请求的发送者和接收者之间耦合,而使多个对象都有机会处理这个请求。将这些对象连成一条链,并沿着这条链传递该请求,直到有一个对象处理它。
UML类图:
应用:待补充
2.命令模式(Command)定义:将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化;对请求排队或记录请求日志,以及支持可取消的操作。
UML类图:
应用:待补充
3.解释器模式(Interpreter)定义:给定一个语言, 定义它的文法的一种表示,并定义一个解释器, 该解释器使用该表示来解释语言中的句子。
UML类图:
应用:待补充
4.迭代器模式(Iterator)定义:提供一种方法顺序访问一个聚合对象中各个元素,而又不需暴露该对象的内部表示。
UML类图:
应用:待补充
5.中介者模式(Mediator)定义:用一个中介对象来封装一系列的对象交互。中介者使各对象不需要显式地相互引用,从而使其耦合松散,而且可以独立地改变它们之间的交互。
UML类图:
应用:待补充
6.备忘录模式(Memento)定义:在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到保存的状态。
UML类图:
应用:待补充
7.观察者模式(Observer)定义:定义对象间的一种一对多的依赖关系,以便当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并自动刷新。
UML类图:
应用:观察者模式
8.状态模式(State)定义:允许一个对象在其内部状态改变时改变它的行为。对象看起来似乎修改了它所属的类。
UML类图:
应用:待补充
9.策略模式(Strategy)定义:定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。本模式使得算法的变化可独立于使用它的客户。
UML类图:
应用:待补充
10.模板方法模式(Template Method)定义:定义一个操作中的算法的骨架,而将一些步骤延迟到子类中。Template Method使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
UML类图:
应用:待补充
11.访问者模式(Visitor)定义:表示一个作用于某对象结构中的各元素的操作。它使你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。
UML类图:
应用:待补充
===参考===================
设计模式总结
设计模式与23种设计模式的简单介绍
浅谈UML中常用的9种图
关键词:
您可能也感兴趣:
为您推荐
视讯!远方信息:副总经理郭志军拟减持股份
狗粮!皮蓬前妻与乔丹儿子海边度假拥吻,拉尔萨西语示爱:我太爱你!|信息
世界快资讯丨大连灵活就业人员社保缴费标准2023年公布
排行
最近更新
- 一文掌握设计模式(定义+UML类图+应用)
- 漯河银保监分局:聚焦重点领域 精准发力全力提升政策性金融...
- 《羚羊木雕》教案【优秀8篇】
- 天天要闻:油价迎中长期利好!OPEC预计到2045年,全球能源需...
- 【全球新要闻】行驶中的公交车“趴窝”路中,关键时刻他们出手了
- 西宁城市职业技术学院是985还是211 西宁城市职业技术学院排名多少
- 德防长:德国计划在立陶宛永久驻扎4000名士兵
- 花滑女神张子君现状:证件照美出新高度,频频和樊振东互动!
- “网红”的迁徙:主播涌向东南亚_环球观天下
- 喊也没用,张本智和被打哭了!国乒豪门决胜国光横扫日本一哥
- 焦点速递!郑州首批51个西瓜便民销售点出炉
- 漯河召开全市政务服务“一件事一次办”工作推进会|当前热点
- 华建集团:下属公司签署7408万元工程设计合同 世界观天下
- 假期更新为 Disney Mirrorverse 带来季节性销售
- 象山县召开土地推介座谈会
- 知名地产巨头确认违约!
- 抢先体验 VisionOS 操作系统,附详细教程
- 5天4板中马传动:不涉及机器人概念 公司股票可能存在非理性...
- 【环球时快讯】秋乐种业:拟使用不超过1.5亿元闲置募集资金购...
- 全球报道:体育消费融合发展,长沙市第三届体育消费节系列活动...
- 江西赣州首趟始发至北京“绿巨人”动车7月1日开行
- NASA 正在开发人工智能界面,以让宇航员与航天飞船实现对话...
- 当前最新:网上公积金提取失败怎么办?盘点5种常见原因和解决...
- 广西壮族自治区市场监管局关于组织开展2023年全区食品检验检...
- 【世界报资讯】新坦克500将上市!动力更强更省油,免购置税配...
- “济南大陆机电”入围《信用中国》栏目
- 【播资讯】招联逾期一年怎么还?收到开庭信息是真的吗?
- 卖教辅、当房东,一年营收1400亿元,新华书店活成“隐形大佬”
- 速递!共享单车行业调研 2023共享单车行业发展趋势及市场现状分析
- Letme谈亚运会名单:这个名单早就定好了,名单没啥大问题
今日要闻
- 合资车企下半场怎么踢|汽势焦点
- 全球微头条丨美团在成都成立科技新公司 注册资本100万元
- 每日关注!房地产及物管行业23年第25周周报:端午节奏影响月末冲量 LPR下调期待后续政策
- 漯河银保监分局:聚焦重点领域 精准发力全力提升政策性金融服务质效 精彩看点
- 做短视频素材哪里找?短视频素材获取渠道和注意事项
- 湖南张家界太任性!机场就建在风景里,游客直呼“中国最美机场”_当前信息
- 全球最资讯丨女神节祝福语金句
- 上海环境: 公司在手多个BOT项目,此类项目系与政府方或政府授权方签订的合同_焦点播报
- 献给所有孩子和曾经是孩子的大人,许美达编译版《小王子》出版
- 8岁男童被武术教练殴打致死,涉事俱乐部仅成立2个月,警方通报:系故意伤害案件 全球快播报