- 浏览: 148796 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
august_000:
很有道理,我已经亲自测试过了:
public class ...
单例模式之线程安全解析 -
Chris_bing:
一个单例有这么多名堂,最后那个内部类的解决方案很有创意啊,受教 ...
单例模式之线程安全解析
讲解几个设计模式中的面向接口思想和基于.NET平台的分层架构中的面向接口思想,加深理解。
通过前面两篇,我想各位朋友对“面向接口编程”的思想有了一定认识,并通过第二篇的例子,获得了一定的直观印象。但是,第二篇中的例子旨在展示面向接口编程的实现方法,比较简单,不能体现出面向接口编程的优势和这种思想的内涵。那么,这一篇作为本系列的终结篇,将通过分析几个比较有深度的模式或架构,解析隐藏其背后的面向接口思想。这篇我将要分析的分别是MVC模式和.NET平台的分层架构。
这篇的内容可能会比较抽象,望谅解。
1.从MVC开始
MVC简介:
本文不打算详细解释MVC架构,而是把重点放在其中的面向接口思想上。所以在这里,只对MVC做一个简略的介绍。
MVC是一种用于表示层设计的复合设计模式。M、V、C分别表示模型(Model)、View(视图)、Controller(控制器)。它们的职责如下:
模型:用于存储应用中的数据及运行逻辑,是应用的实体。
视图:负责可视部分,用于与用户交互及呈现数据。视图只负责显示,不负责将用户的操作行为解释给模型。
控制器:负责将用户的行为解释给模型。根据指定的策略和用户的操作,调用模型的逻辑。
关于三者的关系,我画了一张图,大家请看:
它们之间的交互有以下几种:
1.当用户在视图上做任何需要调用模型的操作时,它的请求将被控制器截获。
2.控制器按照自身指定的策略,将用户行为翻译成模型操作,调用模型相应逻辑实现。
3.控制器可能会在接到视图操作时,指定视图做某些改变。
4.当模型的状态发生改变时,将通过某种方式通知视图。
5.视图可以从模型获取状态,从而改变自己的显示。
MVC介绍完了,那么可能会有人问,我们的主题呢?面向接口思想呢?其实,MVC中处处都存在面向接口的影子。下面,我对其中几个侧面进行解释。
1.首先我们可以看到,视图和模型是有直接交互的,也就是上面的4、5两点。但是有一点可能会让你吃惊:它们两个谁也不“认识”谁,即它们相互并不知道对方是做什么的、有什么属性、有什么方法,但是它们能交互。这是怎么做到的呢?因为它们个各知道对方实现了某一个接口。
此乃面向接口思想一大作用:使相互不认识的类进行交互。这样做是很有好处的,首先它们之间的耦合度大大降低,其次双方都可以进行替换,只要实现了相同的接口,就没有问题。
打个不太恰当的比喻。我们都知道120这个电话号码,是急救电话。其实120就是个接口,因为当你拨打这个电话时,你不知道那边是哪所医院,甚至不知道那边是不是医院,你只知道电话那头的地方可以救人,也可以说实现了IHelp接口。这样,你通过一个号码可以说同全部的救人机构联系起来了,当有紧急事件,接线控制那边会将你的请求接到最近可用的机构,你就可以最快的得到帮助。
现在我们假设没有使用面向接口思想,来看看会发生什么恐怖的事情:首先,我家的120号码是绑定在本市第一人民医院的,即当我拨打120时,只能拨通第一人民医院。如果有一天我食物中毒了,急忙拨通了120,但是电话那边告诉我他们医院的救护车都派出去了,我问那怎么接通别家医院的电话,那边的MM很温柔的告诉我,让我打电话给网通公司,然后重新为我布线。于是我吐血而亡……
言归正传。这里,我要引入一个设计模式,叫观察着(Observer)模式。这个模式大约是这样的:整个模式中有两种实体:观察者和被观察者,它们分别实现一个接口,这里我们姑且叫做IObserver与IObserverSubject。IObserver只有一个方法,例如叫Update,当被观察者状态改变时,调用这个方法,用来通知观察者。IObserverSubject接口有两个方法,都是供观察者调用。一个用来将观察者注册为此被观察者的观察对象,另一个用于将观察者移除。
一般情况下,一个被观察者对应多个观察者。
在MVC中,视图是观察者,模型是被观察者,当模型状态改变时,调用所有观察者的Update方法,通知视图模型有变,视图在Update方法里写下响应代码,完成操作。通过这个方法,视图和模型就可以在仅依赖接口的情形下进行交互,而不必强耦合,而且在模型不变的情况下,视图可以随意替换。(只要实现了IObserver)
2. 在MVC中另一个使用接口的地方就是控制器,这里我要首先引入一个设计模式:策略模式(Strategy)。在MVC中,控制器就使用了这个模式。
刚才我说过,视图负责与用户交互,但是,它只负责界面显示部分,至于当用户做了某个操作(如单击某个按钮)后系统应该怎么反应,视图并不负责,它只是将这个动作交给控制器,控制器根据内置的策略,将用户操作翻译成模型的逻辑。这就是说,同一个视图、同一种操作,模型可以做出不同的反应,这取决与控制器的内置策略。所以,我们的系统中可以有很多控制器,它们有不同的策略,当视图希望改变策略时,它可以更换控制器。怎么实现呢?这就需要视图不能和具体控制器耦合,而是要仅依赖一个控制器接口(如IController),并聚合一个IController的实例。当希望更改策略时,可以在系统运行时动态更换Controller,这就是策略模式的实现。
关于MVC的接口思想就先介绍到这里。其实MVC中还有很多地方用到面向接口,由于本文不是专门介绍MVC或设计模式的,所以对用到的模式没有做详解,而是把重点放在其中的面向接口思想上。如果没有设计模式的基础,读上文可能会有些困难,希望各位见谅!我打算在以后专门写文章来解析MVC。
2..NET平台下分层架构的面向接口思想
我们知道,在做大一点的系统应用时(特别是B/S架构),比较好的方法是分层架构。所谓分层架构,是指将系统从职责上分成若干层,每层各司其职,上层依赖下层完成操作。
在.NET平台上,比较经典的分层架构是三层架构,从下到上依次是:数据访问层、业务逻辑层、表示层。各层职责如下:
数据访问层:负责与数据源交互,完成数据访问等一系列操作。
业务逻辑层:完成与系统业务有关的逻辑操作。
表示层:负责与用户交互、呈现数据等一切与系统表示有关的操作。
刚才我们说过,分层架构下是向下依赖的(不考虑依赖倒置),也就是业务逻辑层要调用数据访问层完成与数据源有关的操作,而表示层调用业务逻辑层完成业务逻辑工作。但是,表示层对数据访问层是没有依赖的。
在这个架构中,每一层都不是一个类,而是一个类族,例如,在一个CMS系统中,数据访问层可能会有一系列的类,分别负责用户、文章、评论等业务实体的数据访问操作,而业务逻辑层也一样。如果我们直接依赖,即业务逻辑层实例化数据访问层的类,表示层再实例化业务逻辑层的类,会造成强耦合。如果我想把数据库从SQLServer换成MySQL,则要改变整个业务逻辑层代码,这是个不好的设计。(还记得“开放-关闭”原则吗)所以,一般的做法是,为数据访问层和业务逻辑层分别定义一族接口,业务逻辑层不依赖具体的数据访问层,而是仅依赖数据访问层的接口族,表示层也一样,依赖业务逻辑层的接口族。如此一来,当要更换数据库时,我们就不必改写整个业务逻辑层,因为业务逻辑层里根本没有任何数据访问层中的具体类,而全是通过接口实现的。在.NET中,只要配合配置文件和反射机制,再运用Abstract Factory设计模式,就可以实现“依赖注入”,即在不改动代码的情况下根据配置选择相应的层次组件。这样,我们就可以为不通数据库分别实现数据访问层,也可以编写ORM的数据访问层,甚至是基于XML的,只要实现了数据访问层接口族,就可以和业务逻辑层无缝连接,从而极大提高了软件的灵活性和可维护性。当然要更改业务逻辑层也是一样。
如果说,前面的例子都是从微观视角讨论接口,那么,这个例子则从宏观视角展现了面向接口编程的内涵和优势。很抱歉在这里不能对这个架构深入讲解,有兴趣的朋友可以参考微软的官方示例.NET PetShop4。(但是请注意,这个示例中业务逻辑层没有定义接口族,而是强耦合于表示层中,这可能是因为考虑到在这个系统中业务逻辑没有更改的可能。另外由于是个示例,不是真正的B2C系统,所以业务逻辑层很简单。)
好了,本系列文章就到这里。希望各位朋友通过这三篇文章,能对“面向接口编程”有一定的了解。当然,我只是起到一个抛砖引玉的作用,其真正的内涵和精髓,还需要各位从实践中慢慢认识。还有,就是面向接口思想不是孤立的,它和设计模式等内容都是面向对象大系中的精华,而且是相互渗透、相互联系的。其实,很多设计模式就是面向接口思想的体现。我们应该把这些放在一起学习,从而真正提供自己的面向对象思考能力和实战能力。
通过前面两篇,我想各位朋友对“面向接口编程”的思想有了一定认识,并通过第二篇的例子,获得了一定的直观印象。但是,第二篇中的例子旨在展示面向接口编程的实现方法,比较简单,不能体现出面向接口编程的优势和这种思想的内涵。那么,这一篇作为本系列的终结篇,将通过分析几个比较有深度的模式或架构,解析隐藏其背后的面向接口思想。这篇我将要分析的分别是MVC模式和.NET平台的分层架构。
这篇的内容可能会比较抽象,望谅解。
1.从MVC开始
MVC简介:
本文不打算详细解释MVC架构,而是把重点放在其中的面向接口思想上。所以在这里,只对MVC做一个简略的介绍。
MVC是一种用于表示层设计的复合设计模式。M、V、C分别表示模型(Model)、View(视图)、Controller(控制器)。它们的职责如下:
模型:用于存储应用中的数据及运行逻辑,是应用的实体。
视图:负责可视部分,用于与用户交互及呈现数据。视图只负责显示,不负责将用户的操作行为解释给模型。
控制器:负责将用户的行为解释给模型。根据指定的策略和用户的操作,调用模型的逻辑。
关于三者的关系,我画了一张图,大家请看:
它们之间的交互有以下几种:
1.当用户在视图上做任何需要调用模型的操作时,它的请求将被控制器截获。
2.控制器按照自身指定的策略,将用户行为翻译成模型操作,调用模型相应逻辑实现。
3.控制器可能会在接到视图操作时,指定视图做某些改变。
4.当模型的状态发生改变时,将通过某种方式通知视图。
5.视图可以从模型获取状态,从而改变自己的显示。
MVC介绍完了,那么可能会有人问,我们的主题呢?面向接口思想呢?其实,MVC中处处都存在面向接口的影子。下面,我对其中几个侧面进行解释。
1.首先我们可以看到,视图和模型是有直接交互的,也就是上面的4、5两点。但是有一点可能会让你吃惊:它们两个谁也不“认识”谁,即它们相互并不知道对方是做什么的、有什么属性、有什么方法,但是它们能交互。这是怎么做到的呢?因为它们个各知道对方实现了某一个接口。
此乃面向接口思想一大作用:使相互不认识的类进行交互。这样做是很有好处的,首先它们之间的耦合度大大降低,其次双方都可以进行替换,只要实现了相同的接口,就没有问题。
打个不太恰当的比喻。我们都知道120这个电话号码,是急救电话。其实120就是个接口,因为当你拨打这个电话时,你不知道那边是哪所医院,甚至不知道那边是不是医院,你只知道电话那头的地方可以救人,也可以说实现了IHelp接口。这样,你通过一个号码可以说同全部的救人机构联系起来了,当有紧急事件,接线控制那边会将你的请求接到最近可用的机构,你就可以最快的得到帮助。
现在我们假设没有使用面向接口思想,来看看会发生什么恐怖的事情:首先,我家的120号码是绑定在本市第一人民医院的,即当我拨打120时,只能拨通第一人民医院。如果有一天我食物中毒了,急忙拨通了120,但是电话那边告诉我他们医院的救护车都派出去了,我问那怎么接通别家医院的电话,那边的MM很温柔的告诉我,让我打电话给网通公司,然后重新为我布线。于是我吐血而亡……
言归正传。这里,我要引入一个设计模式,叫观察着(Observer)模式。这个模式大约是这样的:整个模式中有两种实体:观察者和被观察者,它们分别实现一个接口,这里我们姑且叫做IObserver与IObserverSubject。IObserver只有一个方法,例如叫Update,当被观察者状态改变时,调用这个方法,用来通知观察者。IObserverSubject接口有两个方法,都是供观察者调用。一个用来将观察者注册为此被观察者的观察对象,另一个用于将观察者移除。
一般情况下,一个被观察者对应多个观察者。
在MVC中,视图是观察者,模型是被观察者,当模型状态改变时,调用所有观察者的Update方法,通知视图模型有变,视图在Update方法里写下响应代码,完成操作。通过这个方法,视图和模型就可以在仅依赖接口的情形下进行交互,而不必强耦合,而且在模型不变的情况下,视图可以随意替换。(只要实现了IObserver)
2. 在MVC中另一个使用接口的地方就是控制器,这里我要首先引入一个设计模式:策略模式(Strategy)。在MVC中,控制器就使用了这个模式。
刚才我说过,视图负责与用户交互,但是,它只负责界面显示部分,至于当用户做了某个操作(如单击某个按钮)后系统应该怎么反应,视图并不负责,它只是将这个动作交给控制器,控制器根据内置的策略,将用户操作翻译成模型的逻辑。这就是说,同一个视图、同一种操作,模型可以做出不同的反应,这取决与控制器的内置策略。所以,我们的系统中可以有很多控制器,它们有不同的策略,当视图希望改变策略时,它可以更换控制器。怎么实现呢?这就需要视图不能和具体控制器耦合,而是要仅依赖一个控制器接口(如IController),并聚合一个IController的实例。当希望更改策略时,可以在系统运行时动态更换Controller,这就是策略模式的实现。
关于MVC的接口思想就先介绍到这里。其实MVC中还有很多地方用到面向接口,由于本文不是专门介绍MVC或设计模式的,所以对用到的模式没有做详解,而是把重点放在其中的面向接口思想上。如果没有设计模式的基础,读上文可能会有些困难,希望各位见谅!我打算在以后专门写文章来解析MVC。
2..NET平台下分层架构的面向接口思想
我们知道,在做大一点的系统应用时(特别是B/S架构),比较好的方法是分层架构。所谓分层架构,是指将系统从职责上分成若干层,每层各司其职,上层依赖下层完成操作。
在.NET平台上,比较经典的分层架构是三层架构,从下到上依次是:数据访问层、业务逻辑层、表示层。各层职责如下:
数据访问层:负责与数据源交互,完成数据访问等一系列操作。
业务逻辑层:完成与系统业务有关的逻辑操作。
表示层:负责与用户交互、呈现数据等一切与系统表示有关的操作。
刚才我们说过,分层架构下是向下依赖的(不考虑依赖倒置),也就是业务逻辑层要调用数据访问层完成与数据源有关的操作,而表示层调用业务逻辑层完成业务逻辑工作。但是,表示层对数据访问层是没有依赖的。
在这个架构中,每一层都不是一个类,而是一个类族,例如,在一个CMS系统中,数据访问层可能会有一系列的类,分别负责用户、文章、评论等业务实体的数据访问操作,而业务逻辑层也一样。如果我们直接依赖,即业务逻辑层实例化数据访问层的类,表示层再实例化业务逻辑层的类,会造成强耦合。如果我想把数据库从SQLServer换成MySQL,则要改变整个业务逻辑层代码,这是个不好的设计。(还记得“开放-关闭”原则吗)所以,一般的做法是,为数据访问层和业务逻辑层分别定义一族接口,业务逻辑层不依赖具体的数据访问层,而是仅依赖数据访问层的接口族,表示层也一样,依赖业务逻辑层的接口族。如此一来,当要更换数据库时,我们就不必改写整个业务逻辑层,因为业务逻辑层里根本没有任何数据访问层中的具体类,而全是通过接口实现的。在.NET中,只要配合配置文件和反射机制,再运用Abstract Factory设计模式,就可以实现“依赖注入”,即在不改动代码的情况下根据配置选择相应的层次组件。这样,我们就可以为不通数据库分别实现数据访问层,也可以编写ORM的数据访问层,甚至是基于XML的,只要实现了数据访问层接口族,就可以和业务逻辑层无缝连接,从而极大提高了软件的灵活性和可维护性。当然要更改业务逻辑层也是一样。
如果说,前面的例子都是从微观视角讨论接口,那么,这个例子则从宏观视角展现了面向接口编程的内涵和优势。很抱歉在这里不能对这个架构深入讲解,有兴趣的朋友可以参考微软的官方示例.NET PetShop4。(但是请注意,这个示例中业务逻辑层没有定义接口族,而是强耦合于表示层中,这可能是因为考虑到在这个系统中业务逻辑没有更改的可能。另外由于是个示例,不是真正的B2C系统,所以业务逻辑层很简单。)
好了,本系列文章就到这里。希望各位朋友通过这三篇文章,能对“面向接口编程”有一定的了解。当然,我只是起到一个抛砖引玉的作用,其真正的内涵和精髓,还需要各位从实践中慢慢认识。还有,就是面向接口思想不是孤立的,它和设计模式等内容都是面向对象大系中的精华,而且是相互渗透、相互联系的。其实,很多设计模式就是面向接口思想的体现。我们应该把这些放在一起学习,从而真正提供自己的面向对象思考能力和实战能力。
发表评论
-
(转)重述——组合/聚合复用原则
2013-10-30 09:10 1064组合/聚合复用原则(Com ... -
(转)重述——迪米特法则
2013-10-29 10:51 1282迪米特法则(Law of Demeter) 又叫最 ... -
(转)重述——依赖倒置原则
2013-10-29 10:50 823依赖倒置原则(Dependence Inversion Pri ... -
(转)重述——里氏替换原则
2013-10-29 10:46 1459里氏替换原则(Liskov Substitution Prin ... -
(转)重述——开放封闭原则
2013-10-29 10:41 828开发封闭原则(Open-Closed Principle OC ... -
(转)重述——单一职责原则
2013-10-29 10:37 844单一职责原则(Single Respo ... -
(转)Java之美[从菜鸟到高手演变]系列之博文阅读导航
2013-10-28 17:00 1746Java之美[从菜鸟到高手演变]系列之博文阅读导航 http: ... -
(转)面向接口编程详解
2013-10-25 12:34 5老文章,自己学习。 面向接口编程详解(一) http://w ... -
(转)细说业务逻辑
2013-10-25 12:30 565前篇 http://www.cnblogs.com/leoo2 ... -
Java 多线程并发控制框架(转)
2012-12-14 11:28 1233Java 提供了语言级 ... -
(转)设计模式综述
2012-11-02 13:29 813设计模式主要分三个类 ... -
(转)面向接口编程详解(二)
2012-10-28 12:53 823来源:http://www.cnblogs.com ... -
(转)面向接口编程详解(一)
2012-10-28 12:50 801在这一篇中,将对接口及面向接口编程有个大致的介绍,着重在 ... -
面向对象的3个基本要素和5个基本设计原则(整理)
2012-10-24 23:20 13299面向对象的3个基本要素 ... -
进程与线程
2012-10-23 15:48 942简单来说, 进程是应用程序的一次执行,是具有一定独立功能的程序 ... -
单例模式之线程安全解析
2012-10-17 16:07 1965本文综合网上资料以及代码时间,对要求延迟加载和线程安全 ... -
反面模式(Anti-pattern)
2012-10-17 11:02 2945原文:http://en.wikipedia.or ... -
如何高效地阅读技术类书籍与博客
2012-10-04 16:39 956原文地址:http://www.nowam ... -
面经:面试官会关注你的哪些能力
2012-10-03 21:47 813原文地址:http://www.nowam ... -
阅读思维训练书籍
2012-10-03 21:44 1026原文地址:http://www.nowamagic.net/l ...
相关推荐
面向接口编程是一种重要的软件设计原则,它强调程序的组件应通过接口进行交互,而不是直接依赖于具体的实现。这种编程范式有助于提高代码的灵活性、可维护性和可测试性。下面我们将详细探讨面向接口编程的思想基础、...
面向接口编程详解(二)——编程实例 面向接口编程是一种编程思想,强调通过接口来实现多态性和可扩展性。在本文中,我们将通过一个实例来详细解释面向接口编程的思想和优点。 问题提出:我们要开发一个应用,模拟...
面向接口编程详解.chm面向接口编程详解.chm面向接口编程详解.chm
面向接口编程是一种编程范式,它基于面向对象编程的思想,但更强调通过接口来定义对象的行为,而不是具体实现。接口在这里扮演着规范和契约的角色,定义了一组方法签名,但不包含任何实现代码。这种编程方式允许代码...
面向接口编程是一种编程范式,它是面向对象编程(OOP)的一个重要组成部分,而非独立的编程思想。在面向接口编程中,我们关注的是定义清晰、明确的行为规范,而不是具体的实现细节。接口作为一种契约,规定了类必须...
在本文档的第三部分,作者探讨了如何在实际的模式中运用这一原则,通过分析MVC(Model-View-Controller)模式和.NET平台的分层架构来深入理解面向接口编程的优势。 MVC模式是一种经典的软件架构模式,用于分离应用...
面向接口编程是面向对象编程中的一个重要概念,它并非与面向对象编程平级,而是面向对象思想的精华之一。本文将详细解释面向接口编程的思想基础。 首先,我们需要理解接口的定义和本质。接口在编程中是一个包含一...
面向接口编程是软件工程中的一种重要设计理念,尤其在面向对象编程中扮演着核心角色。它不仅深化了面向对象思想的应用,而且为构建更加灵活、可扩展和可维护的软件系统提供了理论依据。本文旨在深入探讨面向接口编程...
### 面向接口编程详解 #### 一、面向接口编程与面向对象编程的关系 面向接口编程并非一种独立于面向对象编程之外的新编程思想,而是面向对象编程思想体系中的一个重要组成部分。面向对象编程的核心在于模拟现实...
"Java面向对象编程实例详解2.txt"和"Java面向对象编程实例详解.txt"可能包含了详细的讲解和示例代码,涵盖了类的创建、对象的实例化、访问控制、构造函数、抽象类和接口、异常处理、集合框架等方面的知识。...
Java编程详解是一个深入探讨Java语言及其应用的领域,特别是针对最新的Java版本。在这个最新的Java编程详解中,我们可能涵盖了许多现代Java开发的关键知识点,包括但不限于以下几个方面: 1. **Java语言基础**:从...
面向对象编程是Python的核心特性之一,它通过模拟现实世界的实体和关系来构建代码结构。本文主要探讨了Python中面向对象编程的基本概念、特点以及如何在实际应用中进行类和对象的创建。 首先,面向对象编程(OOP)...
《Java2编程详解》这本书是Java开发者的重要参考资料,它涵盖了Java语言的核心概念和技术,旨在帮助读者深入理解并熟练掌握Java2平台的编程技术。在这个压缩包中,包含了一个名为"Java2编程详解.pdf"的PDF文件,这很...
2. **面向对象编程**:Java是一种纯面向对象的语言,书中会详细介绍类、对象、封装、继承和多态等概念,以及如何设计和实现接口,这对于理解Java的编程模型至关重要。 3. **异常处理**:Java中的异常处理机制是一个...
库卡机器人编程详解 本文档为库卡机器人编程的详细指南,涵盖了库卡机器人系统软件(KSS)版本4.1的编程方法和技术。本文档面向专业的机器人开发人员和编程人员,旨在帮助他们更好地理解和应用库卡机器人编程技术。...
根据提供的信息,《java编程详解》是一本被广泛推荐并深受读者喜爱的专业书籍,它旨在为初学者和进阶学习者提供全面、深入的Java编程知识。以下是对该书可能涵盖的一些核心知识点的概述: ### Java语言基础 1. **...