架构 : 三层架构、MVC、MVP、MVVM

一、 三层架构

 
将整个业务应用划分为:界面层(User Interface layer, UIL)、业务逻辑层(Business Logic Layer, BLL)、数据访问层(Data access layer, DAL)。
 
 
1:界面层: 主要是指用户交互的界面。用于接收用户输入的数据和显示处理后用户须要的数据。若是逻辑层至关强大和完善,不管表现层如何定义和更改,逻辑层都能完善地提供服务。
 
2:业务逻辑层: UI层和DAL层之间的桥梁实现业务逻辑。业务逻辑具体包含:验证、计算、业务规则等等。
 
3:数据访问层:与数据库打交道。主要实现对数据的增、删、改、查。将存储在数据库中的数据提交给业务层,同时将业务层处理的数据保存到数据库。(固然这些操做都是基于UI层的。用户的需求反映给界面(UI),UI反映给BLLBLL反映给DALDAL进行数据的操做,操做后再一一返回,直到将用户所需数据反馈给用户)。
 
   

1.一、 规则

  1. 最关键的,UI层只能做为一个外壳,不能包含任何业务逻辑(BizLogic)的处理过程。只有少许(或者没有)SQL语句或者存储过程的调用,而且这些语句保证不会修改数据。
  2. 设计时应该从BLL出发,而不是UI出发。BLL层在API上应该实现全部BizLogic(以面向对象的方式)。若是把UILayer拿掉,项目还能在Interface/API的层次上提供全部功能)。
  3. 无论数据层是一个简单的SqlHelper也好,仍是带有Mapping过的Classes也好,应该在必定的抽象程度上作到系统无关(DAL能够移植到其余相似环境的项目)。
  4. 无论使用COM+(Enterprise Service),仍是Remoting,仍是WebService之类的远程对象技术,无论部署的时候是否是真的分别部署到不一样的服务器上,最起码在设计的时候要作这样的考虑,更远的,还得考虑多台服务器经过负载均衡做集群(三个模块,能够分别运行于不一样的服务器)。

1.二、 优点

1,结构清晰、耦合度低,html

2,可维护性高,可扩展性高;程序员

3,利于开发任务同步进行;容易适应需求变化数据库

1.三、 劣势

一、有时会致使级联的修改。这种修改尤为体如今自上而下的方向。若是在表示层中须要增长一个功能,为保证其设计符合分层式结构,可能须要在相应的业务逻辑层和数据访问层中都增长相应的代码编程

二、增长了代码量,增长了工做量,增长了复杂度。服务器

 

二、 MVC

 

 

若是说ORM(Object Relation Mapping)等框架是数据访问层的框架模式,解除了业务逻辑和数据之间的耦合,业务逻辑再也不关心底层数据如何存储和读取。全部数据呈现给业务逻辑层的就是一个个的对象。

MVC则是表现层的框架模式。用于解除业务逻辑和视图之间的耦合。从而易于扩展,便于测试。架构

 

MVC诞生于1979年,体现了“关注点分离”这一设计方针,它将一我的机交互应用涉及的功能分为三部分。

2.一、 Model

Model对应应用状态和业务功能的封装,能够将它理解为同时包含数据和行为的领域模型(Domain Model)。Model接受Controller的请求并完成相应的业务处理,在应用状态改变的时候能够向View发出相应的通知。

2.二、 View

View实现可视化界面的呈现并捕捉最终用户的交互操做。View能够直接调用Model查询其状态信息,而Model也能够在本身的状态发生改变时,主动通知View。

2.三、 Controller

Contoller是M和V之间的链接器,用于控制应用程序的流程。View捕获用户交互操做后直接转发给Contoller,后者完成相应的UI逻辑。若是须要涉及业务功能的调用,Contoller会直接调用Model及修改Model状态。Contoller也能够主动控制原View或建立新的View对用户交互操做予以响应。
 

2.一、 MVC使用的误区

