设万维读者为首页 万维读者网 -- 全球华人的精神家园 广告服务 联系我们 关于万维
 
首  页 新  闻 视  频 博  客 论  坛 分类广告 购  物
搜索>> 发表日志 控制面板 个人相册 给我留言
帮助 退出
茶树油之家  
与大家交流和分享苹果产品、网络技术,以及美乐家茶树油及相关的信息  
https://blog.creaders.net/u/588/ > 复制 > 收藏本页
网络日志正文
编程技巧探讨:为什么DI很重要? 2011-04-17 21:42:49
上一周,我们工作小组中有人问我一个问题:为什么DI(Dependency Injection,依靠性元插入的模式,这是编程中常用的一种模式)十分重要?现在许多编程人员采用OO(Object Oriented,目标编程)的方式。他们以为在一个class中定义数据和接口,将程序中的逻辑包含在其中就足够了。他们困惑地提出疑问,什么是DI,为什么还要采用DI模式?

第二天,我碰到单位中一位资深的编程员,我向他问了一个类似的问题,并问他具体怎么使用的。他说他只是在对原程序的测试中采用DI,在测试中假设有关读写数据库的变元,这样不会真正对数据库产生影响。这是测试中常用的方法,但这并不说明DI的全部。实际上,DI是一个非常重要的概念,而且是编程中常用的一种策略。

用一个形象的比喻,公司里IT部门需要采购部门购买一些硬件,IT按照要求将批准的单子交给采购部门,IT部门不感兴趣采购部门的谁去完成这个任务,也不需要了解,部门之间只需要按照之间的交接口进行联系和交流。DI编程模式就是按照这样的方式来编程,“部门”之间不需要知道谁在做具体的工作。

我回忆起我过去所写的许多项目,并查看我过去的程序。在这里我对此用一个简单的例子作具体的解释。先看看下面的一个C#例子:

public class MyDataReader {
  ...

  public bool ReadData() {
    var dbService = new MyDbService();
    ....
    var data = dbService.GetObject();
    ....
  }
}

上面有问题的地方是dbService变元由MyDbService class产生的一行,这种采用new来指定特定class的方式在编程中普遍存在。很明显MyDataReader class依赖于MyDbService class。换言之,MyDataReader知道所需要的dbService是从那一个class产生的。MyDataReader有必要知道具体创建的class吗?它只是使用一数据服务通过其接口取得数据(如GetObject()接口),它并不需要知道数据是如何取得的,那么它关心具体服务的class有必要吗?如果能够将这种依赖性分隔,让一个中介来提供一个数据服务变元,这样不就更好吗?

现在我们来看看下面改进的编码:

public class MyDataReader {
  ...

  public bool ReadData() {
    var dbService = DIContainer.GetInstance<IDBService>();
    ....
    var data = dbService.GetObject();
    ....
  }
}

这里只是一个小小的改动,DIContainer作为一个中介,通过它的接口GetInstance指定所需要的变元,这个变元具有抽象界面定义IDBService即可。DIContainer就像一个黑匣子,它知道如果根据要求的服务提供具体class的变元。这就是DI的典型应用例子。如果MyDataReader需要从不同的数据源取数据,将来MyDataReader根本不需要改动,只要告诉DIContainer即可。 这个服务元可能是从MyDbService,也可能是通过类似别的class如SqlDbService或OracleDbService。

由此可见,采用DI模式可以带来很多的好处。具体采用什么样的DI平台,如果设计和给DI提供不同Interface和具体class的相互对应关系,这些都超出本文的内容了,我在我的其它博客文(在blogger的英文博客, under "Design Pattern" tag)中有详细叙述。

现在有关DI的编程模式有许多,我个人认为,作为一个熟练的编程人员,应该学习和掌握这方面的知识,这样就可以写出更好、更干净、可维护和扩展的应用程序。在学习之前,首先要明白DI的道理,解决什么类型的问题,这样就容易理解DI的重要性和各种DI是如何解决这类问题的。如果你能熟练地运用DI技术,你的编程技术将会是高人一筹,而且如果你将来工作有这方面的要求,你将不会面对天书而一头雾水。


本文为我试图用万维网博客写技术方面(我在新浪博客上也做了成功的尝试)的一个尝试,万维网博客提供有限的界面,但提供源代码接口,这样就可以直接通过HTML码加入我所需要的基本功能。我今天写了一篇英文博客,以此为蓝本,我成功地复制成中文版的技术博文,编码带有不同的颜色,花的功夫不太大,这次尝试看来是成功的。
浏览(1499) (0) 评论(2)
发表评论
文章评论
作者:茶树油之家 留言时间:2011-05-18 09:30:56
In order for my app to get the instances needed, there must be, first, a place to do the configuration and class mapping, and secondly, an API to get instances. DIContainer is my magic box. This is my proposed architecture for the DI implementation.

