今天看看几个基本模式,这包括Gateway模式,Mapper模式,LayerSupertype模式和Separated Interface模式。

在这本书的最后一章,Martin Fowler放了一大堆各种各样的模式,称之为“基本模式(Base Patterns)”,这些模式大多比较简单,专注于解决企业应用中的某个细节问题,可以说不大重要,但真的用到时候有确实那么有用。

因为模式简单,所以模式本身就不用花太多文字解释,我们的重点应该放在体会各种模式的异同。甚至有的模式,早已经成为了我们熟知的一种再平常不过的功能,而不需要再去认为其实一种“模式”了,从中,我着实体会到了模式的发展。

Gateway(入口)

每天的编程我们都会面对大量的API,在处处OO的今天直接面向API编程显然不是一个好的选择,于是我们就引入Gateway,其实很简单,就是把现有的API先封装一下,然后抽象出方便系统调用的接口,再使用。

反正,程序需要什么,我们就为Gateway类定义什么样的接口,至于如何实现,就完全不用管了。

如果你接触过GOF的面向对象设计模式,应该会发现这和另外三种模式很相像,它们分别是Façade, Adapter, Mediator,书中着重介绍了这几种的区别。我重点强调的是,这四种模式,都至少提供了对一个现有对象的再次封装,而区别微妙的体现在封装的目的上,而这种微妙的区别,大家得细细体会。

Gateway是在已经有了现成的服务类情况下,为了简化客户程序的编写,将服务类的提供的API接口进一步简化,一方面简化调用,另一方面方便测试;

这和Adapter非常相像,但是Adapter所做的工作仅仅是重新封装一个服务类使之能与另一个调用它的客户程序匹配,而Gateway并不包含客户类,因此从这个意义上来说,Gateway = 定义新的客户代码接口 + 进行Adapter

最后其实不管什么模式,都可以算作Façade,但是Façade着重在服务代码编写的时候考虑,重点在隐藏不公开的成员,暴露程序功能

而Mediator倒是比较清楚,Mediator模式中服务类和客户类都会调用新定义的中介类,这是和其他几个模式显然不同的地方。

要是你坚持看完了以上这些异同,估计你已经快晕过去了。其实说实话,在.NET+C#的平台这几种所谓的模式表现在代码上很可能是一模一样的,之所以要分成这么多种模式,完全是从模式的思想上来看的。

虽然学院派了一点,但我还是认为理解这几种模式对从更高层次上理解面向对象编程编程有很大的帮助。下面看看它们.NET框架里的应用。

System.IO.File类,负责磁盘文件的创建,删除等等工作,在Windows平台下,这些操作就是调用了Windows API的几个文件处理函数。总体上看来,.NET框架是利用Gateway模式封装了几个API函数,并作为File类中的成员公开出来。

使用Reflactor工具我们可以大概的看看.NET的File类是如何工作的,这里就以CreateFile方法为例,经过一次次的转到定义(提供的重载可真是多),最终我们看到这样一个复杂的方法(FileStream.Init),定义如下

internal unsafe void Init(string path, FileMode mode, FileAccess access, int rights, bool useRights, FileShare share, int bufferSize, FileOptions options, Win32Native.SECURITY_ATTRIBUTES secAttrs, string msgPath, bool bFromProxy)

这虽然已经是一个unsafe方法了,但依然是一个.NET下的类,再继续看下去,所有方法最终都会调用这样一个类:

internal static class Win32Native{
}
Win32Native这个类负责直接封装了所有的WindowsAPI,按照原来的样子提供了WindowsAPI的封装,其中用于创建文件的方法名叫Win32Native.SateCreateFile
真的有好多层封装,我们来看看一个简单的File.Create方法到底进行了多少调用(跳过方法重载):
                    File.Create ->  FileStream.Init -> Win32Native.SafeCreateFile -> WindowsAPI
也许你平时知道.NET很多功能都是直接调用WindowsAPI,但是你可能没有想到在WindowsAPI上还有这么多层封装吧。为什么要有这么多层封装呢?
 

从Gateway模式的角度来看,每一层封装,都是对上一层简化,每一层都是上一层的Gateway。

Win32Native类,提供了dll文件导入,API函数映射到.NET函数功能;

映射出来的函数非常多,那就公开一个文件处理方面的封装吧,于是有了FileStream类,我想这叫做Façade可能更好一些;

我们可以看到Init函数非常复杂,到这为止仅仅只是简单的导出WindowsAPI的函数,使用起来仍然相当不方便,于是我们便加上一个Gateway,这个Gateway封装了所有unsafe的代码,处理了很多该处理的异常,最后甚至提供了一个最简单的重载File.Create(string fileName);

到此为止,创建文件这个功能封装完毕了,和使用WindownsAPI创建文件比起来,使用一个简单的File.Create来创建文件真的很完美。

Mapper(映射器)

