﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>博客园-专家区</title><link>http://www.cnblogs.com/expert/</link><description>程序员的网上家园</description><language>zh-cn</language><lastBuildDate>Fri, 05 Dec 2008 10:14:03 GMT</lastBuildDate><pubDate>Fri, 05 Dec 2008 10:14:03 GMT</pubDate><ttl>60</ttl><item><title>[WCF的Binding模型]之五：绑定元素（Binding Element）</title><link>http://www.cnblogs.com/artech/archive/2008/12/05/1348622.html</link><dc:creator>Artech</dc:creator><author>Artech</author><pubDate>Fri, 05 Dec 2008 09:24:00 GMT</pubDate><guid>http://www.cnblogs.com/artech/archive/2008/12/05/1348622.html</guid><wfw:comment>http://www.cnblogs.com/artech/comments/1348622.html</wfw:comment><comments>http://www.cnblogs.com/artech/archive/2008/12/05/1348622.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/artech/comments/commentRss/1348622.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/artech/services/trackbacks/1348622.html</trackback:ping><description><![CDATA[摘要: 在上面的内容中，先后介绍了信道、信道管理器、信道监听器和信道工厂。从对象的创建来讲，信道管理器是信道的创建者。说的再具体点，客户端的信道通过信道工厂创建，服务端的信道通过信道监听器创建。但是信道工厂和信道监听器又是如果被创建出来的呢？

我们在一开始就已经说过，作为终结点三要素的绑定对象实现了所有的通信细节，并且通过创建信道栈实现了消息的传递。从这一点来说，绑定对象无疑是信道层所有通信对象的最终缔造者，所以信道工厂和信道监听器最终的创建都是靠绑定对象实现的。关于这个创建过程又和另一个重要的对象密切相关，那就是绑定元素。
&nbsp;&nbsp;<a href='http://www.cnblogs.com/artech/archive/2008/12/05/1348622.html'>阅读全文</a><img src ="http://www.cnblogs.com/artech/aggbug/1348622.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/43812/" target="_blank">[新闻]Google操作系统已开始内部测试？</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>[WCF的Binding模型]之四：信道工厂（Channel Factory）</title><link>http://www.cnblogs.com/artech/archive/2008/12/05/1348618.html</link><dc:creator>Artech</dc:creator><author>Artech</author><pubDate>Fri, 05 Dec 2008 09:11:00 GMT</pubDate><guid>http://www.cnblogs.com/artech/archive/2008/12/05/1348618.html</guid><wfw:comment>http://www.cnblogs.com/artech/comments/1348618.html</wfw:comment><comments>http://www.cnblogs.com/artech/archive/2008/12/05/1348618.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/artech/comments/commentRss/1348618.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/artech/services/trackbacks/1348618.html</trackback:ping><description><![CDATA[摘要: 由于信道管理器在客户端和服务端所起的不同作用，分为信道监听器和信道工厂。和服务端的信道监听其相比，处于客户端的信道工厂显得简单。从名称就可以看得出来，信道工厂的作用就是单纯的创建用于消息发送的信道。我们先来看看与信道工厂相关的一些接口和基类的定义。&nbsp;&nbsp;<a href='http://www.cnblogs.com/artech/archive/2008/12/05/1348618.html'>阅读全文</a><img src ="http://www.cnblogs.com/artech/aggbug/1348618.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/43811/" target="_blank">[新闻]Google阅读器界面升级 全新改版</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>微软一家人---在云端运行的ServiceBus</title><link>http://www.cnblogs.com/daizhj/archive/2008/12/04/1347447.html</link><dc:creator>代震军</dc:creator><author>代震军</author><pubDate>Thu, 04 Dec 2008 03:57:00 GMT</pubDate><guid>http://www.cnblogs.com/daizhj/archive/2008/12/04/1347447.html</guid><wfw:comment>http://www.cnblogs.com/daizhj/comments/1347447.html</wfw:comment><comments>http://www.cnblogs.com/daizhj/archive/2008/12/04/1347447.html#Feedback</comments><slash:comments>13</slash:comments><wfw:commentRss>http://www.cnblogs.com/daizhj/comments/commentRss/1347447.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/daizhj/services/trackbacks/1347447.html</trackback:ping><description><![CDATA[摘要:      TECHED2008大会已过去了快一个月了，在大会上所看到的关于 Azure的介绍至今还在头脑中不时出现。当然我本人不是什么云计算的狂热支持者，到如今我的观点也与蔡学镛先生的差不多，就是关注加观望（以免在云端一脚踏空摔下来）。另外就是我对云的兴趣目前也仅限在SDS和NetServiceBus这两方面。其中对服务总线一直感到很好奇，这一点在我之前的一篇文章中已做了一些说明。今天的这篇文章主要是从流程上了解一下如何运行（或调试一个运行在云端ServiceBus中的service）.通过它，可以对Azure的服务总线的工作原理有一个初步的认识。
&nbsp;&nbsp;<a href='http://www.cnblogs.com/daizhj/archive/2008/12/04/1347447.html'>阅读全文</a><img src ="http://www.cnblogs.com/daizhj/aggbug/1347447.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/43810/" target="_blank">[新闻]微软官方下载：Windows Vista SP2 Beta测试版</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>WinHEC 2008 China</title><link>http://www.cnblogs.com/cathsfz/archive/2008/12/03/1347018.html</link><dc:creator>Cat Chen</dc:creator><author>Cat Chen</author><pubDate>Wed, 03 Dec 2008 12:28:00 GMT</pubDate><guid>http://www.cnblogs.com/cathsfz/archive/2008/12/03/1347018.html</guid><wfw:comment>http://www.cnblogs.com/cathsfz/comments/1347018.html</wfw:comment><comments>http://www.cnblogs.com/cathsfz/archive/2008/12/03/1347018.html#Feedback</comments><slash:comments>18</slash:comments><wfw:commentRss>http://www.cnblogs.com/cathsfz/comments/commentRss/1347018.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/cathsfz/services/trackbacks/1347018.html</trackback:ping><description><![CDATA[摘要: 今天是WinHEC第一天。WinHEC就是Windows Hardware Engineering Conference，中文名是做Windows硬件工程大会。昨晚紫柔告诉我9:00到场签到就可以了，因为9:30正式开始，但我早上还是忍不住多睡了一会儿，所以10:00才到场。当时还是张亚勤的演讲，我进入主会场后迅速找到剩余的几个空位坐下来了。张亚勤的演讲当然紧接着若干个demo，其中Surface&nbsp;&nbsp;<a href='http://www.cnblogs.com/cathsfz/archive/2008/12/03/1347018.html'>阅读全文</a><img src ="http://www.cnblogs.com/cathsfz/aggbug/1347018.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/43809/" target="_blank">[新闻]微软发布PC Live单机游戏客户端</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>ADO.NET Entity Framework支持多Provider</title><link>http://www.cnblogs.com/unruledboy/archive/2008/12/02/adonetefproviders.html</link><dc:creator>灵感之源</dc:creator><author>灵感之源</author><pubDate>Tue, 02 Dec 2008 08:39:00 GMT</pubDate><guid>http://www.cnblogs.com/unruledboy/archive/2008/12/02/adonetefproviders.html</guid><wfw:comment>http://www.cnblogs.com/unruledboy/comments/1346022.html</wfw:comment><comments>http://www.cnblogs.com/unruledboy/archive/2008/12/02/adonetefproviders.html#Feedback</comments><slash:comments>8</slash:comments><wfw:commentRss>http://www.cnblogs.com/unruledboy/comments/commentRss/1346022.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/unruledboy/services/trackbacks/1346022.html</trackback:ping><description><![CDATA[摘要: 前言EF跟其它ORM的做法不一样，其它ORM是先有Model再自动维护数据库，EF是先有数据库再自动(目前只能手工重建来达到“刷新”的目的)维护Model的。相比其它ORM，EF最要命的是目前不“内置”切换Provider的支持。但微软的开发人员给我们提供了以下思路：参考代码：http://code.msdn.microsoft.com/EFQuerySamples参考文章：http://foru&nbsp;&nbsp;<a href='http://www.cnblogs.com/unruledboy/archive/2008/12/02/adonetefproviders.html'>阅读全文</a><img src ="http://www.cnblogs.com/unruledboy/aggbug/1346022.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/43808/" target="_blank">[新闻]Firefox遭“独家”恶意软件攻击</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>用 Chiron 运行 IronPython 编写的 Silverlight 程序</title><link>http://www.cnblogs.com/RChen/archive/2008/12/02/1345643.html</link><dc:creator>木野狐(Neil Chen)</dc:creator><author>木野狐(Neil Chen)</author><pubDate>Tue, 02 Dec 2008 04:03:00 GMT</pubDate><guid>http://www.cnblogs.com/RChen/archive/2008/12/02/1345643.html</guid><wfw:comment>http://www.cnblogs.com/RChen/comments/1345643.html</wfw:comment><comments>http://www.cnblogs.com/RChen/archive/2008/12/02/1345643.html#Feedback</comments><slash:comments>5</slash:comments><wfw:commentRss>http://www.cnblogs.com/RChen/comments/commentRss/1345643.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/RChen/services/trackbacks/1345643.html</trackback:ping><description><![CDATA[摘要: Silverlight Dynamic Languages SDK 目前 host 在 CodePlex 上，使用它可以用 IronPython/IronRuby/Managed JScript 等动态语言编写 Silverlight 程序，其项目的主页在：http://www.codeplex.com/sdlsdk我做了一些尝试，发现要实际用来开发点东西，还是有不少需要注意的地方，特别是程序集引&nbsp;&nbsp;<a href='http://www.cnblogs.com/RChen/archive/2008/12/02/1345643.html'>阅读全文</a><img src ="http://www.cnblogs.com/RChen/aggbug/1345643.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/43806/" target="_blank">[新闻]Python 3.0正式发布</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>D2（前端技术论坛）上海站参后感（附照片）</title><link>http://www.cnblogs.com/JustinYoung/archive/2008/12/02/shanghai-d2.html</link><dc:creator>阿一(杨正祎)</dc:creator><author>阿一(杨正祎)</author><pubDate>Tue, 02 Dec 2008 03:24:00 GMT</pubDate><guid>http://www.cnblogs.com/JustinYoung/archive/2008/12/02/shanghai-d2.html</guid><wfw:comment>http://www.cnblogs.com/JustinYoung/comments/1345600.html</wfw:comment><comments>http://www.cnblogs.com/JustinYoung/archive/2008/12/02/shanghai-d2.html#Feedback</comments><slash:comments>18</slash:comments><wfw:commentRss>http://www.cnblogs.com/JustinYoung/comments/commentRss/1345600.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/JustinYoung/services/trackbacks/1345600.html</trackback:ping><description><![CDATA[摘要: <center><img src="http://downloads.cnblogs.com/justinyoung/articleIMG/2008d4/d2_728x90.jpg"/></center>
D2是淘宝网内部讨论发展而成的国内前端设计、开发者论坛。现在已经是第三届了。从现场的参加者来看，算的上是有声有色了。不容易呀！特别是它的建立思想和出发点。也算是给前台设计、开发者办了大好事呀。
说实话，这次D2会议很多演讲并不算成功。很多话题让人感到索然无味，倒是右面的大屏幕成了大家聊天逗趣的场所。当然，也有可能是时间有限的原因，很多话题没有展开吧。&nbsp;&nbsp;<a href='http://www.cnblogs.com/JustinYoung/archive/2008/12/02/shanghai-d2.html'>阅读全文</a><img src ="http://www.cnblogs.com/JustinYoung/aggbug/1345600.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/43805/" target="_blank">[新闻]JavaFX千呼万唤始出来</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>微软同步框架(MSF)入门之七--定制同步提供程序(SyncProvider)</title><link>http://www.cnblogs.com/daizhj/archive/2008/12/02/1339869.html</link><dc:creator>代震军</dc:creator><author>代震军</author><pubDate>Tue, 02 Dec 2008 01:07:00 GMT</pubDate><guid>http://www.cnblogs.com/daizhj/archive/2008/12/02/1339869.html</guid><wfw:comment>http://www.cnblogs.com/daizhj/comments/1339869.html</wfw:comment><comments>http://www.cnblogs.com/daizhj/archive/2008/12/02/1339869.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cnblogs.com/daizhj/comments/commentRss/1339869.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/daizhj/services/trackbacks/1339869.html</trackback:ping><description><![CDATA[摘要:     在上一篇文章当中，简要介绍了一下如何使用现有的 SyncProvider 对象来进行文件（夹）同步。今天的这个DEMO主要演示通过继承方式来实现自己的SyncProvider来进行相关同步元数据存储，当然这样做会给我们以额外的好处，比如按自己的意愿来创建、版本和删除项的信息等。另外就是对同步应用程序的工作原
理也会有一个大概的认识。&nbsp;&nbsp;<a href='http://www.cnblogs.com/daizhj/archive/2008/12/02/1339869.html'>阅读全文</a><img src ="http://www.cnblogs.com/daizhj/aggbug/1339869.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/43804/" target="_blank">[新闻]Moonlight: Linux 平台下的 Silverlight</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>[从设计到架构]第四回：依赖的哲学（上）</title><link>http://www.cnblogs.com/anytao/archive/2008/12/02/anytao_design_04_couplingphilosophy.html</link><dc:creator>Anytao</dc:creator><author>Anytao</author><pubDate>Mon, 01 Dec 2008 16:16:00 GMT</pubDate><guid>http://www.cnblogs.com/anytao/archive/2008/12/02/anytao_design_04_couplingphilosophy.html</guid><wfw:comment>http://www.cnblogs.com/anytao/comments/1345389.html</wfw:comment><comments>http://www.cnblogs.com/anytao/archive/2008/12/02/anytao_design_04_couplingphilosophy.html#Feedback</comments><slash:comments>55</slash:comments><wfw:commentRss>http://www.cnblogs.com/anytao/comments/commentRss/1345389.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/anytao/services/trackbacks/1345389.html</trackback:ping><description><![CDATA[<p><strong><a href="http://book.anytao.com/"><strong><font color="#ff0000">《你必须知道的.NET》网站</font></strong></a></strong> | <strong><font color="#0000ff"><a href="http://www.anytao.com/">Anytao技术博客</a>&nbsp; </font></strong></p>
<h2 align="center"><font color="#0000ff" face="微软雅黑" size="6">[从设计到架构]第四回：依赖的哲学（上）</font></h2>
<p align="right"><font face="微软雅黑">发布日期：2008.12.02 作者：</font><a href="http://about.anytao.com/"><font face="微软雅黑">Anytao</font></a>
<br />
<font color="#ff0000" face="微软雅黑">&#169; 2008 </font><a href="http://www.anytao.com/"><font color="#ff0000" face="微软雅黑">Anytao.com</font></a><font color="#ff0000" face="微软雅黑"> ，Anytao原创作品，转贴请注明作者和出处。</font></p>
<!------------------------------------------------以下为logo区-------------------------------------------->
<div style="border: 1px dotted teal; text-align: center; width: 220px; float: right; color: teal; font-size: 9pt;"><img alt="" src="http://www.cnblogs.com/images/cnblogs_com/anytao/125111/o_Anytao_Design_Logo2008_En.jpg" /> <a title="从设计到架构" href="http://www.cnblogs.com/anytao/archive/2007/08/15/anytao_design_catalog.html">从设计到架构</a> </div>
<br />
<!------------------------------------------------以上为logo区-------------------------------------------->
<p>本文将介绍以下内容: </p>
<ul>
    <li>关于依赖和耦合 </li>
    <li>面向抽象编程 </li>
    <li>依赖倒置原则 </li>
    <li>控制反转 </li>
    <li>依赖注入 </li>
    <li>工厂模式 </li>
    <li>Unity框架应用 </li>
