天天看点

普通接口、多态、工厂模式、依赖注入三者的耦合强度区别

第一个例子 普通的多态

第二个例子 运用工厂解除依赖耦合

第三个例子 刚是运用了依赖注入彻底解耦 借用spring.net 

     (1)也许有人说,IoC和工厂模式不是一样的作用吗,用IoC好象还麻烦一点。

   举个例子,如果用户需求发生变化,要把Chinese类修改一下。那么前一种工厂模式,就要更改Factory类的方法,并且重新编译布署。而IoC只需要将class属性改变一下,这些对象是动态生成的,这时我们就可以热插拨Chinese对象(不必把原程序停止下来重新编译布署)

  (2)也许有人说,即然IoC这么好,那么我把系统所有对象都用IoC方式来生成。

   注意,IoC的灵活性是有代价的:设置步骤麻烦、生成对象的方式不直观、比正常生成对象在效率上慢一点。因此使用IoC要看有没有必要,我认为比较通用的判断方式是:用到工厂模式的地方都可以考虑用IoC模式。

  (3)关于IoC的低侵入性。

   什么是低侵入性?如果你用过MVC或Nhibernate就会发现,要继承一些接口或类,才能利用它们的框架开发。这样,系统就被绑定在MVC、Nhibernate上了,对系统的可移植性产生不利的影响。如果代码中很少涉及某一个框架的代码,那么这个框架就可以称做是一个低侵入性的框架。

第一个例子是最明显的耦合 他没有画图 我给加了张图 vs中自带的类图里怎么也找不着依赖的箭头...我自己画了个箭头 不是很好看...!

  /// <summary>

普通接口、多态、工厂模式、依赖注入三者的耦合强度区别

    /// 抽象人类

普通接口、多态、工厂模式、依赖注入三者的耦合强度区别

    /// </summary>

普通接口、多态、工厂模式、依赖注入三者的耦合强度区别

    public abstract class Person

普通接口、多态、工厂模式、依赖注入三者的耦合强度区别

    {

普通接口、多态、工厂模式、依赖注入三者的耦合强度区别

        /// <summary>

普通接口、多态、工厂模式、依赖注入三者的耦合强度区别

        /// 使用工具劳动

普通接口、多态、工厂模式、依赖注入三者的耦合强度区别

        /// </summary>

普通接口、多态、工厂模式、依赖注入三者的耦合强度区别

        public abstract void Work();

普通接口、多态、工厂模式、依赖注入三者的耦合强度区别

    }

普通接口、多态、工厂模式、依赖注入三者的耦合强度区别
普通接口、多态、工厂模式、依赖注入三者的耦合强度区别

    public interface ITool

普通接口、多态、工厂模式、依赖注入三者的耦合强度区别
普通接口、多态、工厂模式、依赖注入三者的耦合强度区别
普通接口、多态、工厂模式、依赖注入三者的耦合强度区别

        /// 使用工具

普通接口、多态、工厂模式、依赖注入三者的耦合强度区别
普通接口、多态、工厂模式、依赖注入三者的耦合强度区别

        void UseTool();

普通接口、多态、工厂模式、依赖注入三者的耦合强度区别

  场景一,原始社会:原始人使用长矛打猎

普通接口、多态、工厂模式、依赖注入三者的耦合强度区别

    public class Spear : ITool

普通接口、多态、工厂模式、依赖注入三者的耦合强度区别
普通接口、多态、工厂模式、依赖注入三者的耦合强度区别

        public void UseTool()

普通接口、多态、工厂模式、依赖注入三者的耦合强度区别

        {

普通接口、多态、工厂模式、依赖注入三者的耦合强度区别

            Console.WriteLine("使用长矛");

普通接口、多态、工厂模式、依赖注入三者的耦合强度区别

        }

普通接口、多态、工厂模式、依赖注入三者的耦合强度区别
普通接口、多态、工厂模式、依赖注入三者的耦合强度区别
普通接口、多态、工厂模式、依赖注入三者的耦合强度区别

    public class PrimitivePerson : Person

普通接口、多态、工厂模式、依赖注入三者的耦合强度区别
普通接口、多态、工厂模式、依赖注入三者的耦合强度区别
普通接口、多态、工厂模式、依赖注入三者的耦合强度区别

        /// 原始社会使用长矛打猎

普通接口、多态、工厂模式、依赖注入三者的耦合强度区别
普通接口、多态、工厂模式、依赖注入三者的耦合强度区别

        public override void Work()