Gateway模式中对象调用是单向的,Gateway所起的作用仅仅是对低层函数或者类的封装,而Mapper希望完成的事情远不止这些。Mapper模式的重点在于关注映射两种不同机制的系统,他希望通过一个中间的Mapper,完全隔离两个系统,是两者完全不互相依赖。

听得最多的,也许就是最有争议的ORM(Object Relational Mapping)。

ORM的话题总是说不完的,简单面向对象系统和关系数据库系统是两种完全不同的系统,但是我们又必须使用关系数据库系统存储数据,因此我们需要一种程序来进行面向对象数据和关系数据库中存储的数据之间的转换。

Mapper的作用就是处理这种转换,这个概念很早就被提出来,但是很模糊,因为他并没有说清楚这个“转换”到底如何设计,好多年前Martin Fowler就提出了Mapper,甚至提出了Data Mapper的简单实现,但是直到今天,在.NET框架下还是没有看到一个真正完美的ORM框架。

我们要理解的,是映射器这种思想,设计一种类,直接在两种不同的机制间进行转换,让双方都满意。这很像Adapter,其实我也不能很清楚的说出Adapter和Mapper的区别,可能他们的差别在于粒度上吧,Adapter在于两种类之间的接口转换,而Mapper不只是接口间的转换,他更在意两种完全不同实现机制之间的相互转换,这种转换的技术含量要高得多。

在.NET平台下,严格意义上说.ORM框架应该只有刚刚推出的ADO.net Entity Framework,这套框架就着重在于对面向对象设计中的各种继承组合关系到关系数据库的映射工作,当然它毕竟是刚推出的工具,我也没有多少实际使用经验,到底如何也不好说。

其他的ORM工具从开源NHibernate到NBear等等可以说多如牛毛,而MS官方的除了之前的DLINQ之外,其实以前的强类型Dataset都可以算作简单的ORM,至少是具有ORM概念的东西。

总的说来,ORM概念已经热了好几年了,但是依然还是很不成熟。

和ORM一样,我认为直到今天Mapper模式也尚未走向成熟,也许,随意的希望隔离两个本来就相关的子系统这种行为本身就有些不切实际。

Layer Supertype

一句话就可以说的非常清楚:如果多个类有同样的成员,那么建立一个基类,让所有的类继承这个基类。

我没什么好说的了,老外真的很喜欢总结,连这都能算作一种模式。

如果这真的算一种模式的话,在.NET框架中,这样的运用就是数不胜数了,几乎绝大多数继承关系的都可以算作这种模式,比如WinForm中TextBox和Button同样继承于Control类。

Separated Interface

并非每一种面向对象编程语言都有接口(Interface)这个概念的,但在像C#或者Java这样在语言级别提供了接口功能的语言中,接口的使用已经是司空见惯了。

要说明的是,实现Separated Interface并非一定要使用接口这东西,用抽象类也是可以很好的实现接口的。

为什么要用接口,大声喊出一句话,把声明和实现分开!

这里涉及到一些基础的东西了,有了抽象类,为什么还要有接口呢?

一个原因是类的继承关系仅仅只是一个面向对象系统中纵向的关系,而同一层次的类之间的关系则无法使用继承关系描述,除非,使用C++的多继承。

实践证明,多继承带来的问题远大于好处,因此便有了更注重功能定义的接口,这个概念。接口更重在描述体现类本身的功能,接口并不关心这个类“是”什么,他只关心这个类“能做什么”。

从这个意义上来说,接口定义了类之间横向的功能关系。这是另一种结构上优化。

纵向继承关系

在继承的基础上加上横向实现关系

IWork2也许并没有定义在ClassRoot中,但是因为接口的存在,本来没有关系的ClassB和Class3被建立了关系,这就是横向的实现关系。

更加重要的是,我们可以把IWork1和IWork2的实现放在其他的程序集或者包中,在我们发布的版本中,只需要指定我们所依赖的接口就足够了。这大大降低了各个程序集之间的耦合度。

分离接口在.NET框架中的运用也是遍地都是,也许你已经根本不认为只是一种模式了,而只是非常平常的使用它了。这便是模式的最高境界,也可见这种分离接口模式的成熟。

举个最典型例子,在定义WCF服务的过程中有一个步骤是定义WCF的ServiceContract, ServiceContract实际上就是一系列接口。在创建一个WCF服务时,通常会将所有的服务代码抽象成这样的接口,客户端只需获得这个接口,就能够进行远程调用服务器以使用。关于WCF的详细信息,可以参考MSDN,或相关资料。

转载于:https://www.cnblogs.com/yayx/archive/2008/09/02/1285336.html