2.1.一、 把Model理解成实体类(Entity)

在MVC中Model应该包含2部分功能,一部分是处理业务逻辑,一部分是提供View显示的数据。app

它应该是业务逻辑真正的实现层。因此Model的其实是Business Model(业务模型)。而Controller仅仅起一个“桥梁”做用,它负责把View的请求转发给Model,再负责把Model处理结束的消息通知View。Controller的存在是为了使UI界面、UI逻辑、业务逻辑之间分离。

2.1.二、 大量业务逻辑代码堆积在Controller端

MVC中的控制器,内里封装了通信,容易变成大而全 的高度耦合的集中器。
  1. 控制器中写业务代码
    1. UI逻辑能够写在Controller中,而业务逻辑应该在Model里,Controller只是去调用它们。
  2. 控制器变得依赖信息数据中心或数据库,对象将间接地经过控制器的action耦合在一块儿负载均衡

    1. 能够经过引入IOC容器来解决

2.二、 总结

MVC最先的定义毕竟是79年提出的,到如今GUI编程环境,业务复杂程度都有了很大改变。当采用MVC模式设计UI应用时,通常会根据开发框架的特色来对Model,View和Contoller设置一个明确的界限,同时为它们之间的交互制定一个更加严格的规则。

三、 MVC变体

在软件发展历程中出现了一些MVC变体,它们遵循定义在MVC中的基本原则,但对三元素直接的交互制定了更为严格的规范。

3.一、 MVP

  1. MVP适用于基于事件驱动的应用框架中,如Asp.net Web Forms 和Windows Forms应用。
  2. MVP中严格禁止View和Model间的直接交互,必需经过Presenter来完成。Model的独立性获得了真正的体现,它不只仅与可视化元素的呈现(View)无关,与UI处理逻辑也无关。使用MVP的应用是用户驱动而不是Model驱动,因此Model不须要主动通知view。
  3. MVP模式中的V表明的是一个接口,一个将UI界面提炼而抽象出来的接口。接口意味着任何实现了该接口的界面,都可以复用已有的Presenter和Model代码。是真正意义上的隔离View的细节和复杂性的模式,下降了Presenter对View的依赖。带来的好处就是定义在Presenter中的UI处理逻辑变得易于测试。
 
MVP中Presenter与Model的交互很清晰,仅体现为Presenter对Model的单向调用。而View与Presenter直接的交互方式就成了MVP的核心。按照View与Presenter的交互方式依据View自己的职责范围,Martin Folwer将MVP分为PV(Passive View)和SC(Supervising Contoller)两种模式。

3.1.一、 PV

view是难以测试的,经过让它尽量不涉及UI处理逻辑来使它不须要测试,这就是PV模式的目的。
这意味着须要将View中的UI元素经过属性的形式暴露出来。将全部UI处理逻辑所有定义到Presenter中。定义在IView里的只有属性。

3.1.二、 SC

PV须要将View中可供操做的UI元素定义在对应的接口中,对于一些复杂的富客户端应用的View来讲,接口成员的数量可能会很是多,这无疑提高了代码量和Presenter的复杂度。
SC则将一些单纯,独立的UI逻辑交由View自身来完成。固然它处理的数据是Presenter实时推送给它的。View尽量不维护数据状态。定义在IView里的接口尽可能只包含方法,且是无返回值的方法(单向传递消息)。
 
Models:
public class Employee
{
     public  string  Id {  get private  set ; }
     public  string  Name {  get private  set ; }
     public  string  Gender {  get private  set ; }
     public  DateTime BirthDate {  get private  set ; }
     public  string  Department {  get private  set ; }
 
     public  Employee( string  id, string  name, string  gender,DateTime birthDate, string  department)
     {
         Id          = id;
         Name        = name;
         Gender      = gender;
         BirthDate   = birthDate;
         Department  = department;
     }
}
 
public  class  EmployeeRespository
{
     private  static  IList<Employee> employees;
 
