文档章节

构造基于配置文件的IOC容器

我只是一只小小鸟
 我只是一只小小鸟
发布于 2016/07/13 13:18
字数 1484
阅读 55
收藏 0
IOC

一.背景

本文是建立在你已经对面向接口编程很熟悉的基础上的。即你已不是处于面向类编程的阶段。若对面向接口编程不是很熟悉,请参考我的博文:http://my.oschina.net/RabbitXiao/blogcatalog=3509386&temp=1468383616081先看简单工厂再看抽象工厂。对接口设计先有一个大致的了解。

那知道一些设计模式的朋友应该知道,一旦面向接口编程,势必就得拿到已实现的接口。为此一些列的设计模式诞生了,比如简单工厂模式,抽象工厂模式等这就是本文要讨论的内容,通过ioc控制反转,转移接口控制权,降低耦合。

二.剖析直接类与类相互依赖的弊端

前提:我们假想一个做菜吃的简单场景。

针对不同的原料得到对应的菜,其具体实现如下:

namespace LogicLayer.rabbit
{
    /// <summary>
    /// 土豆助手类
    /// </summary>
    public class potatoHelper
    {

        public void Cook()
        {
            Console.WriteLine("您要的土豆已经做好!");
        }
    }
}


namespace LogicLayer.rabbit
{
    /// <summary>
    /// 西红柿助手类
    /// </summary>
    class tomatoHelper
    {

        public void Cook()
        {
            Console.WriteLine("您要的西红柿已经做好啦!");
        }
    }
}

如果你没有面向接口的思想,你极有可能这么拿到土豆丝这盘菜.代码如下:

namespace Xml_IocDemo
{
    class Program
    {
        static void Main(string[] args)
        {
            //面向类编程,类与类之间耦合
            potatoHelper patatocooker = new potatoHelper();
            patatocooker.Cook();
            Console.Read();

          
        }
    }
}

然我们来一起分析这样做的耦合关系即依赖关系

很显然,Progrm这个类是依赖potatoHelper这个类的。所谓的依赖就是program调用了potatohelper这个类就表示前者依赖后者。这仅仅是一个很简单的例子,倘若有很多类需要调用,这样program就依赖了很多具体的实例。弊端在哪里?如果后期要改功能或者突然不想使用这个实例要换一个,更有甚者,类名也要换了。这样会改到你到崩溃,因为这个的实例被调用的时候并不是仅仅只在progrm这一个地方,可能很多地方都涉及到了调用。为了降低耦合,实现开闭原则。设计成接口形式,就会稳定的多。因为接口相对来说是很少会被更改的。

*有两句话送给大家,也是我在网上看到的,鄙人非常赞同

  • A. 上层模块不应该依赖于下层模块,它们共同依赖于一个抽象。  
  • B. 抽象不能依赖于具象,具象依赖于抽象。

三.接口设计

于是呼可以重构成如下代码:

namespace LogicLayer.xk
{
    /// <summary>
    /// 厨师接口
    /// </summary>
  public  interface ICooker
    {
        void Cook();
    }
}


namespace LogicLayer.rabbit
{
    /// <summary>
    /// 土豆助手类
    /// </summary>
    public class potatoHelper:ICooker
    {

        public void Cook()
        {
            Console.WriteLine("您要的土豆已经做好!");
        }
    }
}

namespace LogicLayer.rabbit
{
    /// <summary>
    /// 西红柿助手类
    /// </summary>
    class tomatoHelper:ICooker
    {

        public void Cook()
        {
            Console.WriteLine("您要的西红柿已经做好啦!");
        }
    }
}

四.如何拿到ICooker接口?

这一步才是非常关键的地方,因为即使你设计到了接口,但是拿接口不恰当也不一定能满足开闭原则,后期功能扩展或者维护起来也不一定就方便了多少。当然有很多设计模式都立在解决如何拿到这个接口,不通的系统规模和场景选择的设计模式也不尽相同。今天将给大家带来的是依赖反转,转移依赖控制权给配置文件,通过配置文件利用反射来拿到我们需要的接口。

如果你是winform或者控制台程序,项目里面应该就会有个叫app.config的配置文件,web程序就应该有个叫web.conifg的配置文件。不管是哪一种配置都是一样的使用方法。

我们可以进行如下的配置:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
    <startup> 
        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
    </startup>

  <appSettings>
    <add key="土豆" value="LogicLayer.rabbit.potatoHelper" />
    <add key="西红柿" value="LogicLayer.rabbit.tomatoHelper" />
  </appSettings>
</configuration>

配置好这一切后,正在精华的地方要来了。新建一个ioc容器类,专门用于透过配置文件拿接口

代码如下:

namespace LogicLayer
{
    public   class IOC_Factory
    {
      /// <summary>
        /// 得到厨师
        /// </summary>
        /// <typeparam name="T">你想实现的接口</typeparam>
        /// <param name="key">指定要什么菜</param>
        /// <returns>关于这道菜对应的厨师接口</returns>
        public static T GetCooker<T>(string key) 
        {
           
           string classname = ConfigHelper.GetConfiginfo(key);
           string assemblyname = classname.Substring(0,classname.LastIndexOf('.'));
           try
           {
               return (T)Assembly.Load(assemblyname).CreateInstance(classname);
           }
           catch (Exception)
           {
               return default(T);
           }
          
        }

    }
}

