• 通过接口调用接口实现类实现松耦合(接口的多态)


    项目开发在各个层中通过接口实现松耦合的时候,如何实现接口调用接口实现类?

    这里的要求是接口有多个实现类,通过接口调用不的接口实现类!

          开始,我想到了IOC(IOC最近忒火),确实有很多开发好的类库unity,ninject等等,但是这些类库都有点太强大了,例

    如unity 是可以很容易实现我的要求,那么通过RegisterType<I, N>>(String name)注册;通过Resolve<I>(name) 就可以

    用接口调用相应的接口实现类,如果想了解一下unity,

    http://www.cnblogs.com/scy251147/archive/2012/11/21/2781328.html的文章不错!

         但是我想要的也就这点功能,所以就没有必要引入第三方库,自己实现一下IOC【其实,我对IOC理解比较肤浅,我的理解就是同

    一接口调用接口的不同实现类(多态),所以下面不敢用IOC命名】,我这里定义为ServiceFactory类,另一个帮助类ServiceKey;

    接口IOrderService和实现IOrderService接口的OrderService类OrderService2类。

     1     /// <summary>
     2     /// 根据服务接口创建服务类工厂
     3     /// </summary>
     4     public class ServiceFactory
     5     {
     6         
     7         /// <summary>
     8         /// 容器(唯一键,服务标志)
     9         /// </summary>
    10         private static Dictionary<String, RuntimeTypeHandle> container;
    11       
    12         /// <summary>
    13         /// 静态构造函数(注册接口)
    14         /// </summary>
    15         static ServiceFactory()
    16         {
    17             container = new Dictionary<String, RuntimeTypeHandle>();
    18 
    19             RegisterType<IOrderService, OrderService>();
    20             RegisterType<IOrderService, OrderService2>(ServiceKey.Second);/*同一接口,多个实现类*/
    21         }
    22 
    23         /// <summary>
    24         /// 注册对应服务接口和服务类型
    25         /// </summary>
    26         /// <typeparam name="I">服务接口</typeparam>
    27         /// <typeparam name="T">服务类型</typeparam>
    28         /// <param name="Key">服务的key</param>
    29         private static void RegisterType<I, T>(ServiceKey Key = ServiceKey.First)
    30             where I : class
    31             where T : class
    32         {
    33             String name = typeof(I).FullName;
    34             name += ((Int32)Key).ToString();
    35             container.Add(name, typeof(T).TypeHandle);
    36         }
    37 
    38         /// <summary>
    39         /// 根据服务接口创建服务类型
    40         /// </summary>
    41         /// <typeparam name="I">服务接口类型</typeparam>
    42         /// <param name="Key">服务的key(默认ServiceKey.First,用于同一接口,多个实现类)</param>
    43         /// <returns>服务类型实例</returns>
    44         public static I Create<I>(ServiceKey Key = ServiceKey.First) where I : class
    45         {
    46             Type newType = Type.GetTypeFromHandle(container[typeof(I).FullName + ((Int32)Key).ToString()]);
    47             return System.Activator.CreateInstance(newType) as I;
    48         }  
    49     }
    View Code
     1     /// <summary>
     2     /// 服务的key(用于根据服务接口创建服务类,特别同一接口,多个实现类)
     3     /// </summary>
     4     public enum ServiceKey
     5     {
     6         First = 1,
     7         Second = 2,
     8         Third = 3,
     9         Fourth = 4,
    10         Fifth = 5,
    11         Sixth = 6,
    12         Seventh = 7,
    13         Eighth = 8,
    14         Ninth = 9
    15     }
    View Code
     1     public interface IOrderService
     2     {
     3         String Test();
     4     }
     5 
     6     class OrderService : IOrderService
     7     {
     8 
     9         private String info = "OrderService";
    10         public OrderService()
    11         {
    12             info += DateTime.Now.ToString();
    13         }
    14         public String Test()
    15         {
    16             return info;
    17         }
    18     }
    19 
    20     class OrderService2 : IOrderService
    21     {
    22         private String info = "OrderService2";
    23         public OrderService2()
    24         {
    25             info += DateTime.Now.ToString();
    26         }
    27         public String Test()
    28         {
    29             return info;
    30         }
    31     }
    View Code

    1、RegisterType方法:添加接口和对应的实现类的标志(RuntimeTypeHandle 是类型唯一的抽象标志)到字典容器container中

    2、Create方法:根据接口创建接口类型的实例,【这里接口就关联上了接口实现类】,保证在调用前都有注册接口,所以所有的注册

    接口都放在静态构造函数中

    3、参数ServiceKey为接口实现类的唯一键,通过接口的FullName+ServiceKey就可以唯一标示,接口有多个实现类的时候是关键

    4、单元测试

     1         [TestMethod]
     2         public void TestServiceFactory()
     3         {
     4             var t11 = ServiceFactory.Create<IOrderService>().Test();
     5             var t12 = ServiceFactory.Create<IOrderService>().Test();
     6             var t13 = ServiceFactory.Create<IOrderService>().Test();
     7             var t21 = ServiceFactory.Create<IOrderService>(ServiceKey.Second).Test();
     8             var t22 = ServiceFactory.Create<IOrderService>(ServiceKey.Second).Test();
     9         }
    10    
    View Code

    这里,我们手动来维护接口和实现类的关联,大大增加了灵活性和项目的自主控制力,同时也实现了接口多态和解耦!




  • 相关阅读:
    数据挖掘实践(34):实战--高潜用户购买画像(三)特征工程
    数据挖掘实践(33):实战--高潜用户购买画像(二)EDA/探索性数据分析
    数据挖掘实践(32):实战--高潜用户购买画像(一)数据清洗
    Java 流程控制 之 顺序结构
    Java 之 运算符
    Java 之 变量
    Handmade Rust Part 1: Introduction & Allocators
    rust 强制转换
    引用与借用
    candidate #1: `std::clone::Clone`
  • 原文地址:https://www.cnblogs.com/liujinwu-11/p/4245675.html
Copyright © 2020-2023  润新知