The basic logic of DI is to delegate the knowledge of how to create instances to a magic box, such as a container or service. This container is a generic one for all various instances I need for my app. The example codes in my blog show to get instance of IDBService. I could extend it to get instances like logger, data process and others.

If you need to get new or different instances from the container, DIContainer is the only place to change. In addition to that, in my practice of DI, I found this DI wrapper class is very flexible. For example, initially, I used StructureMap and String.Net as my engine for interface to class mapping, later I switched to Microsoft MEF. I only changed the DIContainer library for this update, all my app and other libraries are changed at atll sine my DIContainer's APIs have not changed at all.

By the way, I updated my blog with correction of my codes.
回复 | 0
作者:bfbx 留言时间:2011-05-11 11:58:43
In this example, you removed MyDataReader's dependency on MyDbService. But you introduced a new dependency on DIContainer.

The DI way of doing this is to create a pair of getDbService() and setDbService(IDbService dbService). At runtime you call setDbService(IDbService dbService) to inject the dependency before it's used.
回复 | 0
我的名片
茶树油之家
来自: 加拿大
注册日期: 2007-01-19
访问总量: 508,747 次
点击查看我的个人资料
Calendar
最新发布
· ZOOM 會議:iOS 平台上的軟件開
· 專注做一件事是最好的擺脫
· 我的 iOS app 更新了
· 有關老面製作的問與答(三)
· 從Legacy 小道,我重新開始了跑
· 從Legacy 小道,我重新開始了跑
· 為準備馬拉松長跑的第一次嘗試
分类目录
【社会公益】
· 飄香茉莉 - 李靖惠
· 天使的恩賜
· 經典京劇『鎖麟囊』
· 挑戰自己:參加2013卡爾加里馬拉
· 梦想合唱团大聚会与奥运梦想
· 中央电视台的梦想合唱团公益活动
【WWDC】
· 學習WWDC 2017
· 學習WWDC 2015
· 網上學習:WWDC 2013視頻講座
· WWDC 2013技術講座視頻
· WWDC 2012笔记(4)
· WWDC2012的学习笔记(3)
· WWDC 2012的学习笔记(2)
· WWDC 2012的学习笔记(1)
· WWDC2011视频的学习笔记(21)
· WWDC2011视频的学习笔记(19)
【网络安全】
· Heartbleed網絡安全漏洞
· 苹果小技巧:如何在PDF文件上加
· 警惕你的苹果礼物卡被窃
· 苹果用户的独特免疫能力
· 苹果发布安全更新2011-003
· 最新的微软IE漏洞和劫持Cookie的
· 新的恶意软件第二番攻击苹果
· 新的恶意软件开始攻击苹果
【生活与健康】
· 有關老面製作的問與答(三)
· 從Legacy 小道,我重新開始了跑
· 從Legacy 小道,我重新開始了跑
· 為準備馬拉松長跑的第一次嘗試
· 張宏文與西班牙華人的醫療諮詢
· 有關老面製作的問與答(二)
· 美麗的洛基山脈
· 有關老面製作的問與答(一)
· 我為什麼喜歡蘋果
· 加拿大抗新冠病毒動態 2020.4.16
【TED视频】
· 請求的藝術
· TED有關兩種不同政治制度的精彩
· 游擊隊方式的城市菜園
· 玩游戏可以多活十年
· 中毒宝宝
· 中美关系不需要多一个律师
· TED视频:脆弱的力量
· TED视频精选:戴维·卡梅伦论政府
· TED视频:为什么SOPA是一个馊主
· TED视频:失败是成功之母
【海外生活】
· 從Legacy 小道,我重新開始了跑
· 從Legacy 小道,我重新開始了跑
· 為準備馬拉松長跑的第一次嘗試
· 張宏文與西班牙華人的醫療諮詢
· 有關老面製作的問與答(二)
· 美麗的洛基山脈
· 有關老面製作的問與答(一)
· 我為什麼喜歡蘋果
· 加拿大抗新冠病毒動態 2020.4.16
· 加拿大抗新冠病毒動態 2020.4.16
【网络服务】
· 專注做一件事是最好的擺脫
· 谷歌帳號和相應的雲服務
· 用圖像和風格語言css 定義數字章
· 网络服务:计算型知识引擎服务
· 如何优化图像所占用的空间
· 用视觉方式快速算算数
· 新浪【船过水无痕】的博文,非常
· 苹果的云服务iCloud与谷歌的云服
· 新浪微博对话实例
· 使用网络翻译服务,写中文博客
【软件开发】
· ZOOM 會議:iOS 平台上的軟件開
· 專注做一件事是最好的擺脫
· 我的 iOS app 更新了
· iOS App: TapToCount - 3W
· 第一个iOS app 的里程碑
· TestFlight - 蘋果iOS app測試的
· 24點的算法
· 學習WWDC 2015
· 漢字聽寫大會-電腦書寫輸入法
· WWDC2012的学习笔记(3)
【我爱苹果】
· ZOOM 會議:iOS 平台上的軟件開
· 我為什麼喜歡蘋果
· iOS App: TapToCount - 3W
· 為武漢发生COVID-19疫情做一點貢
· 第一个iOS app 的里程碑
· 创作app的乐趣
· 你知道你的睡覺節奏規律嗎?
· 學習WWDC 2017
· 點擊計數 - 記住隨時隨地的點滴
· 學習WWDC 2015
【网络技术】
· 專注做一件事是最好的擺脫
· 如何用 Blogger 邀请朋友共同写
· 今天是3.14日,以及VIM的強大區
· 探討:採用QR碼快速連接Wi-Fi
· 互聯網+和微信
· 写博客的体会
· WA实例:分数的计算
· 如何将XML内容用HTML格式表述
· 如何优化图像所占用的空间
· 谷歌博客更新:增加动态放大图像
【茶树油】
· 有關老面製作的問與答(三)
· 茶樹精油消毒殺菌的熏蒸法
· 新冠病毒核酸檢測之淺解
· 倡議:聯合海外華人寫抗疫日記
· 茶树精油新用法:消毒和清洁面部
· 為關心COVID-19疫情寫的小詩
· 為武漢发生COVID-19疫情做一點貢
· 2018,达到一万公里里程碑!
· Melaleuca 2017/12/26 年銷售額
· 跑步里程達到八千公里
存档目录
2020-05-11 - 2020-05-21
2020-04-04 - 2020-04-23
2020-03-01 - 2020-03-31
2020-01-07 - 2020-01-25
2019-03-20 - 2019-03-20
2019-02-09 - 2019-02-09
2018-12-31 - 2018-12-31
2018-05-18 - 2018-05-18
2017-12-09 - 2017-12-26
2017-10-19 - 2017-10-19
2017-09-06 - 2017-09-06
2017-08-17 - 2017-08-17
2017-06-07 - 2017-06-28
2017-04-12 - 2017-04-28
2017-03-31 - 2017-03-31
2017-02-22 - 2017-02-22
2017-01-18 - 2017-01-23
2016-10-25 - 2016-10-25
2016-03-21 - 2016-03-21
2016-02-01 - 2016-02-17
2016-01-12 - 2016-01-22
2015-12-04 - 2015-12-11
2015-11-19 - 2015-11-24
2015-10-14 - 2015-10-14
2015-08-05 - 2015-08-05
2015-07-24 - 2015-07-24
2015-04-06 - 2015-04-24
2015-03-14 - 2015-03-18
2015-02-05 - 2015-02-05
2015-01-20 - 2015-01-20
2014-12-13 - 2014-12-13
2014-11-13 - 2014-11-13
2014-10-01 - 2014-10-10
2014-09-01 - 2014-09-24
2014-08-07 - 2014-08-29
2014-07-11 - 2014-07-31
2014-06-23 - 2014-06-23
2014-05-02 - 2014-05-31
2014-04-20 - 2014-04-27
2014-02-14 - 2014-02-14
2014-01-06 - 2014-01-29
2013-12-02 - 2013-12-30
2013-11-06 - 2013-11-18
2013-10-12 - 2013-10-30
2013-09-03 - 2013-09-03
2013-08-01 - 2013-08-23
2013-07-05 - 2013-07-30
2013-06-03 - 2013-06-14
2013-04-03 - 2013-04-30
2013-03-07 - 2013-03-30
2013-02-18 - 2013-02-23
2012-12-05 - 2012-12-25
2012-11-08 - 2012-11-25
2012-10-05 - 2012-10-18
2012-09-26 - 2012-09-26
2012-08-03 - 2012-08-25
2012-07-07 - 2012-07-27
2012-06-01 - 2012-06-28
2012-05-01 - 2012-05-27
2012-04-08 - 2012-04-27
2012-03-03 - 2012-03-31
2012-02-07 - 2012-02-29
2012-01-15 - 2012-01-27
2011-12-03 - 2011-12-20
2011-11-02 - 2011-11-22
2011-10-01 - 2011-10-30
2011-09-03 - 2011-09-24
2011-08-01 - 2011-08-31
2011-07-01 - 2011-07-30
2011-06-01 - 2011-06-29
2011-05-01 - 2011-05-31
2011-04-02 - 2011-04-30
2007-01-19 - 2007-01-19
 
关于本站 | 广告服务 | 联系我们 | 招聘信息 | 网站导航 | 隐私保护
Copyright (C) 1998-2024. Creaders.NET. All Rights Reserved.