     static  EmployeeRespository()
     {
         employees =  new  List<Employee>()
         {
             new  Employee( "001" , "张三" , "男" , new  DateTime(1981,8,24), "销售部" ),
             new  Employee( "002" , "李四" , "男" , new  DateTime(1981,8,24), "人事部" ),
             new  Employee( "003" , "王五" , "女" , new  DateTime(1981,8,24), "人事部" )
         };
     }
 
     public  IEnumerable<Employee> GetEmployees( string  department =  "" )
     {
         if  ( string .IsNullOrEmpty(department))
         {
             return  employees;
         }
         return  employees.Where(e => e.Department == department).ToArray();
     }
}

 
Presenter、IView
public class EmployeePresenter
{
     public  IEmployeeView View {  get private  set ; }
     public  EmployeeRespository Respository {  get private  set ; }
 
     public  EmployeePresenter(IEmployeeView view)
     {
         this .View = view;
         this .Respository =  new  EmployeeRespository();
         this .View.DepartmentSelected += OnDepartmentSelected;
     }
 
     public  void  Initialize()
     {
         IEnumerable<Employee> employees =  this .Respository.GetEmployees();
         this .View.BindEmployees(employees);
         string [] departments
             new  string []{
                 "" , "销售部" , "采购部" , "人事部"
             };
         this .View.BindDepartments(departments);
     }
 
     protected  void  OnDepartmentSelected( object  sender, DepartmentSelectedEventArgs args)
     {
         string  department = args.Department;
         var  employees =  this .Respository.GetEmployees(department);
         this .View.BindEmployees(employees);
     }
}
 
 
public  interface  IEmployeeView
{
     void  BindEmployees(IEnumerable<Employee> employees);
     void  BindDepartments(IEnumerable< string > departments);
     event  EventHandler<DepartmentSelectedEventArgs> DepartmentSelected;
}
public  class  DepartmentSelectedEventArgs : EventArgs
{
     public  string  Department {  get private  set ; }
     public  DepartmentSelectedEventArgs( string  department)
     {
         this .Department = department;
     }
}
WinForm实现的UI界面
public  partial  class  Form1 : Form, IEmployeeView
{
     private  EmployeePresenter Presenter{  get private  set ; }
     public  Form1()
     {
         InitializeComponent();
 
         Presenter =  new  EmployeePresenter( this );
         Presenter.Initialize();      
     }
     public  event  EventHandler<DepartmentSelectedEventArgs> DepartmentSelected;
 
     public  void  BindDepartments(IEnumerable< string > departments)
     {
         this .comboBox1.DataSource = departments;
     }
 
     public  void  BindEmployees(IEnumerable<Employee> employees)
     {
         this .listBox1.DataSource = employees;
         this .listBox1.DisplayMember =  "Name" ;
     }
 
     private  void  comboBox1_SelectedIndexChanged( object  sender, EventArgs e)
     {
         string  department = ( string ) this .comboBox1.SelectedItem;
         DepartmentSelectedEventArgs eventArgs =  new  DepartmentSelectedEventArgs(department);
         DepartmentSelected?.Invoke(sender, eventArgs);
     }
}

 

WebForm实现的UI界面
public  partial  class  Default : Page, IEmployeeView
{
     public  EmployeePresenter Presenter {  get private  set ; }
     public  event  EventHandler<DepartmentSelectedEventArgs> DepartmentSelected;
 
     public  Default()
     {
         this .Presenter =  new  EmployeePresenter( this );
     }
 
     protected  void  Page_Load( object  sender, EventArgs e)
     {
         if  (! this .IsPostBack)
         {
             this .Presenter.Initialize();
         }
     }
 
     protected  void  ButtonSearch_Click( object  sender, EventArgs e)
     {
         string  department =  this .DropDownListDepartments.SelectedValue;
         DepartmentSelectedEventArgs eventArgs =  new  DepartmentSelectedEventArgs(department);
         if  ( null  != DepartmentSelected)
         {
             DepartmentSelected( this , eventArgs);
         }
     }
 
