设计模式1-设计模式概览

序言

有了娃以后才知道学习时间多么宝贵,看书学习研究技术多么幸福和珍贵。

我是一名工作十年的工程师,但对于设计模式,还是觉得自己是一个学生,还很需要学习,当然,跟十年前学习设计模式,已经不是一个层次了,那时候大概是个婴儿,还没上幼儿园。

废话不多说了,再次总结学习设计模式,也是希望可以从更深层次的去总结设计模式在工作和生活中有什么用处,学习设计模式已经不再是为了补充面试经验或者扩展知识面了。

学习设计模式,可以从架构、代码设计甚至优化系统、提高代码开发效率、调试效率等多个角度有所增进,而且可以更加深入的理解JDK的设计、spring的设计以及很多优秀开源框架的设计(本人还没用过啥收费的框架,呵呵)。

本系列的博客叫做设计模式学习之路,会从学习路线的角度去分析如何学习设计模式,以及如何一层一层的循序渐进的学习,结合实际的应用场景、以及模式之间的对比进行总结。

限于本人的技术能力和理解能力,难免会有疏漏和瑕疵,还望读者海涵并指正。谢谢!

零:前景提要

本系列博客,用到的代码是java语言。

一、设计模式是什么?

网上的各种解释我不再赘述,个人理解:设计模式是为设计程序和系统提供的一系列的解决思路,是一系列的模型,类似于数学模型,它是设计的模型。体现在代码层次,是对面向对象设计原则的组合应用。学起来略有抽象,但与我们熟知的开源框架和JDK进行比对的时候,发现非常具体和形象。

二、设计模式分类:

创建型:

创建型模式,模式控制着对象创建、初始化以及类的选择。

关注对象的创建,何为对象的创建?就是我们在写代码的时候写的那一行,Object obj = new Object();这个new的过程就是对象的创建,对于现在的程序员大概都不太懂这块,因为springboot管理的太好了,以前没有springboot的时候,使用spring,还有个配置文件可以看看理解,现在封装的更好了。哈哈。不过基础嘛,还是要学习的,万变不离其宗,再牛逼的技术,最后都是二进制。

扯远了,回来说创建型设计模式,既然关注的是对象的创建,其实也就是解决了创建对象的几种情况,毕竟一句Object obj = new Object();可能会造成太多的copy and paste。

先说有哪些是创建型设计模式:

工厂方法、抽象工厂、单例、建造者、原型。

工厂方法和抽象工厂,一看就是针对所有对象的创建讲的,工厂嘛,量大呀!而单例、建造者、原型,则是一个对象,或者说是一种对象,也就是一个类的对象是如何创建的,这几种模式,往往都是有针对性的对象,有特殊的业务,啥叫特殊的业务呢?

普通的业务就是针对数据库表的增删改查,特殊的业务比如工具类,XXXUtils,增删改查之外的固定流程XXXWorkProgress等。

那么工厂和其他几个有啥关系呢?

工厂其实也可以创建其他这几种对象,只不过这几种对象创建出来之后不只是new 一下那么简单,再说白一点,就是

单例悄悄的改了自己的构造器,使得调用方不能直接new,而是需要调用静态方法获取对象。从而保护了自己的构造过程,而这个构造的过程又是保证唯一性,所以叫单例。

原型使用了克隆,使得在客户端调用的时候,不再去new,而是使用克隆的方法,初始化方法不会再次执行,但需要注意深复制和浅复制问题。

建造者则是体现在“组装”的过程,往往对象创建过程需要组装多个参数对象。建造者,替换了多个入参的形式,使得代码更加清晰。工厂创建对象还是很原始的new,不过是“批量”,每次用对象都去工厂里拿,而不是自己new,使得创建对象的过程被“封装”起来了,在与策略模式结合的时候,有非常好的体验。

结构型