普通接口、多态、工厂模式、依赖注入三者的耦合强度区别
普通接口、多态、工厂模式、依赖注入三者的耦合强度区别

            //知道打猎使用的是长矛,并且制造长矛

普通接口、多态、工厂模式、依赖注入三者的耦合强度区别

            ITool tool = new Spear();

普通接口、多态、工厂模式、依赖注入三者的耦合强度区别

            tool.UseTool();

普通接口、多态、工厂模式、依赖注入三者的耦合强度区别

            Console.WriteLine("使用长矛打猎");

普通接口、多态、工厂模式、依赖注入三者的耦合强度区别
普通接口、多态、工厂模式、依赖注入三者的耦合强度区别
普通接口、多态、工厂模式、依赖注入三者的耦合强度区别

从上面代码我们不难看出,虽然使用的经典的里氏替换原则,但PrimitivePerson类于Spear类存在着耦合。

第二段代码 运用工厂

可以看到它加了一个工厂 包装了实例化 使得PrimitivePerson与Hoe没有直接存在耦合  但是工厂与PrimitivePerson之间还是有关系的 而且这种简单工厂往往会违背开闭原则(如有错误 求拍砖!)

 场景二,经济社会:使用工具耕作

普通接口、多态、工厂模式、依赖注入三者的耦合强度区别

    public class Hoe : ITool

普通接口、多态、工厂模式、依赖注入三者的耦合强度区别
普通接口、多态、工厂模式、依赖注入三者的耦合强度区别
普通接口、多态、工厂模式、依赖注入三者的耦合强度区别
普通接口、多态、工厂模式、依赖注入三者的耦合强度区别

            Console.WriteLine("使用锄头");

普通接口、多态、工厂模式、依赖注入三者的耦合强度区别
普通接口、多态、工厂模式、依赖注入三者的耦合强度区别
普通接口、多态、工厂模式、依赖注入三者的耦合强度区别
普通接口、多态、工厂模式、依赖注入三者的耦合强度区别

    public static class ToolFactory

普通接口、多态、工厂模式、依赖注入三者的耦合强度区别
普通接口、多态、工厂模式、依赖注入三者的耦合强度区别
普通接口、多态、工厂模式、依赖注入三者的耦合强度区别

        /// 工厂制造工具

普通接口、多态、工厂模式、依赖注入三者的耦合强度区别
普通接口、多态、工厂模式、依赖注入三者的耦合强度区别

        /// <returns></returns>

普通接口、多态、工厂模式、依赖注入三者的耦合强度区别

        public static ITool CreateTool()

普通接口、多态、工厂模式、依赖注入三者的耦合强度区别
普通接口、多态、工厂模式、依赖注入三者的耦合强度区别

            return new Hoe();  // 制造锄头

普通接口、多态、工厂模式、依赖注入三者的耦合强度区别
普通接口、多态、工厂模式、依赖注入三者的耦合强度区别
普通接口、多态、工厂模式、依赖注入三者的耦合强度区别
普通接口、多态、工厂模式、依赖注入三者的耦合强度区别

    public class EconomyPerson : Person

普通接口、多态、工厂模式、依赖注入三者的耦合强度区别
普通接口、多态、工厂模式、依赖注入三者的耦合强度区别
普通接口、多态、工厂模式、依赖注入三者的耦合强度区别

        /// 经济社会使用锄头耕作

普通接口、多态、工厂模式、依赖注入三者的耦合强度区别
普通接口、多态、工厂模式、依赖注入三者的耦合强度区别
普通接口、多态、工厂模式、依赖注入三者的耦合强度区别
普通接口、多态、工厂模式、依赖注入三者的耦合强度区别

            //不用知道什么工具,只需知道工厂能买到工具,而不自己制造工具,但仅由工厂制造锄头

普通接口、多态、工厂模式、依赖注入三者的耦合强度区别

            ITool tool = ToolFactory.CreateTool();

普通接口、多态、工厂模式、依赖注入三者的耦合强度区别
普通接口、多态、工厂模式、依赖注入三者的耦合强度区别

            Console.WriteLine("经济社会使用工具耕作");

普通接口、多态、工厂模式、依赖注入三者的耦合强度区别
普通接口、多态、工厂模式、依赖注入三者的耦合强度区别
普通接口、多态、工厂模式、依赖注入三者的耦合强度区别

第三段 运用依赖注入

普通接口、多态、工厂模式、依赖注入三者的耦合强度区别

    public class Computer : ITool

