本系列的全部源代码及二进制文件可以从这里下载:IocInCSharp.rar

你真的了解Ioc与AOP吗?(1)

你真的了解Ioc与AOP吗?(2)

你真的了解Ioc与AOP吗?(3)

你真的了解Ioc与AOP吗?(4)

你真的了解Ioc与AOP吗?(5)


本部分示例代码请参考"src\Step1"、"src\Step2"目录

你真的了解Ioc与AOP吗?我现在还不是很了解,而且越学习越发现自己了解的很少,Ioc与AOP中蕴涵了大量的能量等待我们去开发。在这个系列 中,我仅仅利用Sping.net这个框架向大家展示一下Ioc与AOP的强大功能(呵呵,其实写这段话的目的是因为“文章题目”牛皮吹得有点大了,给自 己个台阶下罢了)。

在这个系列中一共包含6个案例,从简单到复杂,也是对问题分解、思考和解决的一个过程,它们分别是:(1)类之间的依赖;(2)接口依赖;(3)基 于配置文件和Reflection的工厂模式;(4)使用Spring.net实现Ioc;(5)Romoting;(6)利用Ioc在不动一行代码的情 况下实现Remoting。为了更好的理解文中的内容,最好顺序阅读。

作为一个应用系统,代码复用至关重要。如果在你的设计中,类与类存在很强的相互关联,那么你会发现在重用这些组件时就存在很严重的问题。在 Step1到Step3-Reflection的例子中,我们试图 利用“针对接口编程”以及自己设计的Ioc对系统进行解耦。在Step3到Step5的例子中,我们将利用Spring.net提供的Ioc框架,轻松完 成解耦以及系统改造等工作。

一、类之间的依赖

我们的第一个例子主要用于说明程序的基本构造,并且作为一个反面典型,引出为什么要解耦,以及如何下手。在这个例子中,我们将创建三个程序集,分别是MainApp.exe、HelloGenerator.dll以及SayHello.dll。它们之间的关系如下图所示:

HelloGenerator类根据提供的姓名产生一个问候字符串,代码如下:

using System;
namespace IocInCSharp
{public class EnHelloGenerator{public string GetHelloString(string name){return String.Format("Hello, {0}", name);}}
}

SayHello类持有一个对EnHelloGenerator的引用,并负责将生成出来的问候字符串打印出来。

using System;
namespace IocInCSharp
{public class SayHello{private EnHelloGenerator _helloGen;public EnHelloGenerator HelloGenerator{get { return _helloGen; }set { _helloGen = value; }}public void SayHelloTo(string name){if(_helloGen != null)Console.WriteLine(_helloGen.GetHelloString(name));elseConsole.WriteLine("Client.hello is not initialized");}}
}

MainApp.exe负责完成对象的创建、组装以及调用工作:

using System;
namespace IocInCSharp
{public class MainApp{public static void Main(){SayHello sayHello = new SayHello();sayHello.HelloGenerator = new EnHelloGenerator();sayHello.SayHelloTo("zhenyulu");}}
}

在这个设计中,组件与组件之间、类与类之间存在着紧密的耦合关系。SayHello类中的_helloGen字段类型为 EnHelloGenerator,这将导致我们很难给它赋予一个其它的HelloGenerator(例如CnHelloGenerator,用于生成 中文问候语)。另外MainApp也严重依赖于SayHello.dll以及HelloGenerator.dll,在程序中我们可以看到类似new SayHello();new EnHelloGenerator();的命令。

这种紧密的耦合关系导致组件的复用性降低。试想,如果想复用SayHello组件,那么我们不得不连同HelloGenerator一同拷贝过去, 因为SayHello.dll是依赖与HelloGenerator.dll的。解决这个问题的办法就是“针对抽象(接口)”编程 (依赖倒置原则)。这里的抽象既包括抽象类也包括接口。我不想过多的去谈抽象类和接口的区别,在后续的例子中我们将使用接口。由于接口在进行“动态代理” 时仍能保持类型信息,而抽象类可能由于代理的原因导致继承关系的“截断”(如MixIn等)。除此之外,对于单继承的C#语言而言,使用接口可以拥有更大 的弹性。

二、接口依赖

既然类之间的依赖导致耦合过于紧密,按照《设计模式》的理论,我们要依赖于接口。但是人们往往发现,仅仅依赖于接口似乎并不能完全解决问题。我们从上面的例子中抽象出接口后,组件间的依赖关系可能变成如下图所示:

经过改造后,SayHello不再依赖于具体的HelloGenerator,而是依赖于IHelloGenerator接口,如此一来,我们可以 动态的将EnHelloGenerator或是CnHelloGenerator赋给SayHello,其打印行为也随之发生改变。接口的定义以及改造后 的SayHello代码如下(为了节省空间,将代码合并书写):

using System;
namespace IocInCSharp
{public interface IHelloGenerator{string GetHelloString(string name);}public interface ISayHello{IHelloGenerator HelloGenerator{ get; set; }void SayHelloTo(string name);}public class SayHello : ISayHello{private IHelloGenerator _helloGen;public IHelloGenerator HelloGenerator{get { return _helloGen; }set { _helloGen = value; }}public void SayHelloTo(string name){if(_helloGen != null)Console.WriteLine(_helloGen.GetHelloString(name));elseConsole.WriteLine("Client.hello is not initialized");}}
}

但是我们的MainApp似乎并没有从接口抽象中得到什么好处,从图中看,MainApp居然依赖于三个组件:ICommon.dll、 HelloGenerator.dll以及SayHello.dll。这是由于MainApp在这里负责整体的“装配”工作。如果这三个组件中的任何一个 发生变化,都将导致MainApp.exe的重新编译和部署。从这个角度来看,似乎“针对接口编程”并没有为我们带来太多的好处。

