有同事很喜欢用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. Dockerfile制作sshd镜像

    For Centos Shell脚本: # vim Dockerfile # mkdir /data01/sshd # vi Dockerfile # sshd # # VERSION 0.0.2 F ...

  2. JNI调用native方法出现 java.lang.UnsatisfiedLinkError: XXXclass.XXXmethod()异常的解决办法

    昨天拿到JNI的Android工程Demo,然后把demo整合到开发的主线工程上,发现调用JNI方法一直抛同一个异常 java.lang.UnsatisfiedLinkError: XXXclass. ...

  3. 设计模式--迪米特法则(Lod/LKP)

    迪米特法则:(Law of Demeter, LoD),也称最少知识原则(Least Knowledge Principle, LKP) 理解:      假设两个类不必彼此直接通信,那么这两个类就不 ...

  4. c# linq的一些运用

    最近在学习xml.linq 网上也找了一些资料都不大全面,因此在这写了一点东西和大家分享,由于本人知识有限,如有错误请指证 可扩展标记语言,标准通用标记语言的子集,一种用于标记电子文件使其具有结构性的 ...

  5. Hadoop安装测试简单记录

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

  6. Genymotion 模拟器 VirtualBox

    准备 介绍: 1.Genymotion安卓模拟器其实不是普通的模拟器,严格来说,genymotion是虚拟机,被网传定义为模拟器,加载APP的速度比较快,操作起来也很流畅.2.Genymotion依赖 ...

  7. 安装Linux和Windows的双系统

    平时使用较多的操作系统是Windows,想玩玩Linux平时也是在虚拟机上,强迫症的怎么能忍,一直想装个双系统,也能强迫自己练习Linux命令,之前重装系统的时候也试着装了一下,但是准备不够充分.结果 ...

  8. Mysql group_concat

    select p.id,p.parent_id,group_concat(distinct(CONCAT("分类名称:",c.name)) order by c.id desc s ...

  9. spring的xml的property和constructor-arg的解析

    参考文档: http://zzy7182.iteye.com/blog/1153473

  10. Error: theForm.submit is not a function !!

    theForm.submit is not a function 调试了半天,才发现范了低级错误. 页面中有一个按钮ID 是 submit 而引发的错误. 引出的问题是页面上的元素命名范围不能是 wi ...