普通接口、多态、工厂模式、依赖注入三者的耦合强度区别
普通接口、多态、工厂模式、依赖注入三者的耦合强度区别
普通接口、多态、工厂模式、依赖注入三者的耦合强度区别
普通接口、多态、工厂模式、依赖注入三者的耦合强度区别

            Console.WriteLine("使用电脑");

普通接口、多态、工厂模式、依赖注入三者的耦合强度区别
普通接口、多态、工厂模式、依赖注入三者的耦合强度区别
普通接口、多态、工厂模式、依赖注入三者的耦合强度区别
普通接口、多态、工厂模式、依赖注入三者的耦合强度区别

    public class ModernPerson : Person

普通接口、多态、工厂模式、依赖注入三者的耦合强度区别
普通接口、多态、工厂模式、依赖注入三者的耦合强度区别
普通接口、多态、工厂模式、依赖注入三者的耦合强度区别

        /// 从外部获取工具

普通接口、多态、工厂模式、依赖注入三者的耦合强度区别
普通接口、多态、工厂模式、依赖注入三者的耦合强度区别

        public ITool Tool { get; set; }

普通接口、多态、工厂模式、依赖注入三者的耦合强度区别
普通接口、多态、工厂模式、依赖注入三者的耦合强度区别
普通接口、多态、工厂模式、依赖注入三者的耦合强度区别

        /// 现在人用不需要知道电脑是哪来的,直接拿来办公

普通接口、多态、工厂模式、依赖注入三者的耦合强度区别
普通接口、多态、工厂模式、依赖注入三者的耦合强度区别
普通接口、多态、工厂模式、依赖注入三者的耦合强度区别
普通接口、多态、工厂模式、依赖注入三者的耦合强度区别

            //不知道使用什么工具和哪来的工具,只是机械化的办公

普通接口、多态、工厂模式、依赖注入三者的耦合强度区别

            Tool.UseTool();

普通接口、多态、工厂模式、依赖注入三者的耦合强度区别

            Console.WriteLine("使用工具办公");

普通接口、多态、工厂模式、依赖注入三者的耦合强度区别
普通接口、多态、工厂模式、依赖注入三者的耦合强度区别
普通接口、多态、工厂模式、依赖注入三者的耦合强度区别

<?xml version="1.0" encoding="utf-8" ?>

<configuration>

  <configSections>

    <sectionGroup name="spring">

      <section name="context" type="Spring.Context.Support.ContextHandler, Spring.Core" />

      <section name="objects" type="Spring.Context.Support.DefaultSectionHandler, Spring.Core" />

    </sectionGroup>

  </configSections>

  <spring>

    <context>

      <resource uri="config://spring/objects" />

    </context>

    <objects xmlns="http://www.springframework.net">

      <description>一个简单的控制反转例子</description>

      <object id="computer" type="SpringNetIoC.Computer, SpringNetIoC" />

      <object id="modernPerson" type="SpringNetIoC.ModernPerson, SpringNetIoC">

        <property name="Tool" ref="computer"/>

      </object>

    </objects>

  </spring>

</configuration>

普通接口、多态、工厂模式、依赖注入三者的耦合强度区别
普通接口、多态、工厂模式、依赖注入三者的耦合强度区别

    class Program

普通接口、多态、工厂模式、依赖注入三者的耦合强度区别
普通接口、多态、工厂模式、依赖注入三者的耦合强度区别

        static void Main(string[] args)

普通接口、多态、工厂模式、依赖注入三者的耦合强度区别
普通接口、多态、工厂模式、依赖注入三者的耦合强度区别

            IApplicationContext ctx = ContextRegistry.GetContext();

普通接口、多态、工厂模式、依赖注入三者的耦合强度区别

            Person person = (Person)ctx.GetObject("modernPerson");

普通接口、多态、工厂模式、依赖注入三者的耦合强度区别

            person.Work();

普通接口、多态、工厂模式、依赖注入三者的耦合强度区别
普通接口、多态、工厂模式、依赖注入三者的耦合强度区别

            Console.ReadLine();

普通接口、多态、工厂模式、依赖注入三者的耦合强度区别
普通接口、多态、工厂模式、依赖注入三者的耦合强度区别
普通接口、多态、工厂模式、依赖注入三者的耦合强度区别

从上面代码我们可以看出,把对象交给Spring.NET容器进行管理,ModernPerson类不需要知道具体使用什么工具,仅仅是机械化的工作。至于使用的什么工具,则由配置文件决定,所有对象由Spring.NET容器管理,这样可以实现动态的拆装组建和组件重用。我个人理解依赖注入是反射工厂的加强版。