23中设计模式实例

总结一下23中设计模式各自的优缺点,及实际情况中如何使用。

详细解析如下,使用实例代码地址:https://github.com/chanyi/designPattern

设计模式分为3大类:


创建型模式(5个):

关注点是如何创建一个对象。将创建的使用和分离。使用者只需要使用,不需要关注创建的过程

  • 单例模式:一个类只能提供一个实例,但是可以扩展到优先多例模式;

  • 原型模式:将一个类作为原型,通过复制,制造出多个和原型类似的新实例

  • 工厂模式:定义一个用于创建产品的接口,由子类决定生产什么产品,类创建模式

  • 抽象工厂模式:提供一个创建产品族的接口,每个子类可以创建一系列相关的产品

  • 建造者模式:将一个对象分解成多个部分,然后分别创建他们

结构型模式(7个):
  • 代理模式:控制客户端对对象的访问

  • 适配器模式:将类的接口换成对象需要的

  • 桥接模式:用组合方式代替继承关系

  • 装饰模式:在不改变现有结构的情况下,动态的增加功能

  • 外观模式:facade,为多个子系统提供一个统一的接口

  • 享元模式:共享对象

  • 组合模式:一个对象下,有个列表属性,存放子对象,构成树结构

行为型模式(11个):
  • 模板方法模式:

  • 策略模式:适合用于多个实现方法的统一接口调用的情况。比如排序接口提供一个统一的接口用来被调用,但是排序时实际比较大小的策略可以有多个,比如按照高度比较,按照宽度比较。所以不同的策略可以通过参数入参到排序的方法内。排序方式只是实现排序的代码即可。

  • 命令模式:

  • 责任链模式:

  • 状态模式:

  • 观察者模式:

  • 中介者模式:

  • 迭代器模式:

  • 访问者模式:

  • 备忘录模式:

  • 解释器模式:


创建型模式(5个):

1、单例模式:

特点:

一个类只有一个实例对象

该单例对象必须由单例类

单例类对外提供一个访问该单例类的一个全局访问点

实现:一般可以通过new获取多个实例。所以单例的情况,构造函数要设置为私有的

类内定一个私有静态实例,再定义一个静态公有函数,返回这个私有静态实例

两种方式:懒汉式和饿汉式

懒汉式:类加载的时候没有生成单例,在调用获取单例的方法(getInstance)时才创建单例

饿汉式:类一加载,就同时创建一个单例,在getInstence时单例已经存在

应用场景:

1)、只要求生成一个对象的时候,比如一个人的身份证,一个班的班长

2)、当对象需要被共享的时候,比如数据库的连接池。web中的配置对象,

3)、当某个类频繁被实例话,对象又频繁被销毁的时候。多线程的线程池和网络连接池

线程池在程序中一般只需要一个即可,线程的创建都在线程池内操作。线程池是不变的。网络池的原理相同

扩展:单例模式可以扩展为有限多例模式

将对象创建好后放在一个list里面。这样获取到的实例就是一个list,实现有限个实例。

有限多例的应用场景:比如玩麻将开始需要执两个骰子,此时骰子作为一个类的话,就需要创建两个实例。

2、原型模式:用一个已经创建的实例当作原型,复制出多个实例来。

java提供了对象的clone方法,实现原型模式很简单

分类:

深克隆:自己完成每个属性的clone

浅克隆:只需要调用clone即可

优点:

1、简化流程

2、动态获取对象

3、某些情况下比直接new快一些

3、工厂方法模式(FactoryMethod)

抽象工厂接口中只生产一个产品

接口:定义一个工厂接口,里面包含创建对象方法

工厂子类:实现工厂接口,实现具体的创建对象方法

分类:

简单工厂模式:创建的产品不多,只要一个工厂类就可以完成(无抽象工厂类)

抽象工厂模式:在不修改源代码的情况下,引入新的产品(有抽象工厂类)

使用于:

用户只知道产品工厂名,不知道产品类型

客户不关心创建的过程,只关心产品的品牌

