2 结构型模式

2.1 适配器模式

把一个类的接口转化成客户希望的另外一种形式.

回调函数中需要用到的function<>绑定就是一种适配器. 原有的接口不支持, 通过适配器让其支持.

适配器有两种,

一种是类适配器, 用继承的方式实现, Adapter类继承了原来的类并实现了适配的方法.

另一种是对象适配器, 让类含有原来的类的指针/ 引用, 然后自己里面写一个方法内部转换一下接口.

2.2 桥接模式

将抽象部分与它的实现部分解耦,使得两者都能够独立变化。

例子: 对于颜色和笔头粗细, 这是不可分割的两种特性, 属于设计不当. 但是毛笔可以将水彩色和笔头粗细两种正交特性分开, 是良好的设计.

角色:

  • 抽象类: 定义抽象接口, 抽象类中有一个实现类接口的指针
  • 实现类接口:抽象定义另外一个维度
  • 扩充抽象类: 定义抽象类实现的接口
  • 具体实现类: 实现了"实现类接口"定义的接口

用户在持有一个抽象类的指针, 使用的时候实例化成一个扩充抽象类, 同时又可以实例化不同的具体实现类, 保证了两个方向的正交性.


桥接模式和适配器模式有什么不同? 在设计的时候使用桥接模式, 但是如果已经有了两个功能完善的类, 那么使用适配器模式.

桥接模式防止 构建抽象层和实现层过度耦合

缺点: 需要在设计的时候考虑到, 于是两者的关系建立在抽象层, 很难让以后的人识别出来

2.3 组合模式

组合多个对象形成树形结构以表示具有部分-整体关系的层次结构。组合模式让客户端可以统一对待单个对象和组合对象。

最理想的例子是树, 每次调用树的Add()方法来为他添加新的叶子节点.

组合模式有透明组合模式安全组合模式, 透明组合模式要叶子节点也实现枝子节点的方法, 如Add和delete, 但是实现是没有意义的, 因此要做异常处理; 安全组合模式让枝子节点单独去继承组合模式, 然后自己去实现管理方法, 但是这种方法大大增加了实现的复杂性.

角色有:

  • 抽象构件(定义了一些公共接口, 叶子构件和容器构件都要实现)
  • 叶子构件
  • 容器构件(里面可以有容器构件, 也可以是叶子构件)

优点: 清晰分层次地表达对象, 让客户忽略层次差异; 符合开闭原则;
缺点: 叶子构件/ 容器构件的行为受限, 因为他们来自于相同的抽象构件, 因此如果要使用特定的方法, 那么就要在运行的时候判断对象类型.

2.4 装饰模式

动态地给一个对象增加一些额外的职责。就扩展功能而言,装饰模式提供了一种比使用子类更加灵活的替代方案。

角色:

  • 抽象构件:; 是具体构件和装饰类的共同基类, 定义了run()方法
  • 具体构件: 继承自抽象构件
  • 抽象装饰类: 继承自抽象构件
  • 具体装饰类: 实现了抽象装饰类的方法

抽象装饰类中有一个抽象构件的指针, 于是具体装饰类的run()方法中先执行具体构件, 然后再执行装饰的方法.

同样的, 这个具体装饰类还可以被传入到其他的具体装饰类中.


优点: 装饰模式比继承更加的灵活, 可以动态扩展一个对象的功能, 并且可以多次装饰
缺点: 会增加很多小的对象, 更难排错. (装饰器一直持有的是基类的指针)

2.5 外观模式

隐藏了系统内部的类和细节, 封装了一个外观给用户去调用

注意事项:

  • 不要增加额外的功能
  • 不要返回内部子系统的组件给客户, 但是必要的时候提供native_handle方法给客户
  • 外观模式的目的是提供一个高层次的接口, 所以不要进行低层次的单独业务执行

比如内部有一个用户类, 信用卡信息类, 余额类

要封装一个外观, 用户直接操作外观就可以创建一个新的储蓄账户


缺点: 增加减少子系统需要修改外观, 违反了开闭原则

2.6 享元模式

运用共享技术有效地支持大量细粒度对象的复用。

注意被共享的对象必须是细粒度的, 比如说单词池的二十六个字母, 围棋盘中的每一个围棋.

享元: 共享元数据.

享元分为外部状态和内部状态. 内部状态是不管外部怎么创建, 我的内部属性都是已知的(围棋的形状, 大小). 外部属性是根据不同的外部状况, 可能要实时改变(如围棋的位置, 黑白)

角色:

  • 享元工厂: 创建享元, 同时还可以预先创造出享元池, 到时候直接给出
  • 抽象享元
  • 具体享元

缺点: 需要区分外部状态和内部状态.

2.7 代理模式

使用代理对象来实现对原对象的访问.

为什么不直接访问? 代理有以下几个好处

  1. 远程代理: 为远程对象提供了一个本地代理, 其他程序可以直接访问这个代理.
  2. 虚拟代理: 如果创建一个真实实际对象消耗过多资源, 先创建一个代理, 等空闲的时候让代理去创建真实对象.
  3. 保护代理: 不同对象的不同访问权限.
  4. 缓冲代理: 增加一层缓冲区, 来保存这些数据(不同用户共享)
  5. 智能引用代理: 如同shared_ptr

角色有:

  • 抽象主题角色: 声明了代理和真实主题角色的共同接口, 客户端是针对抽象主体角色编程的.
  • 代理主题角色: 在抽象主体的基础上, 还可以实现一些新的功能, 同时保存了一个真实主题角色的指针(其实保存一个抽象主体角色的指针也行).
  • 真实主题角色: 实现了抽象主题角色的接口

LOG功能就是一个代理模式. 先打印出来调用时间, 然后再真实的调用实际的函数


优点: 增加新功能时没有动抽象主题角色, 降低系统耦合度, 符合开闭原则

缺点: 让系统变慢

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

推荐阅读更多精彩内容