有同事很喜欢用Context模式,觉得是自己"首创", 我有些自己的想法, 或者大家可以发表下自己的观点。
 
什么是Context模式?

23种设计模式中没有这个模式, 是同事自己命名的, 我觉得名字也挺合理。

Context模式首先要满足的条件是类都是基于COM思想IUnknown接口
继承于IUnknown有2个基本接口, 一个是IContext, 另外一个是IComponent
IContext的作用是保存一个Map, 里面存有接口IID和接口指针的映射关系
IComponent的作用是保存一份对IContext的引用, 通过IContext它可以查询到任何保存在里面的接口
任何比较" 大型“的接口和对象都从IComponent继承,并在对象初始化时把自己存入IContext,
这种设计的好处就是我们在实现对象时可以查询到任何我们需要的接口。

大概类图如下:

 

上面的设计好处很明显, 就是使用简单, 任何接口我们都可以查询到, 我们在写程序时应该有这样的体验, 往往需要一个全局的CXXXApp对象实例, 然后我们可以通过这个对象实例, 一层层往下查询到其他的对象和接口, MFC就是这么做的。如果我们用上面这个模式, 我们就不需要依赖于某个全局对象了, 因为我们继承的IComponent接口本身就有查询其他对象的能力了。
 
但这样的设计也有一些缺陷:

首先是多实例支持不了了, 因为我们根据接口ID来查询某个对象指针,一个接口实现类的多个实例没法存到IContext中; 多个类可以实现同一接口, 这些类实例对象也没法存储多个。COM里面除了IID, 还有CLSID来标志实现类。

其次是耦合性, 尽管耦合是基于接口耦合, 依赖性已经降到最低,但是还是在原本不需要耦合的地方产生了耦合, 把别人用不到接口暴露给他了。
最后是复杂性, 因为IContext里什么都可以查询到, 所以我们会在不经意间什么都向它要, 将原本设计时的单向依赖变成双向依赖, 最后演变成复杂的网状依赖, 最后对代码彻底失去控制
 
究竟什么时候该用这个模式? 我个人的建议是在小模块内部使用。

模块划分首先强调层次性, 就是 单向依赖, 上层依赖于下层, 积木式的层层堆砌。如果在模块间传递Context指针, 很快会变成网状依赖, 对程序失去控制, 谁知道别人拿了你这个IContext指针查询了那些接口, 最后干嘛去了。

大模块内部,除非模块内部层次很清楚, 你能很好的控制。一般我们也不建议使用Context模式, 因为不知不觉就会造成复杂的网状依赖,会对程序就会失去控制。
 
对于对象和接口间的依赖,不知道大家是怎么解决的? 我想大部分人应该是通过全局对象或是显式的传递需要的接口指针来做的。
对于Context模式,大家怎么看?
posted on 2013-11-22 23:29 Richard Wei 阅读(2301) 评论(2)  编辑 收藏 引用 所属分类: 设计模式

FeedBack:

 
# re: 关于 "Context" 模式
2013-11-23 08:58 | 万连文

IServiceProvider->IService->IComponent

小模块更明确直接使用最终的组件,大模块需要能拿到全局的IServiceProvider以便调用需要的服务。总之需要权衡,度的拿捏是架构关键。  回复  更多评论
  

# re: 关于 "Context" 模式
2013-11-23 14:11 | Richard Wei

@万连文
嗯,确实度是关键, 实际上怎样才算一个模块? 它的粒度可以是个小的静态Library, 也可能是个庞大的Service。最关键的就是要保持模块的独立性和层次性,避免形成网状依赖。
  回复  更多评论

http://www.cppblog.com/weiym/archive/2013/11/22/204392.html