五.利用ioc容器工厂拿到接口后使用

什么都别说看代码:

namespace Xml_IocDemo
{
    class Program
    {
        static void Main(string[] args)
        {
         
            //面向接口编程,类只与接口打交道
            ICooker Cooker = IOC_Factory.GetCooker<ICooker>("土豆");
            Cooker.Cook();
            Console.Read();
        }
    }
}

六.分析与总结

看完以上你是否能够模糊的感觉到这样做的好处?一旦我们这样做了,不管你的土豆助手类怎么变化,包括你的类名变了,我们只需要在配置文件里面做相应的调整即可,因为接口是稳定的,那么已有功能的维护就会变得很简单。倘若需要扩展新功能,比方说需要吃茄子,那很好办,实现一个茄子类,让其继承ICooker接口,然后在配置文件中配置好它。这样我们使用的时候只需要这样  ICooker Cooker = IOC_Factory.GetCooker<ICooker>("茄子");即可。如果看了我的以前的两篇关于简单工厂模式和抽象工厂模式的朋友,你觉得他们之间有什么区别嘛?仔细体会吧。个人认为ioc反转依赖是比较好的一种拿接口的方式。

有不明白的,或者多设计模式和架构有兴趣的可以加qq:739462304.相互交流经验

七.附实现该ioc容器例子的demo

http://git.oschina.net/shenjingbing/Xml_IocDemo

© 著作权归作者所有

共有 人打赏支持
我只是一只小小鸟
粉丝 14
博文 102
码字总数 53116
作品 1
荆州
程序员
私信 提问
浅析 Spring IoC - 注入方式

IoC 容器的概念 IoC 容器指 具有依赖注入功能的容器,IoC 容器负责实例化、定位、配置应用程序中的对象及建立这些对象间的依赖。应用程序无需直接在代码中 new 相关对象,而是由 IoC 容器进行...

pradosoul
2015/10/19
266
0
Spring Ioc (Inversion of Control)

以下整理自http://jinnianshilongnian.iteye.com/blog/1413846,如有侵权立即删除。 Ioc Ioc(Inversion of Control),即控制反转。不是什么技术,而是一种设计思想。在Java开发中,Ioc意味...

冰雷卡尔
2012/07/31
0
0
基于unity框架构造IOC容器

一.写在前面 基于上一篇通过配置文件形成ioc容器的例子,我们采用另外一种方式去形成ioc容器,那就是unity框架。 二.unity简介 Unity 应用程序块(Unity)是一个轻量级、可扩展的依赖注入容器...

我只是一只小小鸟
2016/07/14
278
0
spring学习——Ioc基础三(Ioc配置使用)

一、XML配置的结构 一般配置文件结构如下: <beans> <import resource=”resource1.xml”/> <bean id=”bean1”class=””></bean> <bean id=”bean2”class=””></bean> <bean name=”bea......

小风89
2015/10/11
652
0
Spring IoC容器(一)

一、Spring IoC 容器和 Bean 简介 IoC也称为依赖注入(dependency injection, DI)。这是一个过程,在这个过程中,对象仅通过构造函数参数、工厂方法的参数或对象实例构造或从工厂方法返回后在...

皮皮猫32
04/17
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Linux iptables之mangle表使用案例

mangle表的用途 mangle表的主要功能是根据规则修改数据包的一些标志位,以便其他规则或程序可以利用这种标志对数据包进行过滤或策略路由。 mangel表使用示例 示例1-策略路由1 内网的客户机通...

月下狼
45分钟前
2
0
OSChina 周日乱弹 —— 兼职我想去学学布偶戏

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @clouddyy : 《火炎 - 女王蜂》 《火炎 - 女王蜂》 手机党少年们想听歌,请使劲儿戳(这里) @小鱼丁 :还在睡觉突然接到一个小哥哥电话“x...

小小编辑
58分钟前
54
5
租房软件隐私保护如同虚设

近日,苏州市民赵先生向江苏新闻广播新闻热线025-84658888反映,他在“安居客”手机应用软件上浏览二手房信息,并且使用该软件自动生成的虚拟号码向当地一家中介公司进行咨询。可电话刚挂不久...

linux-tao
今天
3
0
分布式项目(五)iot-pgsql

书接上回,在Mapping server中,我们已经把数据都整理好了,现在利用postgresql存储历史数据。 iot-pgsql 构建iot-pgsql模块,这里我们写数据库为了性能考虑不在使用mybatis,换成spring jd...

lelinked
今天
6
0
一文分析java基础面试题中易出错考点

前言 这篇文章主要针对的是笔试题中出现的通过查看代码执行结果选择正确答案题材。 正式进入题目内容: 1、(单选题)下面代码的输出结果是什么? public class Base { private Strin...

一看就喷亏的小猿
今天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部