如果能够将“组件装配”工作抽象出来,我们就可以将MainApp的复杂依赖关系加以简化,从而 进一步实现解耦。为此,我们引入“工厂”模式,并利用配置文件和反射技术,动态加载和装配相关组件。(待续)

 原文链接:http://www.cnblogs.com/zhenyulu/zhenyulu/articles/233966.html

转载于:https://www.cnblogs.com/xwj517537691/archive/2013/06/06/3121009.html

你真的了解Ioc与AOP吗?(1)相关推荐

  1. 你真的了解Ioc与AOP 吗?(2)

    三.基于配置文件和Reflection的工厂模式 为了消除MainApp对其它组件的依赖性,我们引入工厂模式,并且根据配置文件指定的装配规程,利用.net提供的反射技术完成对象的组装工作.本部分代码仅 ...

  2. 再品Spring Ioc 和 Aop

    文章目录 Spring好处 IOC 基于XML和基于注解开发 基于XML开发 基于注解开发 配置类 扫包+注解 依赖注入 AOP 写在前面,这篇文章写的时候我的SSM已经学过一遍了,回头来看真的受益匪 ...

  3. 面试官:谈谈你对IOC和AOP的理解及AOP四种实现方式

    目录 一.IOC与AOP介绍 二.实现AOP的四种方式 方式1:基于经典代理来实现 方式2:使用Spring AOP的API接口 方式3:自定义类来实现AOP 方式4:基于注解实现 一.IOC与AOP ...

  4. BeanPostProcessor —— 连接Spring IOC和AOP的桥梁

    之前都是从大Boss的视角,来介绍Spring,比如IOC.AOP. 今天换个视角,从一个小喽啰出发,来加深对Spring的理解. 这个小喽啰就是, BeanPostProcessor (下面简称 B ...

  5. 自己动手实现的 Spring IOC 和 AOP - 下篇

    1. 背景 本文承接上文,来继续说说 IOC 和 AOP 的仿写.在上文中,我实现了一个很简单的 IOC 和 AOP 容器.上文实现的 IOC 和 AOP 功能很单一,且 IOC 和 AOP 两个模块 ...

  6. 自己动手实现的 Spring IOC 和 AOP - 上篇

    1. 背景 我在大四实习的时候开始接触 J2EE 方面的开发工作,也是在同时期接触并学习 Spring 框架,到现在也有快有两年的时间了.不过之前没有仿写过 Spring IOC 和 AOP,只是宏观 ...

  7. Spring 原理初探——IoC、AOP

    前言 众所周知, 现在的 Spring 框架已经成为构建企业级 Java 应用事实上的标准了,众多的企业项目都构建在 Spring 项目及其子项目之上,特别是 Java Web 项目. Spring ...

  8. spring aop 必须的包 及里面用到的东西_Spring 原理初探——IoC、AOP

    前言 众所周知, 现在的 Spring 框架已经成为构建企业级 Java 应用事实上的标准了,众多的企业项目都构建在 Spring 项目及其子项目之上,特别是 Java Web 项目. Spring ...

  9. 我们到底为什么要用 IoC 和 AOP

    作为一名 Java 开发,对 Spring 框架是再熟悉不过的了.Spring 支持的控制反转(Inversion of Control,缩写为IoC)和面向切面编程(Aspect-oriented ...

  10. Dubbo的SPI机制对比传统的SPI做了哪些改进?Dubbo的IOC和AOP

    文章目录 1. JAVA的SPI机制 2. Dubbo的SPI机制 3. Dubbo的SPI源码解析 3.1 获取接口对应的 ExtensionLoader 3.2 根据入参的http获取对应的htt ...

最新文章

  1. numpy vsplit
  2. 主创仅2人,题材是大型3D战争,这款游戏竟然“超逼真”?
  3. Android对应用程序签名
  4. python以写模式打开录入_Python的学习(六)—-文件和输入输出处理 | 学步园
  5. c语言陷阱试题,超级经典计算机二级C语言陷阱考试题.doc
  6. C#编程(八十一)---------- 捕获异常
  7. GitHub Pages自定义域名如何支持https
  8. php openssl.so加载,LINUX下PHP编译添加相应的动态扩展模块so(不需要重新编译PHP,以openssl.so为例)...
  9. csdn 博客代码块显示复制按钮
  10. rpcbind.service启动失败
  11. 软件测试 | 试用期总结万能模板
  12. 字母’x’在CSS世界中的角色和故事
  13. 2009年毕业设计题目:网上自助装机系统的设计与实现
  14. fetion-robot是基于web飞信接口的飞信机器人
  15. nginx499问题
  16. 【论文阅读】MLO: Multi-Object Tracking and Lidar Odometry in Dynamic Environment
  17. 巨斧砍大树-sdut
  18. IDA动态调试so 指南
  19. 【react】This synthetic event is reused for performance reasons.
  20. 医院计算机系统日常维护记录表,医院计算机信息管理系统维护措施

热门文章

  1. 实验——基于文件验证和MYSQL验证的vsftpd虚拟用户
  2. java中的Map每次只能put一次,写段增强的put,可以一次put很多次
  3. mac Lion 10.7系统使用笔记
  4. 】oracle em配置常用命令
  5. 论文阅读笔记——拥塞控制算法PCC Vivace
  6. CF1042A Benches
  7. vue组件中传值遇到的一些问题
  8. vue项目中打包的相关配置问题
  9. jemter java请求后置_jmeter完成一个java请求-本机调用
  10. mysql内存淘汰_mysql内存数据淘汰机制和大查询会不会把内存打爆?