关于 "Context" 模式(基于COM思想IUnknown思想)的更多相关文章

  1. 设计模式:Context模式

    作者:吴香伟 发表于 2014/09/12 版权声明:可以任意转载,转载时务必以超链接形式标明文章原始出处和作者信息以及版权声明 Ceph实现中使用了大量派生于Context抽象类的子类,用法简单却很 ...

  2. 认识Web前端、Web后端、桌面app和移动app新开发模式 - 基于Node.js环境和VS Code工具

    认识Web.桌面和移动app新开发模式 - 基于Node.js环境和VS Code工具 一.开发环境的搭建(基于win10) 1.安装node.js和npm 到node.js官网下载安装包(包含npm ...

  3. 《UML和模式应用》重点之思想篇

    本书是帮助开发人员和学生学习面向对象分析和设计(OOA/D)的核心技能的重要工具. UML不是OOA/D.也不是方法,仅仅是图形表示法,假设没有真正掌握怎样创建优秀的面向对象设计,或者怎样评估和改进现 ...

  4. U3D 飞机大战(MVC模式)解析--面向对象编程思想

    在自己研究U3D游戏的时候,看过一些人的简单的游戏开发视频,写的不错,只是个人是java web 开发的人,所以结合着MVC思想,对游戏开发进行了一番考虑. 如果能把游戏更加的思想化,分工化,开发便明 ...

  5. 基于 CSP 的设计思想和 OOP 设计思想的异同

    LinkerLin Go语言推崇的CSP编程模型和设计思想,并没有引起很多Go开发者包括Go标准库作者的重视.标准库的很多设计保留了很浓的OOP的味道.本篇Blog想比较下从设计的角度看,CSP和OO ...

  6. 求两个数之间的质数 -----------基于for循环 算法思想

    前端代码: <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.as ...

  7. Delphi 基于组件的编程思想

  8. “多团队大规模”开发模式 - 基于SAP HANA平台的多团队产品研发

    应用SAP HANA “官方”开发模式的伙伴们在转到“多团队大规模”开发模式时会遇到各式各样的心理不适应的状况,各种纠结.比如GIT Repository和HANA Repository冲突什么的. ...

  9. SAP HANA 开发模式 - 基于SAP HANA平台的多团队产品研发

    “基本”开发模式 Windows: Unix/Linux: 在基本模式下我们可以通过regi来进行激活我们的object.Regi是一个类git功能的,方便和HANA repository交互的一个命 ...

随机推荐

  1. qt之treeview例子

    # -*- coding: utf-8 -*- # python:2.x __author__ = 'Administrator' from PyQt4.Qt import * from PyQt4. ...

  2. DB2 递归

    公司一直用递归来生成组织机构的树状图.看了上面的文档,应该立马就能写了. 不过前几天,有个功能涉及到下面的状况: 需要组织机构等级为1级的下面所有子机构.且按照一级组织机构分组.大家都觉得很难,哥就一 ...

  3. 机器学习笔记——K-means

    K-means是一种聚类算法,其要求用户设定聚类个数k作为输入參数,因此,在执行此算法前,须要预计须要的簇的个数. 如果有n个点,须要聚到k个簇中.K-means算法首先从包括k个中心点的初始集合開始 ...

  4. 更改Zend Studio/Eclipse代码风格主题

    最近决定把几个IDE的代码样式统一一下,Visual Studio的还算好改,PHP目前用得不多,不过也打算给Zend Studio换身新装. 网上搜索的一些更改Zend Studio主题的多是修改或 ...

  5. ubuntu12.04软件中心打开错误和 ubuntu 包管理之“:E: 读错误 - read (5: 输入/输出错误) E: 无法解析或打开软件包的列表或是状态文件。”的解决

    执行ubuntu软讲中心时打不开.老是崩溃,从终端也下载不了软件. 执行包管理的update或者search等等会报错: E: 读错误 - read (5: 输入/输出错误) E: 无法解析或打开软件 ...

  6. Hadoop安装测试简单记录

    安装的节点如下:1个namenode.1个hiveserver.3个dataNode192.168.1.139   namenode1192.168.1.146   hiveserver 192.16 ...

  7. 人工智能2:智能Agent

    一.Agent基本定义 基于理性行为的Agent是本书人工智能方法的核心.Agent由传感器.执行器两个重要元件组成,具有与环境交互的能力,其能力是通过分析感知序列,经过Agent函数映射到相应的行动 ...

  8. 反编译 APKTool 逆向助手

    最佳实践--Android逆向助手 1.点击"反编译apk,完成后res下的所有资源就都可以正常使用了,相当于apktool的功能------目前已失效,但是直接用rar解压是可以的!2.点 ...

  9. ASP.NET-FineUI开发实践-6(二)

    1.上回说到修改以前的会出现好几个5: 这是因为新增时是只新增到最后一行,所以点击选好了就跑到最后一行了,而且行号不会累积,只加到初始化的行号. 其实js里是有插入的,例子里可以插入到第一行,新增是a ...

  10. hdu 2156

    #include <iostream> #include <stdio.h> using namespace std; int main() { int i,n; while( ...