     public  void  BindEmployees(IEnumerable<Employee> employees)
     {
         this .GridViewEmployees.DataSource = employees;
         this .GridViewEmployees.DataBind();
     }
 
 
     public  void  BindDepartments(IEnumerable< string > departments)
     {
         this .DropDownListDepartments.DataSource = departments;
         this .DropDownListDepartments.DataBind();
     }
}

在MVP里,能够根据User Story来首先设计和开发Presenter。在这个过程当中,View是很简单的,可以把信息显示清楚就能够了。在后面,根据须要再随便更改View, 而对Presenter没有任何的影响了。框架

若是要实现的UI比较复杂,并且相关的显示逻辑还跟Model有关系,能够在View和 Presenter之间放置一个Adapter。由这个 Adapter来访问Model和View,避免二者之间的关联。而同时,由于Adapter实现了View的接口,从而能够保证与Presenter之 间接口的不变。这样就能够保证View和Presenter之间接口的简洁,又不失去UI的灵活性。函数

3.二、 MVVM

MVVM模式中,一个ViewModel和一个View匹配,它没有MVP中的IView接口,而是彻底的和View绑定,全部View中的修改变化,都会自动更新到ViewModel中,同时ViewModel的任何变化也会自动同步到View上显示。
这种自动同步之因此可以的缘由是ViewModel中的属性都实现了observable这样的接口,也就是说当使用属性的set的方法,都会同时触发属性修改的事件,使绑定的UI自动刷新。(在WPF中,这个observable接口是 INotifyPropertyChanged; 在knockoutjs中,是经过函数ko.observable() 和ko.observrableCollection()来实现的)
在MVP中,V是接口IView, 解决对于界面UI的耦合; 而MVVM则干脆直接使用ViewModel和UI无缝结合, ViewModel直接就能表明UI。可是MVVM作到这点是要依赖具体的平台和技术实现。 这也就是为何ViewModel不须要实现接口的缘由,由于对于具体平台和技术的依赖,本质上使用MVVM模式就是不能替换UI的使用平台的。
MVVM的提出源于WPF,主要是用于分离应用界面层和业务逻辑层。WPF/Siverlight是基于数据驱动开发的。
在MVC和MVP模式中, 开发View层的是程序员, 虽然UI/UE团队会作不少工做, 但这个层的"实现者"仍然是程序员。
而在WPF开发中将View层的代码逻辑抽取出来,并使View层很纯粹以便彻底让美工去打造它。相应地, 须要将View层的相应逻辑抽取到一个代码层上,以便让程序员专一在这里。

3.三、 Asp.net Mvc 应用中的请求处理

  • 每一个HTTP请求的目标是Controller中的一个Action,具体体现为定义在Controller类型中的一个public方法。因此对请求的处理最终体现为对目标Controller对象的激活和对目标Action方法的执行。
  • Controller的类型和Action方法的名称及做为Action方法的部分参数能够直接经过请求的Url解析出来。
  • 经过一个拦截器(Interceptor)对抵达Web服务器的HTTP请求进行拦截。这个拦截器根据当前请求解析出目标Controller的类型和对应的Action方法的名称,随后目标Controller被激活,相应的Action方法被执行。
  • Action方法执行过程当中,能够调用Model获取相应的数据及改变其状态。在Action执行的最后阶段通常会建立一个View,后者最终被转换为HTML以HTTP响应的形式返回到客户端。
  • 绑定在View上的数据称为ViewModel,来源于Model或者基于显示要求进行的简单逻辑计算。它与MVVM中的ViewModel是彻底不一样的概念,后者不只包括呈如今View中的数据,也包括数据操做行为。

 


 转载自:http://www.cnblogs.com/wj033/p/5812938.html

相关文章
相关标签/搜索