zoukankan      html  css  js  c++  java
  • .net你必须知道的事儿 1.5

    玩转接口

    什么是接口

    接口映射本质

    面向接口编程

    典型的.net接口

    接口,是面向对象设计中的重要元素,也是打开设计模式精要之门的钥匙,玩转接口,就意味着紧握这把钥匙,打开面向对象的抽象之门,成全设计原则,成就设计模式,实现集优雅和灵活于一生的代码艺术

    本节从接口由来讲起,通过概念阐述,面向接口编程的分析以及.net框架中的典型接口实例,勾画一个理解接口的框架蓝图,通过这一蓝图将会了解玩转接口的学习曲线。

    什么是接口

    所谓接口就是契约,用于规定一种规则大家遵守,所以.net中很多的接口都以able为命名后缀例如INULLABL等意指能够为空,能够克隆,能够枚举,能够对比,其实正是契约的一种遵守寓意,只有实现了ICloneable接口的类型,才允许其实例对象被拷贝,以社会契约而言,只有司机,才能够驾驶,人么必须遵守这种约定,无照驾驶将被视为犯罪而不被允许,这是社会契约的表现,由此来理解接口,才是对面向接口编程及其精髓的把握,列如

     面向接口编程就意味着,在自定义类中想要有驾驶这种特性,就必须遵守这种契约,因此必须让自定义类实现IDriveable接口,从而才使其具有了“合法”的驾驶能力,列如:

    没有实现接口的额类型则不被允许具有drive这一行为特性所以接口是一组行为规范,列如要是用foreach语句迭代前提是操作类型必须实现IEnumerable接口,这也是一种契约

    实现接口哈意味着,同样的方法对不同的对象表现为不同的行为,如果使司机具有驾驶拖拉机额的能力,也必须实现IDRIVASNPE,并提供不同的方式

     在面向对象世界里,接口是实现抽象机制的重要手段,通过接口实现可以部分的弥补继承和多态在纵向关系上的不足,具体的讨论可以参见1.4节“多态的艺术”,接口在抽象机制上,表现为基于接口的多态性列如:

     通过接口实现,同一个对象可以不同的身份,这种设计的思想与实现,广泛存在于.net框架类库中,正是这种基于接口的设计成就了面向对象思想中很多了不起的设计模式。

    1.接口多继承

    在,net中clr支持单实现继承和多接口继承,就意味着同一个对象可以代表多个不同的身份,一DateTime为例,其定义为

     因此可以通过DateTime实例代表多个省份,不同的省份具有不同的行为,列如

     接口的本质

    从概念上理解了几口,还应进一步从本质揭示其映射机制,在.net中基于接口的多态究竟是如何被实现的呢,这是值得思考的话题,根据下面的示列,及其il分析,我们对此进行一定的探讨;

     该定义在Reflector中的Il为

     根据Il分析可知Im接口本质仍然被标记为.class。同时提供了Abstract virtual方法MyMenthod,因此接口其实本质上可以看做是一个定义了抽象方法的类,该类仅提供了方法的定义,而没有方法的实现,其功能有借口的实现类来完成例如:

     其对应的IL代码为:

     由此可见是想了接口的类方法在IL标记为oVERRIDE,表示覆写了接口方法实现,因此接口的抽象机制任然是多态来完成的,接口在本质上,人就是一个不能实例化的类,但是有区别与一般意义上的类,列如不能实例化,语序多继承,可以作用于值类型等。

    namezaiclr内部,接口的方法分派是如何被完成的呢?在托管堆中clr维护者一个接虚标来完成方法分派,该表基于方法表内的接口图信息创建,主要保存了接口实现的索引记录,已IMyInterface为例,zaimyclass第一次加载时clr检查到Myclass实现可ImyIntrface的MymENTHOD方法,则会在接口虚表中创建一条记录信息,用于保存MyCLASSf方法表中实现了MyMethod方法的应用地址,其他实现了IMyInterface的类型都会在接口虚表中创建相应的记录,因此,接口的1方法调用时基于虚表进行的

    由string所想到的框架类库的典型接口

    在。net框架类库中,存在大量的接口,以典型的System。string类型为例,就克制接口在Fct设计中的重要性

     对几个典型的接进行简要的分析,以便zaiFct的探索中不会感觉陌生,同时也有助于熟悉框架类库

     

     关于框架类库的接口讨论,在本书的各个部分均有所涉及,列如关于集合的若干接口IList,Icollection等在8.9节“集合通论”中有详细的讨论,在本书的学习过程汇总将会逐渐有所收获,在此仅做简单介绍。

    面向接口的编程

    设计模式的祖师Gof,有句名言四大行施工队哈撒给的哈股东会,表示对接口编程而不要对实现编程,更通俗的说法是对抽象编程而不是对具体编程,关于面向对象和设计原则,将始终强调对抽象编程的重要性,这源于抽象代表了系统中相对稳定并又能通过多爱特性对其扩张,这姮好的符合了高内聚,低耦合的设计思想。

    下面就以著名的Petshop4.0中一个简单的面向独享设计片段为例来诠释面向借口变成的奥秘

    在Petshop4.0的数据访问层设计上,微软设计师将较为基础的增删改查操作封装为借口,有具体的实体操作类来实现抽象出的单独接口模块,使得对于数据的操作和业务逻辑对象相分离,借鉴这种设计思路实现一个简单的用户操作数据访问层,其设计如图1-14所示。

    从上述设计可见,通过接口将增删改查封装起来,在有具体的MySqlUser来实现Hepler类则提供了操作数据的通用方法,基于接口的数据访问层和具体的数据操作实现彻底隔离,对数据的操作规则的变更不会影响实体类对象的行为,体现了职责分离的设计原则,而这种机制是通过接口来完成的

    同时能够以IUSER接口来统一处理用户操作,列如再具体的实例创建时,可以借助反射机制,通过依赖注入来设计实现:

     

     你看,通过抽象可以将未知的对象表现出来,通过读取配置文件的相关信息可以很容易创建具体的对象,当有新的类型增加时不需要对原来的系统做任何修改只要在配置文件中增加相应的类型全路径即可,这种方式体现了面向接口编程的另一个好处对修改封闭对扩展开放

    正是基于这种设计才行成了数据访问层,业务逻辑层,将只有实体对象的相互操作,而不必关心具体的数据库操作实现,甚至看不到Sql语句执行的痕迹,例如

     另外按照接口隔离原则,接口应该被实现为具有单一功能的多个小接口,而不是具有多个功能的大接口,通过多个接口的不同组合没客户端按需实现不同的接口,从而避免出现接口污染的问题。

    关于捷库的规则,可以有以下的归纳;

    接口隔离原则强调接口应该被实现为具有单一功能的小借口,而不是时限为酷游多个功能的胖借口类对于累的依赖应该建立在最小的接口之上,

    接口支持多继承,既可以作用于值类型,也可以作用与引用类型

    禁止为已经发布的接口,添加新的成员,这意味着你必须重新修改所有实现了改接口的类型,在实际的应用这往往是不可能完成的事情。

    接口不能被实例化,没有个构造函数,接口成员被隐式声明为public。

    通常而言,练好的设计必然是面向抽象的接口试试先这一思想的完美手段之一,通过面向接口编程,保证了系统的职责清洗分离实体与实体之间保持相对合适的耦合度,尤其是高层模块不再依赖于底层模块,而依赖与比较稳定的抽象,是的底层的更改不会波及高层实现了良好的设计架构。

    透彻的了解接口,认识对接口编程体会面向对象的设计原则,是培养一个良好设计习惯的开端,关于接口是否玩的过瘾,就看如何体会本节强调的在概念上的契约在设计上的抽象。

  • 相关阅读:
    .net core2.0 中使用aspectcore实现aop
    [Superset] 设置Superset的登录设置
    [Python]Pandas对于非唯一的label index的数据选择问题
    Data Science Radar测试结果
    [R]R包版本更迭【持续更新】
    [面试] 删除多余的数组内容
    [Python]Python中的包(Package)
    [Linux] 使用Yum在CentOS上安装MySQL
    [pyMongo]insert_many的Bulkwrite实现机制
    [Git]2018-10 解决git cmd中文乱码问题
  • 原文地址:https://www.cnblogs.com/555556J/p/13522454.html
Copyright © 2011-2022 走看看