你真的了解Ioc与AOP吗?(1)
本系列的全部源代码及二进制文件可以从这里下载: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)相关推荐
- 你真的了解Ioc与AOP 吗?(2)
三.基于配置文件和Reflection的工厂模式 为了消除MainApp对其它组件的依赖性,我们引入工厂模式,并且根据配置文件指定的装配规程,利用.net提供的反射技术完成对象的组装工作.本部分代码仅 ...
- 再品Spring Ioc 和 Aop
文章目录 Spring好处 IOC 基于XML和基于注解开发 基于XML开发 基于注解开发 配置类 扫包+注解 依赖注入 AOP 写在前面,这篇文章写的时候我的SSM已经学过一遍了,回头来看真的受益匪 ...
- 面试官:谈谈你对IOC和AOP的理解及AOP四种实现方式
目录 一.IOC与AOP介绍 二.实现AOP的四种方式 方式1:基于经典代理来实现 方式2:使用Spring AOP的API接口 方式3:自定义类来实现AOP 方式4:基于注解实现 一.IOC与AOP ...
- BeanPostProcessor —— 连接Spring IOC和AOP的桥梁
之前都是从大Boss的视角,来介绍Spring,比如IOC.AOP. 今天换个视角,从一个小喽啰出发,来加深对Spring的理解. 这个小喽啰就是, BeanPostProcessor (下面简称 B ...
- 自己动手实现的 Spring IOC 和 AOP - 下篇
1. 背景 本文承接上文,来继续说说 IOC 和 AOP 的仿写.在上文中,我实现了一个很简单的 IOC 和 AOP 容器.上文实现的 IOC 和 AOP 功能很单一,且 IOC 和 AOP 两个模块 ...
- 自己动手实现的 Spring IOC 和 AOP - 上篇
1. 背景 我在大四实习的时候开始接触 J2EE 方面的开发工作,也是在同时期接触并学习 Spring 框架,到现在也有快有两年的时间了.不过之前没有仿写过 Spring IOC 和 AOP,只是宏观 ...
- Spring 原理初探——IoC、AOP
前言 众所周知, 现在的 Spring 框架已经成为构建企业级 Java 应用事实上的标准了,众多的企业项目都构建在 Spring 项目及其子项目之上,特别是 Java Web 项目. Spring ...
- spring aop 必须的包 及里面用到的东西_Spring 原理初探——IoC、AOP
前言 众所周知, 现在的 Spring 框架已经成为构建企业级 Java 应用事实上的标准了,众多的企业项目都构建在 Spring 项目及其子项目之上,特别是 Java Web 项目. Spring ...
- 我们到底为什么要用 IoC 和 AOP
作为一名 Java 开发,对 Spring 框架是再熟悉不过的了.Spring 支持的控制反转(Inversion of Control,缩写为IoC)和面向切面编程(Aspect-oriented ...
- Dubbo的SPI机制对比传统的SPI做了哪些改进?Dubbo的IOC和AOP
文章目录 1. JAVA的SPI机制 2. Dubbo的SPI机制 3. Dubbo的SPI源码解析 3.1 获取接口对应的 ExtensionLoader 3.2 根据入参的http获取对应的htt ...
最新文章
- numpy vsplit
- 主创仅2人,题材是大型3D战争,这款游戏竟然“超逼真”?
- Android对应用程序签名
- python以写模式打开录入_Python的学习(六)—-文件和输入输出处理 | 学步园
- c语言陷阱试题,超级经典计算机二级C语言陷阱考试题.doc
- C#编程(八十一)---------- 捕获异常
- GitHub Pages自定义域名如何支持https
- php openssl.so加载,LINUX下PHP编译添加相应的动态扩展模块so(不需要重新编译PHP,以openssl.so为例)...
- csdn 博客代码块显示复制按钮
- rpcbind.service启动失败
- 软件测试 | 试用期总结万能模板
- 字母’x’在CSS世界中的角色和故事
- 2009年毕业设计题目:网上自助装机系统的设计与实现
- fetion-robot是基于web飞信接口的飞信机器人
- nginx499问题
- 【论文阅读】MLO: Multi-Object Tracking and Lidar Odometry in Dynamic Environment
- 巨斧砍大树-sdut
- IDA动态调试so 指南
- 【react】This synthetic event is reused for performance reasons.
- 医院计算机系统日常维护记录表,医院计算机信息管理系统维护措施