易于扩展,如果新增一个具体产品,则新建一个具体工厂,继承抽象工厂。在新建的工厂中写代码,不影响原来的代码

实例:

使用工厂方法模式写一个计算器(面试)

思路:

抽象工厂接口:计算接口,方式是返回结果

具体工厂类:加法工厂类,乘法工厂类,除法工厂类,减法工厂类。。。

调用类:直接使用具体的工厂类创建一个对象,调用返回结果方法,即可;

4、抽象工厂模式(abstractFactory)

抽象工厂接口中可以生成两个及多个产品

工厂方法模式只生产一个等级的产品,抽象工厂可以生产多个等级的产品

使用条件:

1、系统中有多个产品族,每个具体的工厂产生一族产品

2、系统一次只可能生产某一族产品,同族的产品一起使用

优点:

对同族多产品共同管理

增加一个新的产品族时不需要修改源代码,满足开闭原则

缺点:

如果产品族中增加一个新产品,整个工厂都要修改

5、建造者模式:

使用多个简单的对象,一步一步构建成一个复杂的对象

将一个复杂的对象拆分成多个简单的对象

使用的实例:

套餐的组成(拆分成多个简单的组成),StringBuilder,

优点:

容易扩展,便于控制细节风险

缺点:

如果内部复杂会有多个建造类

产品必须要有共同点

注意:

和抽象工厂模式相比,更加注重各个组成部分的顺序


结构型模式:

1、代理模式(proxy):

为对象提供一种代理,以控制对象的访问,客户端通过代理访问对象,可以控制客户端对对象属性的访问和操作

实例:

下载很大文件,需要时间比较长

单位内部数据库,限制客户端的访问

优点:

起中介作用,保护目标对象

对目标对象的功能进行扩展

目标对象与客户端分离,可以降低系统的耦合度

缺点:

有了中介,请求速度变慢

增加系统的复杂度

结构:

真实类

抽象类(接口/抽象类)

代理类

2、适配器模式(adapter):将一个类的接口换成客户端所需要的接口,比如将交流电转为直流电供笔记本电脑使用

优点;

将已有的类放到新环境下,使之适应新的需求

可以让两个没有关联的类一起运行

提高了类的复用性

提高类的透明度

灵活性好

缺点:

过多适配器会是系统变得复杂

java是单继承类,最多只能适配一个类

3、桥接模式(bridge):抽象与实现分离,二者可以独立变化,用组合关系代替继承关系,降低了耦合度

优点:

降低耦合度,扩展性强

细节对客户透明

缺点:

设计难度大,对系统要有深入的理解

结构:

抽象类

扩展抽象类

实现类

具体实现类

适用:

一个类有两个独立变化的维度

4、装饰模式(decorator):在不改变现有结构的情况下,动态的给对象增加一些职责

优点:

比继承更灵活

可以设计出不同的装饰类,创造出多个不同行为的组合

缺点:

增加许多子类,增加复杂度

结构:

抽象类

具体类

抽象装饰类:增加一个抽象类的属性,

具体装饰类:具体装饰类继承抽象装饰类,重写抽象装饰类继承的抽象类的抽象方法,然后改写实现动态增加

5、外观模式(facade):为多个复杂的子系统提供一个统一而接口,是其他客户只需要访问这一个接口即可,不需要按个访问每一个复杂的子系统

优点:

降低子系统与客户端的耦合度

减少客户端处理的子系统对象的数量,子系统用起来更方便

编译一个子系统不会影响其他的子系统和客户端

缺点:

不能很好的限制客户使用子系统的类

增加新系统,要修改统一接口,不满足开闭原则

适用场景:

子系统很多的系统

客户端和多个子系统之间有联系的时候

6、享元模式(flyweight):利用共享技术,重用细粒度的对象。减少系统开销

优点:

减少系统开销

缺点:

对象共享,增加程序的复杂度

读取享元模式的外部状态,是运行时间稍微变长

两种状态:

内部状态:不会随着环境改变的内部共享部分

外部状态:随环境改变的外部不可共享的部分

7、组合模式(composite):

在一个对象中包含其他对象,多个对象形成一个树形结构

主要适用于树形结构的对象的情况

优点:

高层模块调用简单,增加子节点自由

缺点:

实现是 叶子和树枝都是实现类,不是接口,违反了依赖倒置原则

行为型模式(11个)

1、模板方法:定义一个操作中的算法骨架,子类实现算法的具体步骤,主要就是封装不可变性,扩展可变性

优点:

父类中封装共用代码,便于代码的复用

部分方法有子类实现,符合开闭原则,

缺点:

每一个具体算法的实现都有有一个对应的子类,类比较多,不好维护

父类的抽象方法由子类实现,子类执行的结果会影响父类的结果,导致一种反向的控制结构,提高代码的阅读难度

结构:

抽象类:给出整个框架,由一个模板方法(定义算法骨架)和几个基本方法构成(算法的具体步骤)

具体子类:实现抽象类的抽象方法

2、策略模式(strategy)定义一系列算法,把每个算法封装起来,算法之间可以相互替换。而且算法的变化不会影响使用。

优点:

替代多重条件判断的方法,这样易于维护

一系列的算法族中的公共部分可以抽取到父类中,避免重复代码

支持开闭原则

算法族的实现放在策略类中,算法族的使用放在使用类中。二者分离

缺点:

策略模式需要很多策略类

对算法的选择需要慎重的考虑

构成:

抽象策略类

具体策略类

使用类(环境类)

应用实际场景:

诸葛亮锦囊,一个锦囊就是一个策略。

多种出行方法,一种出行方式就是一个策略

3、命令模式(command):请求以命令的形式包裹在对象中,并传给调用对象,

调用对象寻找可以处理该命令的合适的对象,然后把命令传给相应的对象,对该对象执行命令

优点:

将行为请求者和行为实现者解耦

新的命令很容易加入到系统中

缺点:

系统会有过多的具体命令类

结构:

调用者:有一个命令对象,在某个时间点调用命令对象的execute方法

命令对象:持有一个接受者和一个execute方法

接受者:动作的执行者

4、责任链模式(chain of Responsibility)

请求发送到责任链上,不需要关注处理的系统和请求的传递过程

优点:

降低对象之间的

增强系统的可扩展性

增加给对象指派责任的灵活性

责任的分担,每个类处理自己的责任,符合类的职责单一原则

缺点:

不能保证每个请求一定被处理,一个请求如果没有明确的接受者,这个请求可能传递到责任链的最后还没被处理

责任链长的情况,请求的处理可能会涉及多个处理对象,影响系统性能

责任链建立的合理性靠客户端来保证。增加客户端你的负责性

结构:

抽象处理者(handler)

具体处理者(concreteHandler)

客户端(client)

使用实例:

请假找不同的领导,不同的领导又不同的责任,批假的权限也都不相同

5、状态模式(state):

把复杂的判断逻辑提取到不同的状态对象中,允许状态对象在其内部状态发生改变是改变其行为

优点:

将特定状态的相关行为局部化到一个状态中,将不同状态分离开,满足单一职责原则

减少对象的相互依赖

有利于扩展,有新的状态,就直接定义一个新的状态类

缺点:

增加类和对象的个数

容易造成代码混乱

结构:

环境角色(context)

抽象状态(state)

具体状态(concreteState)

6、观察者模式(observer)

多个对象之间存在着一对多的依赖关系,当一个对象的状态发生变化,其他对象的行为也跟着发生变化

也称为订阅发布,模型视图模式

优点:

降低了目标与观察者之间的耦合关系,

目标与观察者之间建立一套触发机制

缺点:

目标与观察者依赖关系没有完全解除

当观察者对象很多的时候,通知发布会花费很多时间,影响性能

结构:

抽象主题(subject)抽象目标类:

具体主题(concrete subject)

抽象观察者(observer)

具体观察者(concrete observer)