结构型模式,模式用于组织类与对象之间的关系为将相关对象组合到一起并使用以获得所需行为提供指南。——《java EE 设计模式解析与应用》
结构型模式涉及到如何组合类和对象以获得更大的结构。——《设计模式—可复用面向对象软件的基础》
哪些是结构型设计模式?
——适配器、代理、桥接、装饰、外观、享元、组合

以上 7 种结构型模式,除了适配器模式分为类结构型模式和对象结构型模式两种,其他的全部属于对象结构型模式。(讲真,关于这句话,截至发文之前,还不透彻,以后完善)

适配器(Adapter)模式:将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类能一起工作。
说起来有点抽象,但实际上就是多系统调用的时候,一般不会直接使用下游系统的接口的入参和返回值作为自己系统的完整入参和完整返回值,因此需要经过一层转换。也就是说不管你懂不懂模式,适配器一定会用到。

代理(Proxy)模式:为某对象提供一种代理以控制对该对象的访问。即客户端通过代理间接地访问该对象,从而限制、增强或修改该对象的一些特性。
第二句话看着和装饰特别容易搞混,装饰关注的是对对象的扩展,不影响对象的访问,而代理,则是要控制也就是要去影响对对象的访问。

桥接(Bridge)模式:将抽象与实现分离,使它们可以独立变化。它是用组合关系代替继承关系来实现的,从而降低了抽象和实现这两个可变维度的耦合度。
看名字特别容易与适配器进行混淆,看概念就完全懵逼,抽象和实现本来不就是分离的么?它们可以独立变化就更加迷惑了。
个人理解就是一个对象有两种(或多种)角度的变化和扩展,比如手机,有品牌、型号这样的维度的变化,也有功能(游戏、打电话等)维度的变化——《大话设计模式》中的例子。
《重学java设计模式》-付政委著,这本书里举得支付方式和支付模式的例子,也桥接模式的经典应用场景。

装饰(Decorator)模式:动态地给对象增加一些职责,即增加其额外的功能。
咋动态的增加的呢?这块儿还真得自己写一写代码才能理解。装饰这个名字不得不说非常的形象,它是一层一层的装饰,每一层都是独立的,最后的效果确实所有装饰器最终的效果,有点像化妆,水、乳、精华、防晒、隔离、粉底、彩妆……
这些化妆品的基础,都是这张脸。代理的话,就是直接用一个长得比较像的“替身”了,这个替身会原身的很多功能,还会原身的不会的功能,所以说代理是控制原身的访问,而装饰是扩展原身的功能。

外观(Facade)模式:为多个复杂的子系统提供一个一致的接口,使这些子系统更加容易被访问。
其实外观和适配器一样普遍,而且一般都是结合一起使用的。简单说就是MVC,某个需求,要处理业务逻辑,那就要关联多个对象,有处理数据库的,有处理缓存的,还要处理下游系统的,也有处理MQ的等,自然service层就肩负起了这个责任,上层调用者只调用一下service就行了。
这个service就是外观模式。在分层设计中,对层的职责划分清楚的,外观模式非常清晰,否则将会出现某一个类巨大,其他类却只是一路透传,失去了分层的作用,而且方法不能复用,造成每个需求都要写一遍所有的逻辑,那种代码,就不能叫外观啦,所以外观的精髓,除了梳理对象关系,还有很大的代码复用率和可读性的作用。
虽然最常用,也是最“乱用”的一个模式。

享元(Flyweight)模式:运用共享技术来有效地支持大量细粒度对象的复用。
共享通用对象,来减少内存的使用。
摘抄一句《重学java设计模式》中的一句话:较大的对象通常比较耗费内存,需要查询大量的接口或使用数据库资源,因此有必要统一抽离出来作为共享对象使用。
大体看了一下享元模式,感觉还是不够清晰,后续再完善。

组合(Composite)模式:将对象组合成树状层次结构,使用户对单个对象和组合对象具有一致的访问性。
这个模式的名字比较“广义”,但概念中的“树状”二字非常形象的描述出了组合模式的应用场景的精髓。
像我们经常用到的组织架构、部门管理、后台的菜单,都是树状的,在数据库设计的时候也是一张表,对应于实体类的关系也是树状的。所以这个模式也是非常经典的常用模式之一。

