MVC模式与用户输入数据检查所谓的MVC模式,即模型-视图-控制器(Model-View-Controller)模式。MVC模式的结构图如下图所示: MVC模式的特殊性 MVC模式常常作为一个设计模式出现在各种讨论中,但是MVC模式实际上是架构模式,而不是设计模式。 John Vlissides在他们的著作“GOF95”里提到: “避免了可以分割较小模式的大的模式。比如,我们没有把Smalltalk的模型-视图-控制器(Model-View-Controller, MVC)当做一个模式提出,因为它很大程度上是我们已经有的较小的模式组成的。我承认,MVC模式比单纯的合成模式加策略模式加观察者模式要多一些东西,但是我们不想在有更基本的模式需要讨论的时候,把时间花在讨论MVC模式上。” 换言之,MVC是一个比本书前面所讨论的设计模式更大的尺度上的模式,而不是本书所关注的尺度上的设计模式。可以分解为几种设计模式:如果硬要把MVC模式与前面所讨论的设计模式对上号话,那么它在大部分情况下是下面几个模式之一。合成模式:合成模式的简略类图如下图所示: 策略模式:策略模式的简略图如下图所示: 观察者模式:观察者模式的简略图如下图所示: 也有可能是三者的混合。它也会涉及到以上三个模式相关的其他模式,比如: ◆ 合成模式:装饰模式、享元模式、迭代子模式、访问者模式 ◆ 策略模式:享元模式 ◆ 观察者模式:调停者模式、单例模式模式的种类:由于【GOF】是论述软件模式的著作的第一本,也是OO设计理论著作中最流行的一本,因此有些人常常使用设计模式(Design Pattern)一词来指所有直接处理软件的架构、设计、程序实现的任何种类的模式。另外一些人则强调要划分三种不同层次的模式:架构(Architectural Pattern)、设计模式(Design Pattern)、成例(Idiom).成例有时也称为代码模式(Coding Pattern). 架构模式(Architectural Pattern) 一个架构模式描述软件系统里的基本的结构组织或纲要。架构模式提供一些事先定义好的子系统,指定它们的责任,并给出把它们组织在一起的法则和指南,有些人把这种架构模式叫系统模式,一个架构模式常常可以分解成很多个设计模式的联合使用。显然,MVC模式就属于这一种模式。设计模式(Design Pattern) 一个设计模式提供一种提炼子系统或软件系统中的组件或者它们之间的关系的纲要设计。设计模式描述普遍存在的相互通信的组件中重复出现的结构,这种结构解决在一定的背景中的具有一般性的设计问题。代码模式或成例(Coding Pattern 或Idiom) 代码模式(或成例)是较低层次的模式,并与编程语言密切相关。代码模式描述怎样利用一个特定的编程语言的特点来实现一个组件的某些特定的方面或关系。这三者之间的区别在于三种不同的模式存在于它们各自的抽象层次和具体层次上。架构模式是一个系统的高层次策略。涉及到大尺度的组件以及整体性质和力学。架构模式的好坏可以影响到总体布局和框架性结构。设计模式是中等尺度的结构策略。这些中等尺度的结构实现了一些大尺度组件的行为和它们之间的关系。模式的好坏不会影响到系统的总体布局和总体框架。设计模式定义出子系统或组件的微观结构。代码模式(或成例)是特定的范例和与特定语言有关的编程技巧。代码模式的好坏会影响到一个中等尺度组件的内部、外部的结构或行为的底层细节,但不会影响到一个部件或子系统的中等尺度的结构,更不会影响到系统的总体布局和大尺度框架。 MVC作为模式,提供了一个原则,可以按照模型、表达式和行为等角色把一个应用系统的各个部分之间的耦合解脱、分割开来。 MVC模式的示意图如下图所示:模型端:在MVC模型里,模型便是执行某些任务的代码,而这部分代码并没有任何逻辑决定它对用户端的表示方法。模型端只有纯粹的功能性接口,也就是一些列的公开方法。通过这些公开方法,便可以取得模型端的所有功能。在这些公开方法中,有些事取值的方法,让系统其他部分可以得到模型端的内部状态参数,其他的改值方法则允许外部修改模型端的内部状态。但是,一般来说,模型端必须由方法登记视图,以便在模型端的内部状态发生变化时,可以通知视图端。在Java语言里,一个模型端可以继承java.util.Observable类。此父类可以提供登记和通知视图所需的接口。多个视图端:在MVC模式里面,一个模型端可以有几个视图端,而实际上复数的视图端是使用MVC的原始动机。使用MVC模式可以允许多于一个的视图端存在,并且可以在需要的时候动态地登记上所需要的视图。举一个大家熟悉的例子,是Excel表格。一个饼图,一个棒图和一个表格均是同组数据的不同的视图端,当用户通过任何一个视图修改数据时,所有的视图都会按照新数据跟新自己。在Java语言的java.awt库和java.swing库里,所有的视窗构件均可用来建造视图端,但是一个视图如果能够自动得到更新,便需要实现java.util.Observer接口,这样百年使得MVC模式符合观察者模式的定义。在视图端丽,视图可以嵌套,这意味着在视图端里会有合成模式。比如,在一个Frame构件里面,会有文字框构件和按键构件。多个控制器端: MVC模式的视图端是MVC模式的控制器端结合使用的,当用户端与相应的视图发生交互时,用户可以通过视窗更新模型的状态,而这种更新时通过控制器端进行的。控制器端通过调用模型端的改值方法更改其状态值。与此同时,控制器端会通知所有的登记了的视图刷新显示给用户的表示。这意味着在视图端对象与控制器对象之间会有观察者模式的应用。 MVC模式在J2EE技术中的应用一般而言,一个J2EE系统应当适当地划分接收请求,根据请求采取行动,并将结果显示给用户等责任。流行的划分方式有两种,分别是JSP模型一和JSP模型二。 JSP模型一的架构模型一又称做以JSP为中心(JSP Centric)的设计模式。其中JSP负责与客户端通信,处理所有的请求的答复,数据库的存取直接由JSP完成,有时由一些JavaBean辅助完成。JavaBean的用途是在不同的JSP之间通信。在这个模型中显示数据的逻辑和数据在这个模型中有了一定程度的区分,但是商务逻辑是和显示数据的逻辑混合在JSP里面,使得两者无法独立的演化。这就是模型一的缺点。 JSP模型二的架构模型二又叫做以Servlet为中心(Servlet Centric)的设计模式。通常认为模型二是一个比模型一好很多的架构。因为它将显示数据的逻辑与商务逻辑分割开来。从而使得系统层次更加清楚。由于商务逻辑和显示数据的逻辑是分开的,因此两者可以独立演化。在这个模型里,系统的活动时序如下所示: Servelt相当于控制器(Conroller)角色,它负责接收客户端请求并处理此请求。根据请求的类型,Servlet可以选择创建一个JavaBean对象,并从请求的处理过程中取得的结果作为初始化参数传递给JavaBean对象。 Servlet也可以直接存取数据库中的数据。 Servlet将请求传递给合适的JSP,而JSP则显示给用户。 JSP仅仅从JavaBean中读取数据,JavaBean直接与数据库打交道。JSP不与数据库打交道。 JSP返回给客户端。在模型二里面,Servlet不参与显示数据的工作,从而没有显示数据的逻辑。Servlet仅仅负责产生中间数据,将这些数据以JavaBean对象的形式存储在Session对象里面。系统的可缩放性:必须指出的是,存储在Session对象中的JavaBean对象的大小直接影响到系统的可缩放性(sacalability). 这些JavaBean对象越大,系统的可缩放性就越差。特别是在使用Application Server的clustering功能时,这些对象会被复制到每一个参加cluster的服务器上,因此也 会消耗一定的资源。所以必须设法将这些JavaBean对象控制在尽可能小的程序上。用户数据检查与MVC模式:下面讨论下基于国际网络技术的信息系统的用户输入检查问题。 Client-Server系统设计:在Client-Server系统设计中,一般倾向于将用户数据检查放到视图端。模型端和控制器端接收任何从视图端传来的用户输入数据。由于Client-Server系统的模型段通常就是数据库,而剩下的两层,即它的视图端和控制器端虽然可以在逻辑上分开,但往往是在同一个地址空间中运行的,物理上并不能分开。由于视图端和控制器端在物理上并不能分开,因此不存在数据传送过程中被恶意用户截获和篡改的可能性。同时,由于模型端(数据库)与视图端和控制器端的联络是在防火墙内部的,因此模型端与控制器、模型与视图端的通信被截获和篡改的可能性很小。国际联网的网站系统随着国际网络技术的普及,很多原先从事Client-Server系统设计的设计师也进入基于国际网络技术的信息系统的设计,他们往往不自觉地将很多Client-Server系统设计中的标准做法带入到基于国际网络技术的信息系统的设计中来。将用户输入检查的责任完全交给视图端的做法也被很多人带入到后者的设计中。而这样会产生很多不安全的系统设计。在一个基于国际网络技术的系统中,视图端的一部分往往在用户自己的浏览器(brower)内运行,另外的视图,控制器,模型端则是在服务器内部运行。在用户浏览器中的视图端与在服务器内的视图是通过HTTP协议经过国际网络相互联络。这时候就需要特别注意可能被截获和篡改的问题。很多设计师错误地解释MVC模式,认为用户端输入检查是试图端的责任,从而将用户输入检查完全局限在客户端的JavaScript检查上,而服务器端则接受任何传进来的用户输入数据,这是很危险的。应用层的保护:使用SSL是保证通信安全的一个手段,使用SSL可以想用户证明服务器的身份,使用SSL不能保证恶意用户没有篡改用户输入的数据,SSL也不能提供应用层的任何保护。为了做到应用层的保护,建议大家使用下面的保护措施: 1. 使用带有密钥的hashing功能,比如md5sum进行数据的完整型检查。 2. 使用像DES这样的行业标准加密算法对数据进行加密(DES即Data Encryption Standard, 是美国政府承认的加密算法标准,美国政府要求某些金融业电子化服务必须采用DES标准)。 3. 列出所有可能的用户端的无效输入,并在用户输入检查过程中加以排除。必须记住,SSL并不能提供以上的保护,SSL保护数据在传送过程中的安全,但是并不能保证浏览器中数据元素,换言之,SSL并不能保证用户输入数据没有被恶意用户利用,来窥视信息系统的秘密。用户端输入检查:一个基于国际网路技术的信息系统的设计必须假设有一些用户是恶意的,这些用户可能利用系统的任何安全漏洞窥视系统的秘密,并利用系统的设计缺陷获取非法的商业价值。为了保护信息系统的安全,设计师必须要做到以下两点:系统必须在服务器一端也进行基于安全考虑的用户输入数据的检查。虽然浏览器内部的JavaScript也可以用来对输入数据进行合法性检查,但是恶意用户可以使用诸如Achilles等软件将传到客户端的网页做相应的修改。在传到浏览器上。这样恶意用户可以妨碍其恶意操作的JavaScript轻易的去掉。不可以将系统内部出错的信息传给客户端,不可以将含有详细程序错误信息的出错信息传递给浏览器,没有一个系统是完美无缺的。任何系统都会出错,特别是恶意用户蓄意制造出错的情况下。在出错的情况下,仅给客户端显示一个抱歉信息,诸如“很抱歉,系统出现运行时错误,请与管理员联系”一类的错误信息,而绝对不应当给出具体的JVM错误信息。下面谈谈三层架构和MVC模式的区别:这两者本省讲的是不同方向与角度的问题。在实际应用中,他们的确存在一些相似的特点。首先,N层结构时一种软件抽象的层次结构,是对复杂然间的一种纵向切分,每一层中完成同一类型的操作,以便将各种代码以其完成的使命作为依据来分隔,以减低软件的复杂度,提高其可维护性,一般而言,层次之间是向下依赖的,下层代码来确定其接口(契约)前,上层代码是无法开发的,下层代码接口(契约)的变化将使上层的代码一起变化,三层结构是N层结构的一种,是人产在长时间使用中得出来的一种应用场合广泛的N层架构,被当做一种典型的软件层次结构而广为流传甚至写入教科书。 MVC模式是一种复合的设计模式,一种特定场合用于解决某种实际问题来得出的可以反复实践的解决方案。首先,在MVC中的三个事物之间并不存在明显的层次结构,没有明显的向下依赖关系,相反的,View和Model往往是比较独立的,而Control是连接两者的桥梁,他们更像是横向的切分,这样一来就出现一个结果,MVC每个块都是可以独立测试的,而三层架构中,上层模块的运行测试必须提供下层代码或者提供接口,另外,MVC中每一块Model则是业务提供者,决定了软件提供的功能,其内部可能是一些普通的类或者是实现了某些接口的类,在这一块当中可能根据业务的不同而色彩缤纷,对于复杂的软件可能会分成很多层,如业务逻辑层、业务提供层、系统提供层、数据提供层、数据访问层等内部特别是Model内部经常被设计为多层的。
MVC模式与用户输入数据检查
最新推荐文章于 2022-02-07 09:14:01 发布