</ul>
<div>&nbsp;</div>
<div>
<table style="border-collapse: collapse;" border="0">
    <colgroup><col style="width: 590px;"></colgroup>
    <tbody valign="top">
        <tr style="background: #87bfd1 none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">
            <td style="padding-left: 7px; padding-right: 7px;"><span style="color: white;"><img alt="" src="http://www.cnblogs.com/images/cnblogs_com/anytao/125111/o_icon_your_info.gif" art="Anytao.com" /><span style="color: white;">说在，开篇之前</span> </span></td>
        </tr>
        <tr>
            <td style="padding-left: 7px; padding-right: 7px;">在老子的&#8220;小国寡民&#8221;论中，提出了一种理想的社会状态：民至老死，不相往来。这是他老人家的一种社会理想，老死不相往来的人群呈现了一片和谐景象。因为不发生瓜葛，也就无所谓关联，进而无法倒置冲突。这是先祖哲学中的至纯哲理，但理想的大同总是和现实的生态有着或多或少的差距，人类社会无法避免联系的发生，所以小国寡民的理想成为一种美丽的梦想，不可实现。同样的道理，映射到软件&#8220;社会&#8221;中，也就是软件系统结构中，也预示着不同的层次、模块、类型之间也必然存在着或多或少的联系，这种联系不可避免但可管理。正如人类社会虽然无法实现小国寡民，但是理想的状态下我们推崇和谐社会，把人群的联系由复杂变为简单，由曲折变为统一，同样可以使得这种关联很和谐。所以，软件系统的使命也应该朝着和谐社会的目标前进，对于不同的关系处理，使用一套行之有效的哲学，把复杂问题简单化，把僵化问题柔性化，这种哲学或者说方法，在我看来就是：依赖的哲学，也就是本文所要阐释的中心思想。
            <br />
            <br />
            <p align="right"><font color="#ff0000"><strong>*Hot:</strong></font><a title="《你必须知道的.NET》" href="http://book.anytao.com/">《你必须知道的.NET》</a></p>
            </td>
        </tr>
    </table>
    </div>
    <div>&nbsp;</div>
    <p><font color="#800000" size="5">1 引言</font></p>
    <p>因为在公司内部进行设计原则和设计模式的培训，我的第一个任务就是和大家就依赖倒置原则进行沟通。作为5大设计原则之一的DIP原则，单纯的由概念而实例在我认为并不能完全阐释清楚： </p>
    <ul>
        <li>什么是依赖倒置？ </li>
        <li>为什么依赖倒置？ </li>
        <li>如何依赖倒置？ </li>
    </ul>
    这几个关键的问题，所以我决定不单纯的通过DIP而DIP，而是从依赖这个最原始的概念讲起，来了解在面向对象软件设计体系中，关于&#8220;关系的处理&#8221;，也就是&#8220;依赖的哲学&#8221;。对，依赖就是关系，处理依赖也就意味着处理关系。因为，我们人类是最善于搞关系的动物，所以原本可以简单的理论，在人类的意识哲学中变得复杂而多变，以至于我们本应简单的道理变得如此复杂，这就是依赖。那么，从依赖讲起来了解依赖倒置原则，我觉得首先应该回到以下的问题：
    <ul>
        <li>控制反转、依赖倒置、依赖注入这些概念，你认识但是否熟悉？ </li>
        <li>Unity、ObjectBuilder、Castle这些容器，你相识但是否相知？ </li>
        <li>面向接口、面向抽象、开放封闭，这些思想，你了解但是否了然？ </li>
    </ul>
    带着对这些问题的思考和思索，<a href="http://www.anytao.com/">Anytao</a>带领大家就依赖这个话题开始一次循序渐进的面向对象之旅，以解答这些从一开始就有足够吸引力的问题，从原理到实例，从关系到异同，我期待这篇文章能带来一些认知的变革。&nbsp;&nbsp;
    <p><font color="#800000" size="5">2 什么是依赖，什么是抽象</font></p>
    <p><font color="#800000" size="4">2.1 关于依赖和耦合：由小国寡民到和谐社会</font></p>
    <p>在老子的&#8220;小国寡民&#8221;论中，提出了一种理想的社会状态：民至老死，不相往来。这是他老人家的一种社会理想，老死不相往来的人群呈现了一片和谐景象。因为不发生瓜葛，也就无所谓关联，进而无法倒置冲突。这是先祖哲学中的至纯哲理，但理想的大同总是和现实的生态有着或多或少的差距，人类社会无法避免联系的发生，所以小国寡民的理想成为一种美丽的梦想，不可实现。同样的道理，映射到软件&#8220;社会&#8221;中，也就是软件系统结构中，也预示着不同的层次、模块、类型之间也必然存在着或多或少的联系，这种联系不可避免但可管理。正如人类社会虽然无法实现小国寡民，但是理想的状态下我们推崇和谐社会，把人群的联系由复杂变为简单，由曲折变为统一，同样可以使得这种关联很和谐。所以，软件系统的使命也应该朝着和谐社会的目标前进，对于不同的关系处理，使用一套行之有效的哲学，把复杂问题简单化，把僵化问题柔性化，这种哲学或者说方法，在我看来就是：依赖的哲学，也就是本文所要阐释的中心思想。
    <br />
    因为，&#8220;耦合是不可避免的&#8221;，所以我们首先就从认识依赖和耦合的概念开始，来一步步阐释我们的依赖哲学思想：</p>
    <ul>
        <li>什么是依赖和耦合 </li>
    </ul>
    <p>依赖，就是关系，代表了软件实体之间的联系。软件的实体可能是模块，可能是层次，也可能是具体的类型，不同的实体直接发生依赖，也就意味着发生了耦合。所以，依赖和耦合在我看来是对一个问题的两种表达，依赖阐释了耦合本质，而耦合量化了依赖程度。因此，我们对于关系的描述方式，就可以从两个方面的观点来分析：</p>
    <p>
    <br />
    从依赖的角度而言，可以分类为： </p>
    <ul>
        <ul>
            <li>无依赖，代表没有发生任何联系，所以二者相互独立，互不影响，没有耦合关系。 </li>
            <li>单向依赖，关系双方的依赖是单向的，代表了影响的方向也是单向的，其中一个实体发生改变，会对另外的实体产生影响，反之则不然，耦合度不高。 </li>
            <li>双向依赖，关系双方的依赖是相互的，影响也是相互的，耦合度较高。 </li>
        </ul>
    </ul>
    <br />
    从耦合的角度而言，可以分类为（此处回归到具体的代码级耦合概念，以方便概念的阐释）：
    <ul>
        <ul>
            <li>零耦合，表示两个类没有依赖。 </li>
            <li>具体耦合，如果一个类持有另一个具体类的引用，那么这两个类就发生了具体耦合关系。所以，具体耦合发生在具体类之间的依赖，因此具体类的变更将引起对其关联类的影响。 </li>
            <li>抽象耦合，发生在具体类和抽象类的依赖，其最大的作用就是通过对抽象的依赖，应用面向对象的多态机制，实现了灵活的扩展性和稳定性。 </li>
        </ul>
    </ul>
    <br />
    不同的耦合，代表了依赖程度的差别，我们以&#8220;粒度&#8221;为概念来分析其耦合的程度。引用中间层来分离耦合，可以使设计更加的优雅，架构更加的柔性，但直接的依赖也存在其市场，过度的设计也并非可取之道。因为效率与性能同样是设计需要考量的因素，过多的不必要分离会增加调用的次数，造成效率浪费。在下文分析依赖倒置原则的弊端之一正是对此问题的进一步阐述。
    <ul>
        <li>耦合是如何产生的？ </li>
    </ul>
    <p>那么，软件实体之间的耦合是如何产生呢？回归我们每天挥洒的代码片段，其实我们在重复的创造着耦合，并且得益于对这种耦合带来的数据通信。如果我们将历史的目光回归到软件设计之初，人类以简单的机器语言来实现最简单的逻辑，给一个输入，实现一个输出，可以表达为：</p>
    <p><img src="http://www.cnblogs.com/images/cnblogs_com/anytao/162192/o_anytao_write_design_dependency_06.jpg" alt="" /> </p>
    <p>随着软件世界的革命，业务逻辑的复杂，以上的简单化处理已经不足以实现更复杂的软件产品，在系统内部的复杂度成为一个超越人脑可识别的程度时，例如：</p>
    <p><img src="http://www.cnblogs.com/images/cnblogs_com/anytao/162192/o_anytao_write_design_dependency_07.jpg" alt="" />&nbsp; </p>
    <p>因此，人类开始发挥重组和简单化处理的优势，我们不得不在软件设计上做出平衡。平衡的结果就是通过对复杂的系统模块化，把复杂问题简单处理，从而达到能够被人脑识别的目的。基于这种指导原则，随着复杂度的增加模块的划分更加朝着精细化发展，尤其是面向对象程序设计理论的出现，使得对复杂的处理实现了更科学的理论基础。然而，复杂的问题可以通过划分实现简单的功能模块或者技术单元，但由此应运而生的子单元会越来越多，而且越来越多的子单元必须发生数据的通信才能完成统一的业务处理，所以产生的数据通信管理也越来越多。对于子单元的管理，也就是我们本文关注的核心概念-依赖，成为新的软件设计问题，那么总结前人的经验，提炼今人的智慧，我们对耦合的产生做以如下归纳： </p>
    <ul>
        <ul>
            <li>继承 </li>
            <li>聚合 </li>
            <li>接口 </li>
            <li>方法调用和引用 </li>
            <li>服务调用 </li>
        </ul>
    </ul>
    了解了耦合发生的一般方式，我们就可以进入了核心思想的讨论，那就是在认识依赖和了解依赖的基础上，我们最终追求的目标。
    <ul>
        <li>设计的目标：高内聚（High cohesion）、低耦合（Low coupling） </li>
    </ul>
    讨论了半天，终于是时候对依赖和耦合进行一点儿总结了，也是该进行一点目标诉求了。在软件设计领域，有那么几个至高原则值得我们深刻心中，它们是：
    <ul>
        <ul>
            <li>面向抽象编程 </li>
            <li>低耦合，高内聚 </li>
            <li>封装变化 </li>
            <li>实现重用：代码重用、算法重用 </li>
        </ul>
    </ul>
    <p>对了，就是这些平凡的字眼，汇集了面向对象思想的核心内容，也是本文力求阐释的禅意心经。关于面向抽象编程和封装变化，我们会在后面详细阐释，在此我们需要将注意力关注于&#8220;低耦合，高内聚&#8221;这一目标。</p>
    <p>
    <br />
    <strong>低耦合</strong>，代表了实现最简单的依赖关系，尽可能的减少类与类、模块与模块、层次与层次、系统与系统之间的联系。低耦合，体现了人类追求简单操作的理想状态，按照软件开发的基本实现技巧来追求软件实体之间的关系简单化，正是大部分设计模式力图追求的目标；低耦合，降低了一个类或一个模块发生修改对其他类或模块造成的影响，将影响范围简单化。在我们阐释的依赖关系方式中，实现单向的依赖，实现抽象的耦合，都是实现低耦合的基础条件。</p>
    <p>
    <br />
    <strong>高内聚</strong>，一方面代表了职责的统一管理，一方面体现了关系的有效隔离。例如单一职责原则其实归根结底是对功能性的一种指导性体现，将功能紧密联系的职责封装为一个类（或模块），而判断的准则正是基于引起类变化的原因。所以，封装离不开依赖，而抽象离不开变化，二者的概念和本质都是相对而言的。因此，高内聚的目标体现了以隔离为目标进行统一管理的思想。
    <br />
    那么，为了达到低耦合、高内聚的目标，通常意义上的设计原则和设计模式其实都是朝着这个方向实现的，因此我们仅仅小结并非普遍意义的规则： </p>
    <ul>
        <ul>
            <li>尽可能实现单项依赖 </li>
            <li>不需要进行数据交换的双方，不要实现多此一举的关联，人们将此形象称为，不要向陌生人说话（Don't talk to strangers） </li>
            <li>保持内部的封装性，关联的双方不要深入实现细节进行通信，这是保证高内聚的必须条件。 </li>
        </ul>
    </ul>
    <p><font color="#800000" size="4">2.2 关于抽象和具体</font></p>
    <p>什么是抽象呢？我们首先不必澄清什么是抽象，而从什么算抽象说起，稳定的、高层的则代表了抽象。就像一个公司，最好保证了高层的稳定，才能保证全局的发展。在进行系统设计时，稳定的抽象接口和高层逻辑，也代表了整个系统的稳定与柔性。兵熊熊一窝，将良良一窝，系统的逻辑也正如着代表打仗，良好的设计都是自上而下的。而对具体的编程实践而言，接口和抽象类则代表了语言层次的抽象。
    <br />
    追溯概念的分析，我们一一过招，首先来看依赖于具体：</p>
    <p><img src="http://www.cnblogs.com/images/cnblogs_com/anytao/162192/o_anytao_write_design_dependency_02.jpg" alt="" />&nbsp; </p>
    <p>因此，为了分离这种<strong>紧耦合</strong>，最好的办法就是<strong>隔离</strong>，引入中间层来分离变化，同时确保中间层本身的稳定性，因此抽象的中间层是最佳的选择。</p>
    <p><img src="http://www.cnblogs.com/images/cnblogs_com/anytao/162192/o_anytao_write_design_dependency_03.jpg" alt="" />&nbsp; </p>
    <p>例如：</p>
    <div class="csharpcode">
    <pre class="alt">    <span class="kwrd">public</span> <span class="kwrd">interface</span> IUserService</pre>
    <pre>    {</pre>
    <pre class="alt">    }</pre>
    <pre>&nbsp;</pre>
    <pre class="alt">    <span class="kwrd">public</span> <span class="kwrd">class</span> UserService : IUserService</pre>
    <pre>    {</pre>
    <pre class="alt">    }</pre>
    </div>
    <style type="text/css">
    .csharpcode, .csharpcode pre
    {
    font-size: small;
    color: black;
    font-family: consolas, "Courier New", courier, monospace;
    background-color: #ffffff;
    /*white-space: pre;*/
    }
    .csharpcode pre { margin: 0em; }
    .csharpcode .rem { color: #008000; }
    .csharpcode .kwrd { color: #0000ff; }
    .csharpcode .str { color: #006080; }
    .csharpcode .op { color: #0000c0; }
    .csharpcode .preproc { color: #cc6633; }
    .csharpcode .asp { background-color: #ffff00; }
    .csharpcode .html { color: #800000; }
    .csharpcode .attr { color: #ff0000; }
    .csharpcode .alt
    {
    background-color: #f4f4f4;
    width: 100%;
    margin: 0em;
    }
    .csharpcode .lnum { color: #606060; }</style>
    <p>下面依赖于具体：</p>
    <div class="csharpcode">
    <pre class="alt">    <span class="kwrd">public</span> <span class="kwrd">class</span> UserManager</pre>
    <pre>    {</pre>
    <pre class="alt">        <span class="kwrd">private</span> UserService service = <span class="kwrd">null</span>;</pre>
    <pre>    }</pre>
    </div>
    <style type="text/css">
    .csharpcode, .csharpcode pre
    {
    font-size: small;
    color: black;
    font-family: consolas, "Courier New", courier, monospace;
    background-color: #ffffff;
    /*white-space: pre;*/
    }
    .csharpcode pre { margin: 0em; }
    .csharpcode .rem { color: #008000; }
    .csharpcode .kwrd { color: #0000ff; }
    .csharpcode .str { color: #006080; }
    .csharpcode .op { color: #0000c0; }
    .csharpcode .preproc { color: #cc6633; }
    .csharpcode .asp { background-color: #ffff00; }
    .csharpcode .html { color: #800000; }
    .csharpcode .attr { color: #ff0000; }
    .csharpcode .alt
    {
    background-color: #f4f4f4;
    width: 100%;
    margin: 0em;
    }
    .csharpcode .lnum { color: #606060; }</style>
    <p>下面依赖于抽象：</p>
    <div class="csharpcode">
    <pre class="alt">    <span class="kwrd">public</span> <span class="kwrd">class</span> UserManager</pre>
    <pre>    {</pre>
    <pre class="alt">        <span class="kwrd">private</span> IUserService service = <span class="kwrd">null</span>;</pre>
    <pre>    }</pre>
    </div>
    <style type="text/css">
    .csharpcode, .csharpcode pre
    {
    font-size: small;
    color: black;
    font-family: consolas, "Courier New", courier, monospace;
    background-color: #ffffff;
    /*white-space: pre;*/
    }
    .csharpcode pre { margin: 0em; }
    .csharpcode .rem { color: #008000; }
    .csharpcode .kwrd { color: #0000ff; }
    .csharpcode .str { color: #006080; }
    .csharpcode .op { color: #0000c0; }
    .csharpcode .preproc { color: #cc6633; }
    .csharpcode .asp { background-color: #ffff00; }
    .csharpcode .html { color: #800000; }
    .csharpcode .attr { color: #ff0000; }
    .csharpcode .alt
    {
    background-color: #f4f4f4;
    width: 100%;
    margin: 0em;
    }
    .csharpcode .lnum { color: #606060; }</style>
    <p>二者的区别仅在于引入了接口IUserService，从而使得UserManager对于UserService的依赖由强减弱。这种方式也在我们的<a href="http://www.cndotnet.org/ezsocio">Ezsocio</a>项目中进行service层的设计方式。然而对于依赖的方式并非仅此一种，设计模式中的智慧正是通过各章编程技巧进行依赖关系的设计，值得我们关注和学习，本文也在下文进行相关设计模式的讨论。
    <br />
    对WCF熟悉的读者一定不难看出这种实现方式如此类似于WCF的推荐模式，这是契约编程的基本思想。关于WCF及SOA的相关内容，本文将在后文进行相关的讨论。
    <br />
    总结一番，什么是抽象，什么是具体？在我看来，抽象就是系统中对变化封装的战略逻辑，体现了系统的必然性和稳定性，能够被具体层次复用和覆写；而具体则包含了与具体实现相关的逻辑，体现了系统的动态性和变动性。因此，抽象是稳定的，而具体是变动的。
    <br />
    Bob大叔在《敏捷》一书直言，程序中所有的依赖关系都应终止于抽象类或者接口，就是对面向抽象编程一针见血的回应，其原因归根结底源自于我们对抽象和具体的认知和分解：关联应该终止于抽象，而不是具体，保证了系统依赖关系的稳定。具体类发生的修改，不会影响其他模块或者关系。那么如何做到这种理想的依赖于抽象的设计呢？ </p>
    <ul>
        <li>层次清晰化 </li>
    </ul>
    将复杂的问题简单化，是人类思维的一般智慧，也自然而然是实现软件设计的基本思路。而将复杂的业务需求通过建模过程的抽象化提炼，去粗取精，去伪存真，凡此种种。而抽象的过程，其目标之一就是形成对于复杂问题简单化的处理过程，只有形成层次简单的逻辑才能将复杂需求中的关系梳理清晰，而依赖的本质正如上文所言，不就是处理关系吗？
    <br />
    所以，清晰的层次划分，进而形成的模块化，是实现系统抽象的必经之路。
    <ul>
        <li>分散集中化 </li>
    </ul>
    由需求而设计的过程，就是一个分散集中化的过程，把需求相关的业务通过开发流程的需求分析过程进行整理，逐步形成需求规格说明、概要设计和详细设计等基本流程。分散集中化，是一个梳理需求到形成设计的过程，因此对于把握系统中的抽象和具体而言，是一个重要的分析过程和手段。现代软件工程已经对此形成了科学的标准化流程处理逻辑，例如可以借助UML更加清晰的设计流程、分析设计要素，进行标准化沟通和交流。
    <ul>
        <li>具体抽象化 </li>
    </ul>
    将具体问题抽象化，是本节关注的要点，而处理的方法是什么呢？答案就在设计模式，设计模式是前辈智慧的总结和实践，所以熟悉和学习设计模式，是学习和实践设计问题的必经之路。然而，没有哪个问题是由设计模式全权解决，也没有那个模式能够适应所有的问题，因此我们要努力的是尽量积累更多的模式来应对多变的需求。作为软件设计话题中最重量级的话题，我也会在以后的岁月中对设计模式问题进行一些探讨。
    <ul>
        <li>封装变化点 </li>
    </ul>
    总的来说，抽象和变化就像一对孪生兄弟，将具体的变化点隔离出来以抽象的方式进行封装，在变化的地方寻找抽象是面对抽象最理想的方式。所以，如何去寻找变化是设计要解决的首页问题，例如工厂模式的目标是封装对象创建的变化，桥接模式封装的是对象间的依赖关系变化等等。23个经典的设计模式，从某种角度来看，正是对不同变化点的封装角度提出的不同解决方案。
    <br />
    这一设计原则中我们还将之称为SoC（Separation of Concerns）原则，定义了对于实现理想的高耦合、低内聚目标的统一规则。&nbsp;
    <p><font color="#800000" size="4">2.3 设计的哲学</font></p>
    <p>之所以花如此篇幅来讲述一个看似简单的问题，其实最终理想是回归到软件设计目标这个命题上。如果悉心钻研就可发现，设计的最后就是对关系的处理，正如同生活的意义在于对社会的适应一样。因此，回归到设计的目标上我们就可知，完美的设计过程就是对关系的处理过程，也就是对依赖的梳理过程，并最终形成一种合理的耦合结果。
    <br />
    所以，面向对象并不神秘，我们以生活的现实眼光来看更是如此。把面向对象深度浓缩起来，我觉得可以概括为： </p>
    <ul>
        <li>目标：重用、扩展 </li>
        <li>核心：低耦合、高内聚 </li>
        <li>手段：封装变化 </li>
        <li>思想：面向接口编程、面向抽象编程 </li>
    </ul>
    <p>
    <br />
    其实，就是这么简单。在这种意义上来说，面向对象思想是现代软件架构设计的基础。下面我们以三层架构的设计为例，来进一步感受这种依赖哲学的具体应用。关于依赖的抽象和对变化隔离的基本思路，其实也是实现我们典型三层架构（或者）多层架构的重要基础。只要使各个层次之间依赖于较稳定的接口，才能使得各个层次之间的变化被隔离在本层之内，不会造成对其他层次的影响，这完全符合开放封闭原则追求的优良设计理念。将这种思路表达为设计，可以表示为：<img src="http://www.cnblogs.com/images/cnblogs_com/anytao/162192/o_anytao_write_design_dependency_04.jpg" alt="" /> </p>
    <p>在此，IDataProvider作为隔离业务层和数据层的抽象，IService作为隔离业务层和表现层的抽象，保证了各个层次的相对稳定和封装。而体现在此的设计逻辑，就正是我们对于抽象和耦合基本目标概念的体现，例如作为重用的单元，抽象隔离保证了对外发布接口的单一和稳定，所以达到了最高限度的重用；通过引入中间的稳定的接口，达到了不同层次的有效隔离，层与层之间体现为轻度耦合，业务层只持有IDataProvider就可以获取数据层的所有服务，而表现层也同样如此；最后，这种方式显然也直接实践了面向接口编程，面向抽象编程的经典理念。
    <br />
    同样的道理，对于架构设计的很多概念，放大可以扩展为面向服务设计所借鉴，放小这正是我们反复降调的依赖倒置原则在类设计中的基本思想。因此，牢记对我影响至深的一位大牛的说法：软件设计的任何问题，都可以通过引入中间逻辑了解决。而这个中间逻辑，很多时候被封装为抽象，是最为合理和智慧的解决方案。
    <br />
    让我们再次高颂《老子》的小国寡民论，来回味关于依赖哲学中，我们如何实现更好的和谐统一，如何遵守科学的软件管理思想："邻国相望，鸡犬之声相闻，民至老死，不相往来。" </p>
    <p><font color="#800000" size="5">3 认识依赖倒置原则（DIP）</font></p>
    <p><font color="#800000" size="4">3.1 什么是依赖倒置？</font></p>
    <p>Bob大叔在《Agile Principles, Patterns, and Practices》一书中对依赖倒置原则进行了精辟的总结为： </p>
    <ul>
        <li>高层模块不应该依赖于低层模块，二者都应该依赖于抽象。 </li>
        <li>抽象不应该依赖于具体，细节应该依赖于抽象。 </li>
    </ul>
    我规规矩矩一字不差的把上述真言放在心里，却发现大师的牛论实在有点故作玄虚，就像欣赏Bob在论述DIP时的插画一样费解不讨好：
    <p><img src="http://www.cnblogs.com/images/cnblogs_com/anytao/162192/o_anytao_write_design_dependency_13.jpg" alt="" />&nbsp; </p>
    <p>其实著名的好莱坞原则更形象的阐述了这一思想：你不要调我，我来调你。不管是通俗的还是高尚的，却都不约而同的揭示了依赖倒置原则的最核心思想就是： </p>
    <p><strong><font color="#ff0000">依赖于抽象，对接口编程，对抽象编程！</font></strong></p>
    <p>相较而言，从实际的生活中来看依赖倒置，就像下面这个示例揭示的一样。</p>
    <p><font color="#800000" size="4">3.2 从实例开始</font></p>
    <p>综合对依赖倒置的认识，结合到具体的程序实现而言，依赖倒置预示着程序中的依赖关系不应是具体的类型，而是归咎于抽象类和接口。下面我们通过一个简单的实例来分析符合依赖倒置和违反依赖倒置，对于系统设计的影响和区别。我们的需求是为某个遥控器生产商，实现一个万能遥控器，该遥控器可以对当前市场上的很多电子设备进行&#8220;打开&#8221;和&#8220;关闭&#8221;的操作，例如你可以使用Anytao牌遥控器打开海尔电视、创维电视等等，当然更理想的状态是可以打开电冰箱、电灯还有门窗等等，总之凡是可以互联的设备都是未来万能遥控器的新需求。
    <br />
    那么该遥控器厂商在设计之初，该如何去考虑实现一个可以打开任何设备的遥控器呢？这一重责首先落在了一位年轻气盛的小王设计师身上，因为遥控器厂家当前的直接客户只有海尔电视一家，所以他轻松的实现了下面的设计，并且兴高采烈的进行了大批量生产：</p>
    <p><img src="http://www.cnblogs.com/images/cnblogs_com/anytao/162192/o_anytao_write_design_dependency_08.jpg" alt="" /> </p>
    <p>随后，厂商多了一个重量级客户长虹，所以小王不得不对初试设计进行了改造，勉强适应了新的需求，如下：</p>
    <p><img src="http://www.cnblogs.com/images/cnblogs_com/anytao/162192/o_anytao_write_design_dependency_09.jpg" alt="" /></p>
    <p>虽然小王应付了这次需求变动，但是原本的设计显然已经捉襟见肘。正当小王绞尽脑汁进行改造的同时，新的需求接踵而来：新飞冰箱、飞利浦照明、盼盼防盗门，一个接一个。小王的最终设计变成了这般摸样：</p>
    <p><img src="http://www.cnblogs.com/images/cnblogs_com/anytao/162192/o_anytao_write_design_dependency_10.jpg" alt="" />&nbsp; </p>
    <p>哎，真是太累了。每一次的需求变更都伴随着小王对遥控器Remote的再次摧残，Remote内部不断增加新的引用和操作处理，显然一个if/else式的判断布满了整个Open和Close的操作中，这种设计显然无法满足OCP对扩展开放、对修改封闭的要求。显然，如果想让卖出去的遥控器也适应新的需求，在小王当前的设计实现方案中是根本无法实现的，遥控器厂商总不能召回已经售出所有的遥控器，再拆开进行重新改造吧。
    <br />
    一筹莫展的小王，终于在崩溃之际想起了经验丰富的前设计师老王，并立即请教如何解决当前问题的思路。而老王也毫不含糊，给出了一个初步的实现：</p>
    <p><img src="http://www.cnblogs.com/images/cnblogs_com/anytao/162192/o_anytao_write_design_dependency_11.jpg" alt="" /> </p>
    <p>在当前的设计中，老王的思路是让遥控器厂切断和各个厂家的直接联系，而是寻找所有电视厂商的领导（例如，电视机协会），请电视机协会制定所有电视机厂商必须遵守的打开和关闭等操作的契约，遥控器厂和电视机协会建立直接的联系而不是各个具体的电视厂商，于是便有了上述设计思路。而新的需求来临时，因为各个厂商必须遵守TurnOn和TurnOff的契约，所以轻松的万能遥控器可以应付所有的电视机品牌，实现的具体操作已经由遥控器转移到具体的厂商手上（顺便说说这也是所有权的倒置体现），轻松的小王终于大呼一口气。并且再接再厉修改了更完善的版本：</p>
    <p><img src="http://www.cnblogs.com/images/cnblogs_com/anytao/162192/o_anytao_write_design_dependency_12.jpg" alt="" /></p>
    <p>现在，遥控器基本实现了万能的要求，任何新的需求或者修改都可以轻松胜任。小王终于解决了原本设计的所有问题，带着感激盛情邀请老王吃饭致谢。席间就坐，小王请教老王二次设计的秘诀，老王神秘一笑沾酒在桌子上写了几个大字：依赖倒置。经历此次设计重构洗礼的小王，也在实战中体味了设计的精妙，看着依赖倒置几个字小王也会心的笑了。
    <br />
    万能遥控器的故事，是一个系统实现中经常的事儿。而这些设计在<a href="http://www.codeplex.com/ezsocio">Ezsocio</a>项目中有广泛的应用，例如对于DataProvider和Service的处理方式，正是一种典型的遵循DIP原则的设计思路。 </p>
    <p><font color="#800000" size="4">3.3 为什么依赖倒置？</font></p>
    <p>依赖倒置原则揭示了面向对象思想中一个最基本而最核心的话题，那就是：面向抽象编程。任何对依赖倒置原则的违反都不同程度的偏离了面向对象设计思想的轨道，所以如果你想自己的程序是否足够的OO，透彻的了解依赖倒置是必不可少的。
    <br />
    所以，要问答为什么依赖倒置这个话题，我觉得可以从以下几个方面来阐释：</p>
    <ul>
        <li>依赖倒置是保证开放封闭的前提和基础。 </li>
        <li>依赖倒置是对抽象和依赖的基本原则和基本思想的哲学阐释。 </li>
        <li>依赖倒置是框架设计的核心思想。 </li>
        <li>依赖倒置是控制反转和依赖注入的思想基础。 </li>
    </ul>
    <br />
    综上而言，依赖倒置是对软件实体关系处理的基本思想原则，也是其他设计原则与设计模式的基础之一，因此遵守依赖倒置是实现OO的基本原则，是我们必须了解的基础性原则。下面，我们对此进行详细的说明和举例。
    <p><font color="#800000" size="4">3.4 为什么是倒置？</font></p>
    <p>鲁迅先生有云：其实地上本没有路，走的人多了也便成了路。对依赖倒置原则中的&#8220;倒置&#8221;二字而言，其实也类似于一条被很多人走过的路，因为习惯性的称呼走过的为&#8220;路&#8221;，所以只好把违反习惯的东西称为&#8220;倒置的路&#8221;。这倒置的含义，正基于此。
    <br />
    对于从结构化编程走过的人来说，基于软件复用的考虑，侧重于对具体模块的复用，因为也就习惯了从高层模块出发了构建系统流程的思维模式，所以那时的高手一出手就实现了高层依赖于底层的典型套路，例如：</p>
    <p><img src="http://www.cnblogs.com/images/cnblogs_com/anytao/162192/o_anytao_write_design_dependency_01.jpg" alt="" /></p>
    <p>高层模块通过自上而下的实现来完成系统功能的调用，将这种方式表达为代码就是：</p>
    <div class="csharpcode">
    <pre class="alt">        <span class="rem">// Release : code01, 2008/11/02                    </span></pre>
    <pre>        <span class="rem">// Author  : Anytao, http://www.anytao.com </span></pre>
    <pre class="alt">        <span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">void</span> Main()</pre>
    <pre>        {</pre>
    <pre class="alt">            <span class="kwrd">try</span></pre>
    <pre>            {</pre>
    <pre class="alt">                <span class="rem">//Do something here.</span></pre>
    <pre>            }</pre>
    <pre class="alt">            <span class="kwrd">catch</span></pre>
    <pre>            {</pre>
    <pre class="alt">                Log(<span class="kwrd">true</span>, <span class="str">"XMLLog"</span>);</pre>
    <pre>            }</pre>
    <pre class="alt">        }</pre>
    <pre>&nbsp;</pre>
    <pre class="alt">        <span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">void</span> Log(<span class="kwrd">bool</span> isRead, <span class="kwrd">string</span> logType)</pre>
    <pre>        {</pre>
    <pre class="alt">            <span class="kwrd">if</span> (isRead)</pre>
    <pre>                ReadLog(logType);</pre>
    <pre class="alt">            <span class="kwrd">else</span></pre>
    <pre>                WriteLog(logType);</pre>
    <pre class="alt">        }</pre>
    </div>
    <style type="text/css">
    .csharpcode, .csharpcode pre
    {
    font-size: small;
    color: black;
    font-family: consolas, "Courier New", courier, monospace;
    background-color: #ffffff;
    /*white-space: pre;*/
    }
    .csharpcode pre { margin: 0em; }
    .csharpcode .rem { color: #008000; }
    .csharpcode .kwrd { color: #0000ff; }
    .csharpcode .str { color: #006080; }
    .csharpcode .op { color: #0000c0; }
    .csharpcode .preproc { color: #cc6633; }
    .csharpcode .asp { background-color: #ffff00; }
    .csharpcode .html { color: #800000; }
    .csharpcode .attr { color: #ff0000; }
    .csharpcode .alt
    {
    background-color: #f4f4f4;
    width: 100%;
    margin: 0em;
    }
    .csharpcode .lnum { color: #606060; }</style>
    <p>然而，当软件设计的模式发展到面向对象阶段时，我们发现原来习惯的世界了已经变了。基于高层依赖于底层的弊政，也越来越被可扩展性的系统需求折磨的面目全非，例如如果日志记录的载体发生变化，当前设计中需要同时自上而下的修改实现的逻辑，同时避免出现越来越多的if/else结构。所以当新的依赖关系从传统的方式被完全扭转时，&#8220;倒置&#8221;二字就此诞生了。我们修改Log实现的设计思路，将可能变化的逻辑封装为抽象接口，使得高层依赖发生转换：</p>
    <p>&nbsp;<img src="http://www.cnblogs.com/images/cnblogs_com/anytao/162192/o_anytao_write_design_dependency_05.jpg" alt="" /></p>
    <p>程序实现的逻辑早已被面向对象的设计思想所取代，我们新的实现变成了：</p>
    <div class="csharpcode">
    <pre class="alt">    <span class="rem">// Release : code02, 2008/11/02                    </span></pre>
    <pre>    <span class="rem">// Author  : Anytao, http://www.anytao.com </span></pre>
    <pre class="alt">    <span class="kwrd">public</span> <span class="kwrd">class</span> Client</pre>
    <pre>    {</pre>
    <pre class="alt">        <span class="kwrd">public</span> <span class="kwrd">static</span> <span class="kwrd">void</span> Main()</pre>
    <pre>        {</pre>
    <pre class="alt">            ILog myLogger = <span class="kwrd">new</span> XMLLog();</pre>
    <pre>            <span class="kwrd">try</span></pre>
    <pre class="alt">            {</pre>
    <pre>&nbsp;</pre>
    <pre class="alt">            }</pre>
    <pre>            <span class="kwrd">catch</span></pre>
    <pre class="alt">            {</pre>
    <pre>                myLogger.Write();</pre>
    <pre class="alt">            }</pre>
    <pre>        }</pre>
    <pre class="alt">    }</pre>
    <pre>&nbsp;</pre>
    <pre class="alt">    <span class="kwrd">public</span> <span class="kwrd">interface</span> ILog</pre>
    <pre>    {</pre>
    <pre class="alt">        <span class="kwrd">void</span> Read();</pre>
    <pre>        <span class="kwrd">void</span> Write();</pre>
    <pre class="alt">    }</pre>
    <pre>&nbsp;</pre>
    <pre class="alt">    <span class="kwrd">public</span> <span class="kwrd">class</span> XMLLog : ILog</pre>
    <pre>    {</pre>
    <pre class="alt">        <span class="kwrd">public</span> <span class="kwrd">void</span> Read()</pre>
    <pre>        {</pre>
    <pre class="alt">        }</pre>
    <pre>&nbsp;</pre>
    <pre class="alt">        <span class="kwrd">public</span> <span class="kwrd">void</span> Write()</pre>
    <pre>        { </pre>
    <pre class="alt">        }</pre>
    <pre>    }</pre>
    </div>
    <style type="text/css">
    .csharpcode, .csharpcode pre
    {
    font-size: small;
    color: black;
    font-family: consolas, "Courier New", courier, monospace;
    background-color: #ffffff;
    /*white-space: pre;*/
    }
    .csharpcode pre { margin: 0em; }
    .csharpcode .rem { color: #008000; }
    .csharpcode .kwrd { color: #0000ff; }
    .csharpcode .str { color: #006080; }
    .csharpcode .op { color: #0000c0; }
    .csharpcode .preproc { color: #cc6633; }
    .csharpcode .asp { background-color: #ffff00; }
    .csharpcode .html { color: #800000; }
    .csharpcode .attr { color: #ff0000; }
    .csharpcode .alt
    {
    background-color: #f4f4f4;
    width: 100%;
    margin: 0em;
    }
    .csharpcode .lnum { color: #606060; }</style>
    <p>所以，了解了历史才能正视现实，对于软件设计同样如此，只有认清楚依赖倒置产生的历史背景，我们才能更加熟练的驾驭倒置含义本身带来的误解，而将中心思想牢牢的把握在依赖倒置最核心的设计思想上，那还是万变不离其宗的：依赖于抽象，这简单的5个字上。
    <br />
    对于所属权关系的依赖问题上，我们看到，只有倒置的才是面向对象的，没有倒置的还是面向结构的。如果你的系统中存在着不合理的依赖关系，那么依赖倒置将是检查系统设计最好的标尺，这也是我们把握这一原则的实际意义之一。 </p>
    <p><font color="#800000" size="4">3.5 如何依赖倒置？</font></p>
    <p>如何依赖倒置的关键，还是体现在如何对抽象和具体的封装和分离，实践的基本思路就是封装变化。这正如我们在单一职责原则中反复强调，对一个类只有一个引起它变化的原因。我们实践依赖倒置，仍然可以从关注变化开始，详细的分析和预测系统中的变化点，然后针对每个可能的变化抽象出相对稳定的约束，这是我们实践依赖倒置原则最基本的方法步骤。
    <br />
    就原理而言，依赖倒置要求我们的设计： </p>
    <ul>
        <li>少继承，多聚合 </li>
        <li>单向依赖（低耦合，高内聚） </li>
        <li>封装抽象 </li>
        <li>对依赖关系都应该终止于抽象类和接口 </li>
    </ul>
    <br />
    就实践而言，经典的软件设计实践为我们提出了很多值得借鉴的思路，例如每个设计模式就是对一种特定情况的实践总结，在此我们继续列出一些经典的大师忠言，Bob大叔在《Agile Principles, Patterns, and Practices》一书对此进行了3点总结：
    <ul>
        <li>任何变量都不应该持有一个指向具体类的指针或者引用。 </li>
        <li>任何类都不应该从具体类派生。 </li>
        <li>任何方法都不应该覆写它的任何基类中的已经实现的方法。 </li>
    </ul>
    实际上，在实际的设计过程中要完全遵守这几点要求是有难度的，所以如何既能很好的遵守设计原则，又能很好的适应代码情况，是值得权衡的问题，需要我们不断的积累和实践。另外，还有几个经验只谈：
    <ul>
        <li>系统架构应该有清晰的层次定义，层次之间通过接口向外提供内聚服务，正如在三层示例中的举例一样。 </li>
        <li>典型的以new进行的对象创建操作，是对依赖倒置原则的典型违反，我们将在后文进行详细讨论。 </li>
    </ul>
    <br />
    如何依赖倒置，我们阐释了一点原则还有一点方法，算是对实现依赖倒置的一点小结。然而，在实际的开发过程中，并没有一成不变的规则，当前的面向对象语言本身就提供了对抽象和封装的支持，为实现面向对象设计提供了基础机制。回顾软件开发的历史，我们不难看出依赖和封装哲学的发展轨迹，在结构化编程中函数是封装的基本单元；随着面向对象的发展C++/C#高级语言以类为基本单元，第一次将数据和行为有机的组合为一个逻辑单元，于是有了对于不同类之间的关系处理哲学；而SOA中封装的单元上升为service，是一种更高意义的逻辑封装，实现了更优良的逻辑封装和松散耦合关系。同样的道理，也体现在三层架构的分割和通信中，体现在ORM对表现层和领域层的分离中。
    <br />
    因此，依赖倒置是一种高度的智慧和经验总结，如何实现依赖倒置也是一种积累和不断的学习。&nbsp;
    <p><font color="#800000" size="4">3.6 也有弊端</font></p>
    <p>然而，一味的遵守原则，就等于没有原则。重要的是，我们需要把握其平衡，在进行开发中适当的把握其程度。Bob在《敏捷》中也提到这个问题，他总结了依赖倒置的两个弊端，同样需要我们必要的关注： </p>
    <ul>
        <li>对抽象编程，需要增加必要的类和辅助代码进行支持，某种程度上增加了系统复杂度和维护成本； </li>
        <li>当具体类不存在变化时，遵守依赖倒置是多此一举。所以，如果具体或细节没有变化可能时，我们没有必要通过抽象转嫁依赖是没有必要的处理。 </li>
    </ul>
    <p>所以，学习模式或者原则必须把握灵活处理，不能一味强行。</p>
    <div>&nbsp;</div>
    <div>
    <table style="border-collapse: collapse;" border="0">
        <colgroup><col style="width: 590px;"></colgroup>
        <tbody valign="top">
            <tr style="background: #87bfd1 none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">
                <td style="padding-left: 7px; padding-right: 7px;"><span style="color: white;"><img alt="" src="http://www.cnblogs.com/images/cnblogs_com/anytao/125111/o_icon_your_info.gif" art="Anytao.com" /><span style="color: white;"><font color="#ff0000">下集预告</font></span>&nbsp;</span></td>
            </tr>
            <tr>
                <td style="padding-left: 7px; padding-right: 7px;">
                <p>在下篇中，我们将继续对依赖相关的问题进行讨论，基本的内容还包括：</p>
                <ul>
                    <li>解构控制反转（IoC）和依赖注入（DI） </li>
                    <li>基于契约编程：SOA架构下的依赖 </li>
                    <li>相关的设计模式简析 </li>
                    <li>对象创建的依赖 </li>
                </ul>
                <p>近期发布，敬请期待。
                <br />
                </p>
                <p align="right"><font color="#ff0000"><strong>*Hot:</strong></font><a title="《你必须知道的.NET》" href="http://book.anytao.com/">《你必须知道的.NET》</a></p>
                </td>
            </tr>
        </table>
        </div>
        <p>&nbsp;</p>
        <p><font color="#800000" size="4">参考文献</font></p>
        <ul>
            <li><a href="http://martinfowler.com/">Martin Fowler</a>，<a target="_blank" href="http://martinfowler.com/articles/injection.html">Inversion of Control Containers and the Dependency Injection pattern</a> </li>
            <li><a target="_blank" href="http://ninputer.cnblogs.com/">装配脑袋</a>，<a href="http://ninputer.cnblogs.com/archive/2006/01/12/315890.html">泛型技巧系列：用泛型打造可复用的抽象工厂</a> </li>
        </ul>
        <p>&nbsp;</p>
        <p><font color="#800000" size="4">系列导航</font>
        <br />
        [<a href="http://www.cnblogs.com/anytao/archive/2007/08/15/anytao_design_catalog.html">目录导航</a>]
        <br />
        [<a href="http://www.cnblogs.com/anytao/archive/2007/08/15/anytao_design_01.html">第一回：设计，应该多一点</a>]
        <br />
        [<a href="http://www.cnblogs.com/anytao/archive/2007/09/03/anytao_design_02.html">第二回：对象的旅行---对象和人，两个世界，一样情怀</a>]
        <br />
        [<a href="http://www.cnblogs.com/anytao/archive/2008/03/19/anytao_design_03.html">第三回：设计的分寸</a>]</p>
        <div id="MySignature">
        <p class="class"><a href="http://i.anytao.com/">anytao</a> | <a class="copyright" href="http://www.anytao.com/">&#169; 2008 Anytao.com</a></p>
        <p class="class">2008/12/02 | <a href="http://anytao.cnblogs.com/">http://anytao.cnblogs.com/</a></p>
        <p class="class">本文以&#8220;现状&#8221;提供且没有任何担保，同时也没有授予任何权利。 | This posting is provided "AS IS" with no warranties, and confers no rights.</p>
        <p>本文版权归作者所有，欢迎转载，但未经作者同意必须保留此段声明，且在文章页面明显位置给出原文连接，否则保留追究法律责任的权利。</p>
        </div><img src ="http://www.cnblogs.com/anytao/aggbug/1345389.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/43803/" target="_blank">[新闻]印度软件外包企业秘密收购中国公司</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>ORM漫谈</title><link>http://www.cnblogs.com/Barton131420/archive/2008/12/01/1345314.html</link><dc:creator>双鱼座</dc:creator><author>双鱼座</author><pubDate>Mon, 01 Dec 2008 14:45:00 GMT</pubDate><guid>http://www.cnblogs.com/Barton131420/archive/2008/12/01/1345314.html</guid><wfw:comment>http://www.cnblogs.com/Barton131420/comments/1345314.html</wfw:comment><comments>http://www.cnblogs.com/Barton131420/archive/2008/12/01/1345314.html#Feedback</comments><slash:comments>18</slash:comments><wfw:commentRss>http://www.cnblogs.com/Barton131420/comments/commentRss/1345314.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Barton131420/services/trackbacks/1345314.html</trackback:ping><description><![CDATA[摘要: 还是以前那句话，我不喜欢ORM这个词，但是更多的时候又不得不用。看到园友写的&#8220; ORM是进化还是倒退？&#8221;的文章，禁不住想说上几句。其实进化(或者进步?)或者倒退(或者退化?)是没有一个清晰标准的，追求这个进步或者倒退实在也没有什么意义。但是这个标题很惹人，很多年轻人很容易受到蛊惑，所以我必须站起来提醒一下他们。ORM可以理解成object-relation-mapping，&nbsp;&nbsp;<a href='http://www.cnblogs.com/Barton131420/archive/2008/12/01/1345314.html'>阅读全文</a><img src ="http://www.cnblogs.com/Barton131420/aggbug/1345314.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/43802/" target="_blank">[新闻]华人高管陆奇出任微软互联网业务总裁</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>微软同步框架(MSF)入门之六--文件(夹)同步</title><link>http://www.cnblogs.com/daizhj/archive/2008/12/01/1339688.html</link><dc:creator>代震军</dc:creator><author>代震军</author><pubDate>Mon, 01 Dec 2008 01:14:00 GMT</pubDate><guid>http://www.cnblogs.com/daizhj/archive/2008/12/01/1339688.html</guid><wfw:comment>http://www.cnblogs.com/daizhj/comments/1339688.html</wfw:comment><comments>http://www.cnblogs.com/daizhj/archive/2008/12/01/1339688.html#Feedback</comments><slash:comments>16</slash:comments><wfw:commentRss>http://www.cnblogs.com/daizhj/comments/commentRss/1339688.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/daizhj/services/trackbacks/1339688.html</trackback:ping><description><![CDATA[摘要:      在前五篇文章当中，介绍了Sync For ADO.NET Service，从这篇文章开始，将开始介绍有关使用MSF进行文件（夹）同步的相关知识。因为文件同步的应用目前比较广泛，所以可能够要用3-4篇文章来进行介绍。今天先介绍一下有关MSF文件同步的原理和使用MSF中现有的类来实现一个简单的DEMO（本DEMO支持文件和文件夹）同步。 好的，下面开始今天的正文。
&nbsp;&nbsp;<a href='http://www.cnblogs.com/daizhj/archive/2008/12/01/1339688.html'>阅读全文</a><img src ="http://www.cnblogs.com/daizhj/aggbug/1339688.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/43801/" target="_blank">[新闻]AT&T将裁员12,000人</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>在Vista配置SSAS通过HTTP远程连接的方法.</title><link>http://www.cnblogs.com/aspnetx/archive/2008/11/28/1342946.html</link><dc:creator>aspnetx</dc:creator><author>aspnetx</author><pubDate>Fri, 28 Nov 2008 02:52:00 GMT</pubDate><guid>http://www.cnblogs.com/aspnetx/archive/2008/11/28/1342946.html</guid><wfw:comment>http://www.cnblogs.com/aspnetx/comments/1342946.html</wfw:comment><comments>http://www.cnblogs.com/aspnetx/archive/2008/11/28/1342946.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.cnblogs.com/aspnetx/comments/commentRss/1342946.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/aspnetx/services/trackbacks/1342946.html</trackback:ping><description><![CDATA[摘要: Analysis Services不同于数据引擎有自己的sa方式的验证,而我们在实际生产环境部署的时候不可能应用程序服务器和分析服务器都在同一台物理机器上,这个时候就需要配置分析服务的远程方式访问.目前网上资料最多的就是通过http的方式,本文主要描述sqlserver 2005 analysis services在vista平台下的配置方法. &nbsp;&nbsp;<a href='http://www.cnblogs.com/aspnetx/archive/2008/11/28/1342946.html'>阅读全文</a><img src ="http://www.cnblogs.com/aspnetx/aggbug/1342946.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/43800/" target="_blank">[新闻]微软本月安全公告预告：6个危急、2个重要</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>[原创] Enterprise Library深入解析与灵活应用（6）：自己动手创建迷你版AOP框架</title><link>http://www.cnblogs.com/artech/archive/2008/11/27/1342309.html</link><dc:creator>Artech</dc:creator><author>Artech</author><pubDate>Thu, 27 Nov 2008 07:13:00 GMT</pubDate><guid>http://www.cnblogs.com/artech/archive/2008/11/27/1342309.html</guid><wfw:comment>http://www.cnblogs.com/artech/comments/1342309.html</wfw:comment><comments>http://www.cnblogs.com/artech/archive/2008/11/27/1342309.html#Feedback</comments><slash:comments>20</slash:comments><wfw:commentRss>http://www.cnblogs.com/artech/comments/commentRss/1342309.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/artech/services/trackbacks/1342309.html</trackback:ping><description><![CDATA[摘要: 基于Enterprise Library PIAB的AOP框架已经在公司项目开发中得到广泛的使用，但是最近同事维护一个老的项目，使用到了Enterprise Library 2，所以PIAB是在Enterprise Library 3.0中推出的，所以不同直接使用。为了解决这个问题，我写了一个通过方法劫持（Method Interception）的原理，写了一个简易版的AOP框架。&nbsp;&nbsp;<a href='http://www.cnblogs.com/artech/archive/2008/11/27/1342309.html'>阅读全文</a><img src ="http://www.cnblogs.com/artech/aggbug/1342309.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/43799/" target="_blank">[新闻]微软发布云计算版第四代模块化数据中心</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>巧用Reponse.Filter实现多语言功能</title><link>http://www.cnblogs.com/tsoukw/archive/2008/11/26/1341188.html</link><dc:creator>Kevin Zou</dc:creator><author>Kevin Zou</author><pubDate>Wed, 26 Nov 2008 02:24:00 GMT</pubDate><guid>http://www.cnblogs.com/tsoukw/archive/2008/11/26/1341188.html</guid><wfw:comment>http://www.cnblogs.com/tsoukw/comments/1341188.html</wfw:comment><comments>http://www.cnblogs.com/tsoukw/archive/2008/11/26/1341188.html#Feedback</comments><slash:comments>26</slash:comments><wfw:commentRss>http://www.cnblogs.com/tsoukw/comments/commentRss/1341188.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/tsoukw/services/trackbacks/1341188.html</trackback:ping><description><![CDATA[摘要: 对于有跨国业务的web系统来说，一般都需要提供多语言功能。然而在众多多语言方案里，如.net自带的Resource方式，都会在程序开发时增加程序员的额外负担，不易开发：1.各种不同的地方实现多语言，如aspx的control绑定,js脚本，cs代码,procedure里的提示信息等，这些多语言实现方式各不相同，加重了开发难度...
&nbsp;&nbsp;<a href='http://www.cnblogs.com/tsoukw/archive/2008/11/26/1341188.html'>阅读全文</a><img src ="http://www.cnblogs.com/tsoukw/aggbug/1341188.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/43798/" target="_blank">[新闻]IBM发布“无微软”虚拟桌面系统</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>微软同步框架(MSF)入门之五--使用WCF同步远程数据</title><link>http://www.cnblogs.com/daizhj/archive/2008/11/25/1337245.html</link><dc:creator>代震军</dc:creator><author>代震军</author><pubDate>Tue, 25 Nov 2008 01:00:00 GMT</pubDate><guid>http://www.cnblogs.com/daizhj/archive/2008/11/25/1337245.html</guid><wfw:comment>http://www.cnblogs.com/daizhj/comments/1337245.html</wfw:comment><comments>http://www.cnblogs.com/daizhj/archive/2008/11/25/1337245.html#Feedback</comments><slash:comments>8</slash:comments><wfw:commentRss>http://www.cnblogs.com/daizhj/comments/commentRss/1337245.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/daizhj/services/trackbacks/1337245.html</trackback:ping><description><![CDATA[摘要:      在之前介绍的两个DEMO中，链接远程服务器所使用的方式都是通过数据库链接串。虽然可以简单的实现所期望的数据同步功能，但这样做有两个问题：
    1.不适合进行分布式布署.    
    2.安全方面存在问题，因为在客户端会持有远程数据库服务器的链接帐号。&nbsp;&nbsp;<a href='http://www.cnblogs.com/daizhj/archive/2008/11/25/1337245.html'>阅读全文</a><img src ="http://www.cnblogs.com/daizhj/aggbug/1337245.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/43797/" target="_blank">[新闻]2008年12月5日科技博客精选</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>方法的直接调用，反射调用与……Lambda表达式调用</title><link>http://www.cnblogs.com/JeffreyZhao/archive/2008/11/24/invoke-method-by-lambda-expression.html</link><dc:creator>Jeffrey Zhao</dc:creator><author>Jeffrey Zhao</author><pubDate>Mon, 24 Nov 2008 01:59:00 GMT</pubDate><guid>http://www.cnblogs.com/JeffreyZhao/archive/2008/11/24/invoke-method-by-lambda-expression.html</guid><wfw:comment>http://www.cnblogs.com/JeffreyZhao/comments/1338682.html</wfw:comment><comments>http://www.cnblogs.com/JeffreyZhao/archive/2008/11/24/invoke-method-by-lambda-expression.html#Feedback</comments><slash:comments>78</slash:comments><wfw:commentRss>http://www.cnblogs.com/JeffreyZhao/comments/commentRss/1338682.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/JeffreyZhao/services/trackbacks/1338682.html</trackback:ping><description><![CDATA[摘要: 想调用一个方法很容易，直接代码调用就行，这人人都会。其次呢，还可以使用反射。不过通过反射调用的性能会远远低于直接调用——至少从绝对时间上来看的确是这样。因此，很多框架在必须利用到反射的场景中，都会设法使用一些较高级的替代方案来改善性能。例如，使用CodeDom生成代码并动态编译，或者使用Emit来直接编写IL。不过自从.NET 3.5发布了Expression相关的新特性，我们在以上的情况下又有了更方便并直观的解决方案。&nbsp;&nbsp;<a href='http://www.cnblogs.com/JeffreyZhao/archive/2008/11/24/invoke-method-by-lambda-expression.html'>阅读全文</a><img src ="http://www.cnblogs.com/JeffreyZhao/aggbug/1338682.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/43796/" target="_blank">[新闻]Google和Facebook同日推Connect数据迁移功能</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>微软同步框架(MSF)入门之四--冲突(Conflict)检测和处理</title><link>http://www.cnblogs.com/daizhj/archive/2008/11/24/1336559.html</link><dc:creator>代震军</dc:creator><author>代震军</author><pubDate>Mon, 24 Nov 2008 01:07:00 GMT</pubDate><guid>http://www.cnblogs.com/daizhj/archive/2008/11/24/1336559.html</guid><wfw:comment>http://www.cnblogs.com/daizhj/comments/1336559.html</wfw:comment><comments>http://www.cnblogs.com/daizhj/archive/2008/11/24/1336559.html#Feedback</comments><slash:comments>7</slash:comments><wfw:commentRss>http://www.cnblogs.com/daizhj/comments/commentRss/1336559.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/daizhj/services/trackbacks/1336559.html</trackback:ping><description><![CDATA[摘要:      在几篇文章当中，我介绍了 SnapShot(快照方式)和“只同步新更改和增量更改”这两种同步方式并对相应的生成文件进行了粗略的分析。今天开始把话题深入一下，聊一聊MSF的冲突检测和处理。这里所说的冲突(Conflict) 主要是指当客户端与服务端数据在进行CUD时，所操作的数据同步期间发生了错误，如通常所说的约束冲突（主键重复），以及在同步时多个节点（客户端）上更改了同一行，或服务端删除该行而其它节点却更新了该行便存在冲突等。当然在设计应用程序时应避免产生冲突（比如可通过筛选行和列等方式做到这一点），因为冲突的检测和解决会增加应用程序的复杂性，增加处理负担和网络流量。&nbsp;&nbsp;<a href='http://www.cnblogs.com/daizhj/archive/2008/11/24/1336559.html'>阅读全文</a><img src ="http://www.cnblogs.com/daizhj/aggbug/1336559.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/43795/" target="_blank">[新闻]UserAgent的历史变迁</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>写在WinHEC开幕之际：沿着Windows我们一路走来</title><link>http://www.cnblogs.com/Terrylee/archive/2008/11/23/1339477.html</link><dc:creator>TerryLee</dc:creator><author>TerryLee</author><pubDate>Sun, 23 Nov 2008 10:59:00 GMT</pubDate><guid>http://www.cnblogs.com/Terrylee/archive/2008/11/23/1339477.html</guid><wfw:comment>http://www.cnblogs.com/Terrylee/comments/1339477.html</wfw:comment><comments>http://www.cnblogs.com/Terrylee/archive/2008/11/23/1339477.html#Feedback</comments><slash:comments>29</slash:comments><wfw:commentRss>http://www.cnblogs.com/Terrylee/comments/commentRss/1339477.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Terrylee/services/trackbacks/1339477.html</trackback:ping><description><![CDATA[摘要: <div style="float:right;padding-right:5px;"><img src="http://www.cnblogs.com/images/cnblogs_com/Terrylee/120066/o_winHEC.png" alt=""/></div>微软 2008 Windows 硬件工程大会（Windows Hardware Engineering Conference 2008，简称WinHEC 2008 China）即将于 2008年12月3-4日在北京万豪酒店盛大开幕，今年是微软第一次在中国独立举办WinHEC大会，以至于JesseQu用WinHEC终于来了一文回忆了自己近18年软件开发工作中对驱动、内核层次开发工作的情愫感慨。在WinHEC 2008开幕之际，让我们一起来回顾一下Windows的发展历史，寻找那些曾经熟悉的符号。&nbsp;&nbsp;<a href='http://www.cnblogs.com/Terrylee/archive/2008/11/23/1339477.html'>阅读全文</a><img src ="http://www.cnblogs.com/Terrylee/aggbug/1339477.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/43794/" target="_blank">[新闻]棱角分明: Google Reader 阅读器外观和功能更新</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>也来凑泛型协变/反变的热闹</title><link>http://www.cnblogs.com/sumtec/archive/2008/11/23/1339252.html</link><dc:creator>Sumtec</dc:creator><author>Sumtec</author><pubDate>Sun, 23 Nov 2008 06:33:00 GMT</pubDate><guid>http://www.cnblogs.com/sumtec/archive/2008/11/23/1339252.html</guid><wfw:comment>http://www.cnblogs.com/sumtec/comments/1339252.html</wfw:comment><comments>http://www.cnblogs.com/sumtec/archive/2008/11/23/1339252.html#Feedback</comments><slash:comments>16</slash:comments><wfw:commentRss>http://www.cnblogs.com/sumtec/comments/commentRss/1339252.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/sumtec/services/trackbacks/1339252.html</trackback:ping><description><![CDATA[摘要: 前言今天看了两篇讲协变/反变的文章，写得很好也很有意思。不过我猜应该有不少人可能还是很难理解这个新概念——每一次推出新的概念的时候，都会或多或少造成我们的困惑：这是个什么东西？为什么要出这么复杂的东西？我们什么时候应该用这种东西，什么时候不该用？有这样的困惑没关系，我想绝大多数人都经历过这个过程。我在这里呢，也说说从我的角度是如何看这个新鲜事物的，也许对理解这个东西有帮助。不过先声明一下，我没有装&nbsp;&nbsp;<a href='http://www.cnblogs.com/sumtec/archive/2008/11/23/1339252.html'>阅读全文</a><img src ="http://www.cnblogs.com/sumtec/aggbug/1339252.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/43793/" target="_blank">[新闻]雅虎董事伊坎迷恋微软 反对AOL前CEO米勒插足</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>visifire笔记</title><link>http://www.cnblogs.com/aspnetx/archive/2008/11/23/1339368.html</link><dc:creator>aspnetx</dc:creator><author>aspnetx</author><pubDate>Sun, 23 Nov 2008 05:50:00 GMT</pubDate><guid>http://www.cnblogs.com/aspnetx/archive/2008/11/23/1339368.html</guid><wfw:comment>http://www.cnblogs.com/aspnetx/comments/1339368.html</wfw:comment><comments>http://www.cnblogs.com/aspnetx/archive/2008/11/23/1339368.html#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://www.cnblogs.com/aspnetx/comments/commentRss/1339368.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/aspnetx/services/trackbacks/1339368.html</trackback:ping><description><![CDATA[摘要: visifire是silverlight下很不错的一套开源组件,最近其发布了2.0beta版本,本文将主要记录一些这个版本跟以前版本不同的地方.
昨天初步把1.55版本移植到了2.0beta,没有遇到太大的麻烦,不过确实还是进行一些细节的修改,这些更改看上去更合理了,很多东西都不用往children下硬塞,直接类似Serise.Add或者Titles.Add就可以了.
由于visifire更新速度还是挺快的,所以请留意下,写这篇文章的时候visifire的版本是2.0 beta,未来的版本可能会有变化,具体细节请阅读当前时间的visifire对应版本的文档. &nbsp;&nbsp;<a href='http://www.cnblogs.com/aspnetx/archive/2008/11/23/1339368.html'>阅读全文</a><img src ="http://www.cnblogs.com/aspnetx/aggbug/1339368.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/43792/" target="_blank">[新闻]微软任命雅虎前高管陆奇互联网业务总裁</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item></channel></rss>