架构 : 三层架构、MVC、MVP、MVVM
1、 三层架构
1.1、 规则
- 最关键的,UI层只能作为一个外壳,不能包含任何业务逻辑(BizLogic)的处理过程。只有少量(或者没有)SQL语句或者存储过程的调用,并且这些语句保证不会修改数据。
- 设计时应该从BLL出发,而不是UI出发。BLL层在API上应该实现所有BizLogic(以面向对象的方式)。如果把UILayer拿掉,项目还能在Interface/API的层次上提供所有功能)。
- 不管数据层是一个简单的SqlHelper也好,还是带有Mapping过的Classes也好,应该在一定的抽象程度上做到系统无关(DAL可以移植到其他类似环境的项目)。
- 不管使用COM+(Enterprise Service),还是Remoting,还是WebService之类的远程对象技术,不管部署的时候是不是真的分别部署到不同的服务器上,最起码在设计的时候要做这样的考虑,更远的,还得考虑多台服务器通过负载均衡作集群(三个模块,可以分别运行于不同的服务器)。
1.2、 优势
1,结构清晰、耦合度低,
2,可维护性高,可扩展性高;
3,利于开发任务同步进行;容易适应需求变化
1.3、 劣势
1、有时会导致级联的修改。这种修改尤其体现在自上而下的方向。如果在表示层中需要增加一个功能,为保证其设计符合分层式结构,可能需要在相应的业务逻辑层和数据访问层中都增加相应的代码
2、增加了代码量,增加了工作量,增加了复杂度。
2、 MVC
MVC则是表现层的框架模式。用于解除业务逻辑和视图之间的耦合。从而易于扩展,便于测试。
2.1、 Model
2.2、 View
2.3、 Controller
2.1、 MVC使用的误区
2.1.1、 把Model理解成实体类(Entity)
在MVC中Model应该包含2部分功能,一部分是处理业务逻辑,一部分是提供View显示的数据。
2.1.2、 大量业务逻辑代码堆积在Controller端
- 控制器中写业务代码
- UI逻辑可以写在Controller中,而业务逻辑应该在Model里,Controller只是去调用它们。
控制器变得依赖信息数据中心或数据库,对象将间接地通过控制器的action耦合在一起
- 可以通过引入IOC容器来解决
2.2、 总结
MVC最早的定义毕竟是79年提出的,到现在GUI编程环境,业务复杂程度都有了很大改变。当采用MVC模式设计UI应用时,一般会根据开发框架的特点来对Model,View和Contoller设置一个明确的界限,同时为它们之间的交互制定一个更加严格的规则。
3、 MVC变体
3.1、 MVP
- MVP适用于基于事件驱动的应用框架中,如Asp.net Web Forms 和Windows Forms应用。
- MVP中严格禁止View和Model间的直接交互,必需通过Presenter来完成。Model的独立性得到了真正的体现,它不仅仅与可视化元素的呈现(View)无关,与UI处理逻辑也无关。使用MVP的应用是用户驱动而不是Model驱动,所以Model不需要主动通知view。
- MVP模式中的V代表的是一个接口,一个将UI界面提炼而抽象出来的接口。接口意味着任何实现了该接口的界面,都能够复用已有的Presenter和Model代码。是真正意义上的隔离View的细节和复杂性的模式,降低了Presenter对View的依赖。带来的好处就是定义在Presenter中的UI处理逻辑变得易于测试。
3.1.1、 PV
3.1.2、 SC
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;
}
}
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.2、 MVVM
3.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
架构 : 三层架构、MVC、MVP、MVVM的更多相关文章
- Android App的设计架构:MVC,MVP,MVVM与架构经验谈
相关:http://www.cnblogs.com/wytiger/p/5996876.html 和MVC框架模式一样,Model模型处理数据代码不变在Android的App开发中,很多人经常会头疼于 ...
- Android App的设计架构:MVC,MVP,MVVM与架构AAAAA
1. 架构设计的目的1.1 通过设计使程序模块化,做到模块内部的高聚合和模块之间的低耦合.1.2 这样做的好处是使得程序在开发的过程中,开发人员只需要专注于一点,提高程序开发的效率,并且更容易进行后续 ...
- [转]MVVM架构~mvc,mvp,mvvm大话开篇
MVP 是从经典的模式MVC演变而来,它们的基本思想有相通的地方:Controller/Presenter负责逻辑的处理,Model提供数据,View负 责显示.作为一种新的模式,MVP与MVC有着一 ...
- 前端mvc mvp mvvm 架构介绍(vue重构项目一)
首先 我们为什么重构这个项目 1:我们现有的技术是前后台不分离,页面上采用esayUI+jq构成的单页面,每个所谓的单页面都是从后台胜场的唯一Id 与前端绑定,即使你找到了那个页面元素,也找不到所在的 ...
- android MVC && MVP && MVVM分析和对比
相关:http://www.cnblogs.com/wytiger/p/5305087.html 出处http://blog.csdn.net/self_study,对技术感兴趣的同鞋加群544645 ...
- MVC, MVP, MVVM比较以及区别(上)
MVC, MVP和MVVM都是用来解决界面呈现和逻辑代码分离而出现的模式.以前只是对它们有部分的了解,没有深入的研究过,对于一些里面的概念和区别也是一知半解.现在一边查资料,并结合自己的理解,来谈一下 ...
- MVC, MVP, MVVM比较以及区别
MVC, MVP和MVVM都是用来解决界面呈现和逻辑代码分离而出现的模式.以前只是对它们有部分的了解,没有深入的研究过,对于一些里面的概念和区别也是一知半解.现在一边查资料,并结合自己的理解,来谈一下 ...
- [1] MVC & MVP &MVVM
开发架构之MVC & MVP & MVVM
- 浅析前端开发中的 MVC/MVP/MVVM 模式
MVC,MVP和MVVM都是常见的软件架构设计模式(Architectural Pattern),它通过分离关注点来改进代码的组织方式.不同于设计模式(Design Pattern),只是为了解决一类 ...
- 用户界面编程模式 MVC MVP MVVM
用户界面编程模式 MVC MVP MVVM 程序 = 数据 + 算法 数据:就是待处理的东西 算法:就是代码 涉及到人机交互的程序,不可避免涉及到界面和界面上显示的数据原始方式是界面代码和逻辑代码糅合 ...
随机推荐
- Ubuntu 14.04环境变量修改
因在开发编译时是找不到命令,原因是将路径添加到环境变量,如何设置环境变量,搜索一下,找到以下关于环境变量设置的几个文件及何时执行. 首先要认识几个和环境变量有关的文件: /etc/profile —— ...
- Mac上把python源文件编译成so文件
把python源文件编译成so文件 前言 实际上属于一种代码混淆/加密的技术,大家知道python的源文件放在那里,大家是都可以看的,不像C语言编译出来可以拿编译后的东西去运行,所以就出现了这种需求. ...
- LeetCode: Validate Binary Search Tree 解题报告
Validate Binary Search Tree Given a binary tree, determine if it is a valid binary search tree (BST) ...
- sql 基础练习 计算7天各个时间点的总和 group by order mysql一次查询多个表
SQL 基础练习 -- 创建数据库 CREATE DATABASE school CHARACTER SET UTF8; -- 使用数据库 USE school; -- id: 学生的id -- na ...
- python celery 多work多队列
1.Celery模块调用 既然celery是一个分布式的任务调度模块,那么celery是如何和分布式挂钩呢,celery可以支持多台不通的计算机执行不同的任务或者相同的任务. 如果要说celery的分 ...
- Robo 可视化mongoDb的操作
因为公司的项目出现了MongodbCpu 100%的问题,所以最近在开始排查,也开始更加深入的接触Mongodb这个缓存型的数据库. 简单的就不说了,前面几张有安装和简单的使用,因为需要开始添加索引, ...
- 编译 Linux 3.5 内核烧写 Android 4.2.2 到 Tiny4412 开发板
. . . . . 昨天已经编译了 Android 4.2.2 的源码,详见<Ubuntu 14.04 编译 Android 4.2.2 for Tiny4412>一文. 今天我们继续剩下 ...
- Objective的宏到swift中该怎么办?
ReadMehtml, body {overflow-x: initial !important;}.CodeMirror { height: auto; } .CodeMirror-scroll { ...
- android——字符串string(转)
原文地址:http://www.open-open.com/lib/view/open1387942832078.html String : 字符串类型 一.构造函数 String(byte[ ...
- 【转】15个最受欢迎的Python开源框架
以下是伯乐在线从GitHub中整理出的15个最受欢迎的Python开源框架.这些框架包括事件I/O,OLAP,Web开发,高性能网络通信,测试,爬虫等. Django: Python Web应用开发框 ...