行为型

行为型模式,模式涉及到算法和对象间职责的分配,还描述了对象和类之间的通信模式。将你的注意力从控制流转移到对象间的联系方式上来。——《设计模式—可复用面向对象软件的基础》
行为型模式,模式控制着对象间的通信、消息传递与交互。——《java EE 设计模式解析与应用》

哪些是结构型设计模式?
——模板方法、策略、命令、职责链、观察者、中介者、迭代器、访问者、备忘录、解释器

行为型模式是 GoF 设计模式中最为庞大的一类,它包含以下 11 种模式。

模板方法(Template Method)模式:定义一个操作中的算法骨架,将算法的一些步骤延迟到子类中,使得子类在可以不改变该算法结构的情况下重定义该算法的某些特定步骤。
模板的精髓在于方法内部的实现步骤是确定的,由父类制定好,这也就是模板(母版),至于每一步具体的实现,则由子类来完成,往往大部分步骤都是相同的,由父类完成即可,只有个别部分需要子类来完成不同的实现。

策略(Strategy)模式:定义了一系列算法,并将每个算法封装起来,使它们可以相互替换,且算法的改变不会影响使用算法的客户。
策略大概是继外观和适配器以外最常用的模式了。看概念其实还蛮绕的,从实现角度讲就是定义了接口,不同的方案(算法)不同的实现,调用方,根据需要调用不同的实现罢了,一般和工厂方法模式结合使用,这样就可以将变化的点交给工厂来处理了。

命令(Command)模式:将一个请求封装为一个对象,使发出请求的责任和执行请求的责任分割开。
发出请求和执行请求分开,挺抽象的,那么为啥要分开呢?好处是啥呢?不分开有啥隐患呢?还没明白,待我继续研究。
不过,命令模式的精髓在于这个命令,我们常常认为命令是一条指令,一个字符串标识,但命令模式的命令,是一个类一个接口。而真正执行者,则是命令实现类里去调用的。

职责链(Chain of Responsibility)模式:把请求从链中的一个对象传到下一个对象,直到请求被响应为止。通过这种方式去除对象之间的耦合。
职责链顾名思义了,最大的优点就是客户端只需要提出一个需求,至于后面到底都有哪些人去处理哪些业务就不需要关心了,而处理业务的职责也只需要知道自己要处理啥以及知道自己的下游是谁就好了,名字非常的形象,实现也很简单,应用场景也算普遍,比如需要层层业务校验的,或者app需要各种层次弹层的等。

状态(State)模式:允许一个对象在其内部状态发生改变时改变其行为能力。
当一个对象的内在状态改变时允许改变其行为,这个对象看起来像是改变了其类。
状态模式的好处是将与特定状态相关的行为局部化,并且将不同状态的行为分割开来。
当一个对象的行为取决于它的状态,并且它必须在运行时刻根据状态改变它的行为时,可以考虑使用状态模式。
一个行为下的多种状态变更。

观察者(Observer)模式:多个对象间存在一对多关系,当一个对象发生改变时,把这种改变通知给其他多个对象,从而影响其他对象的行为。

中介者(Mediator)模式:定义一个中介对象来简化原有对象之间的交互关系,降低系统中对象间的耦合度,使原有对象之间不必相互了解。

迭代器(Iterator)模式:提供一种方法来顺序访问聚合对象中的一系列数据,而不暴露聚合对象的内部表示。

访问者(Visitor)模式:在不改变集合元素的前提下,为一个集合中的每个元素提供多种访问方式,即每个元素有多个访问者对象访问。

备忘录(Memento)模式:在不破坏封装性的前提下,获取并保存一个对象的内部状态,以便以后恢复它。

解释器(Interpreter)模式:提供如何定义语言的文法,以及对语言句子的解释方法,即解释器。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值