7、中介者模式(mediator)

为了降低多个对象和类之间的通信复杂性,使用中介类,处理不同类的通信,支持松耦合,解决网状结构

优点:

减低对象之间的耦合度

将对象间的一对多关联变成一对一关联,提高系统的易维护性

缺点:

对象太多的时候,中介者对象会变的很复杂

结构:

抽象中介类(mediator)

具体中介类(concrete mediator)

抽象同事类(colleague)

具体同事类(concrete colleague)

8、迭代器模式(Iterator)

提供一个对象来顺序访问聚合对象中的一系列数据,而不暴露聚合对象的内部表示

优点:

简化聚合类,遍历任务给遍历器类

封装性好,为遍历不同的聚合结构提供统一的接口

增加新的聚合类,新的遍历器类都很方便,无需修改原有代码

缺点:

增加类的个数,增加复杂度

结构:

抽象聚合类(Aggregate)

具体聚合类(concreteAggregate)

抽象迭代器(Iterator)

具体迭代器类(concreteIterator)

9、访问者模式(visitor)

将某种数据结构中的各元素的操作分离出来封装成独立的类,某些元素的有了新的操作,就定义新的类,不影响原有的数据结构

为每个数据元素中的元素提供多种访问方式

优点:

扩展性好

复用性好

灵活性好

符合单一职责原则

缺点:

每增加一个新的元素类,就需要增加一系列的访问类,违背开闭原则

破坏封装性,具体的元素对访问者公开

违反了依赖倒置原则,访问者类依赖了具体类,没有依赖抽象类

结构:

抽象访问者(visitor)

具体访问者(visitorConcrete)

抽象元素(element)

具体元素(elementConcrete)

对象结构(Object Structure)

10、备忘录模式(memento)

在不破坏封装性的前提下,捕获一个对象的内部状态,并缓存,当需要的时候把对象回复原来的状态,也是一种快照模式

优点:

提供一种可以回复状态的机制,

实现内部封装,除创建人外,其他人都不能访问

简化发起人类,回复过程直接由管理者管理,符合单一职责原则

缺点:

资源消耗大,要花内存去存储快照数据

结构:

发起人(Originator)

备忘录(memento)

管理者(caretaker)

11、解释器模式(interpreter)

给分析对象定义一个语言,定义语言的文法,然后再用解释器解析,该接口解释一个特定的上下文

优点:

扩展性好,使用类来解释文法,可以继承

容易实现,语法树中的每个表达式节点类都是相似的,实现文法比较容易

缺点:

执行效率低:解释器中有很多的循环和递归

会引起类膨胀,每条规则至少定义一个类

可用场景比较少

结构:

抽象表达式(Expression)

终止符表达式(Terminal Expression)

非终止符表达式(Notterminal Expression)

环境角色(context)

客户端(client)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,053评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,527评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,779评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,685评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,699评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,609评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,989评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,654评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,890评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,634评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,716评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,394评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,976评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,950评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,191评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,849评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,458评论 2 342

推荐阅读更多精彩内容

  • 我曾经很憎恨读书 这两天一想到我要天天打理我的公众号,还要写出我的淘小铺细节,我就觉得心里莫名...
    幸福猪2023阅读 183评论 0 0
  • 《全球行动》是由腾讯公司极光计划代理的即时战略游戏,其丰富的玩法和让人眼花缭乱的兵种搭配,吸引了一批的忠实粉丝。 ...
    一只最靓的仔阅读 120评论 0 0
  • 铝板的定义 铝板,是指用纯铝或铝合金材料通过压力加工制成(剪切或锯切)的获得横断面为矩形.厚度均匀的矩形材料。国际...
    铝氏春秋阅读 216评论 0 1
  • 夜莺2517阅读 127,709评论 1 9
  • 版本:ios 1.2.1 亮点: 1.app角标可以实时更新天气温度或选择空气质量,建议处女座就不要选了,不然老想...
    我就是沉沉阅读 6,876评论 1 6