重温经典之《企业应用架构模式》——.NET中的架构模式运用 (Base Patterns 1)相关推荐

  1. Java实现二十三种设计模式(五)—— 十一种行为型模式 (中)——解释器模式、迭代器模式、中介者模式、备忘录模式

    Java实现二十三种设计模式(五)-- 十一种行为型模式 (中)--解释器模式.迭代器模式.中介者模式.备忘录模式 一.解释器模式 我国 IT 界历来有一个汉语编程梦,虽然各方对于汉语编程争论不休,甚 ...

  2. 命令模式 java_JAVA中的命令模式实例教程

    原文链接  作者:Pankaj Kumar 译者:f0tlo <1357654289@qq.com> 命令模式是一种行为模式,因此,它处理的是对象的行为.命令模式为系统中不同的对象提供中性 ...

  3. java模板方法模式_Java中的模板方法模式

    java模板方法模式 模板方法模式是一种行为模式,建议在超类中更一般地定义算法. 该算法是在称为模板方法的方法中定义的. 子类仅定义更具体的算法步骤的实现. 使用这种设计模式的好处是,算法后面的任何更 ...

  4. swift 听筒模式_Swift中的“复合”模式

    swift 听筒模式 定义 (Definition) 'Composite' pattern is a structural design pattern that is useful for com ...

  5. linux win95模拟,【重温经典】Windows 95 模拟软件--记忆中的扫雷和纸牌

    软件平台:Windows/Mac os/Linux 今天给大家分享一个东西,虽然没啥卵用... 简单介绍 聊天软件 Slack 的开发者 Felix Rieseberg 把 Windows 95 变成 ...

  6. java中的原型模式_java中的原型模式理解

    //测试类 public class TestPrototype { /** * @param args */ public static void main(String[] args) { She ...

  7. 计算机的上帝模式,电脑中的上帝模式,你用过吗?

    [摘要] 上帝模式,即"God Mode",是电脑中隐藏的一个简单的文件夹窗口,包含了系统所有的设置,控制面板.界面个性化.辅助功能选项等方方面面的控制设置,用户只需通过这一个窗口 ...

  8. java责任链模式_java中责任链模式详解和使用方法

    顾名思义,责任链模式(Chain of Responsibility Pattern)为请求创建了一个接收者对象的链.这种模式给予请求的类型,对请求的发送者和接收者进行解耦.这种类型的设计模式属于行为 ...

  9. dispose 模式 java_C#中标准Dispose模式的实现

    需要明确一下C#程序(或者说.NET)中的资源.简单的说来,C#中的每一个类型都代表一种资源,而资源又分为两类: 托管资源:由CLR管理分配和释放的资源,即由CLR里new出来的对象: 非托管资源:不 ...

  10. java 中策略模式_JAVA中的策略模式

    现在我们有一个虚基类-鸭子(abstract Duck). 有真鸭子,野鸭子,橡皮鸭子继承了该类.虚基类有swing方法,毕竟游泳是所有的鸭子都应有的功能.还有一个虚方法display,这个方法在子类 ...

最新文章

  1. Java基础教程(15)--枚举类型
  2. C++中map容器的说明和使用技巧
  3. 想通关「限流」?只要这一篇
  4. C和指针之字符串编程练习3
  5. 【Pytorch神经网络理论篇】 26 基于空间域的图卷积GCNs(ConvGNNs):定点域+谱域+图卷积的操作步骤
  6. 34.Silverlight中不得不了解使用的依赖属性
  7. C4D立体素材|旅游度假主题海报,设计点睛之笔
  8. android 环形进地图条,easyEcharts折线,柱状,饼图,仪表盘,环形,水球,圆柱,地图纯JS绘制...
  9. STM32串行驱动LCD12864显示屏程序代码
  10. 一文了解CDN加速服务
  11. python3 socket TCP 服务器 一对多转发信息
  12. 首页推荐流支持快捷修改兴趣标签,问答支持展示gif【2021.11.8】
  13. 迪斯尼乐拍通照片抓取
  14. 谷歌团队在平安金融中心_Google银行业务可以教给我们关于金融和科技的未来
  15. ECharts饼图实例
  16. 购物表单mysql还是mongodb_日志数据是选择mysql 还是 mongodb 还是 postgredb
  17. 百度知道与搜搜问问推广的优劣势
  18. 【论文阅读】——Spons Shields: Practical Isolation for Trusted Execution
  19. 股票融资全面解决方案
  20. 微商php源码,Thinkphp内核微商新零售平台源码

热门文章

  1. [转载]ArcMap中如何自制符号库(二)
  2. java 数据结构容器之HashSet
  3. (function() {})();和(function(){}())
  4. 经济危机过后,中国会变成什么样
  5. SQL进阶随笔--case用法(一)
  6. NSDictionary
  7. HTML5手机端弹窗、提示框、loading加载(多功能xwPop弹窗升级版)
  8. 分布式架构 springcloud+redis+springmvc+ springboot
  9. [LeetCode]ZigZag Conversion
  10. 老王亲述:我的运维心路历程