mvc架构模式没有接口怎么使用虚拟数据库

MVC 搭建属于自己的框架(一)
孤独的十字
发布时间: 11:24:08
为什么要自己搭框架?
  大家伙别急,让我慢慢地告诉你!大家有没有这种感觉,从一家跳槽到另一家公司,公司的框架往往是不相同的,这样你必须就得摒弃原来的,学习新的框架。
问题是你用习惯了一种框架,比如封装的扩展方法、工厂模式、实体映射等等,你用得很爽,但是跳槽到新的公司,又得学习他们公司的框架,往往你在这上面
要花费不少时间。
所以我才有了搭建自己的框架的想法,我的框架用到了EntityFramework6.0+Asp.NET MVC4+Autofac等,下面是我的框架结构:
MyFrame.Domain 实体模型层
MyFrame.DataMapping 数据映射层:映射实体类和数据库表关系,数据库上下文存放在该层
MyFrame.IDao 数据访问接口层
MyFrame.Dao 数据访问层
MyFrame.IService 业务逻辑接口层
MyFrame.Service 业务逻辑层
MyFrame.Common 通用扩展层
MyFrame.Web UI层
层与层之间的引用关系
  Domain(最低层)=》每个层调用;IDao=&Dao,S IService=&S IDao,IService=&Web
实体基类  MyFrame.Domain.DomainBase:实体基类,实体类都需要继承DomainBase,现在这个类只有两个属性,等之后慢慢扩展完善  
3 namespace MyFrame.Domain
/// &summary&
/// 实体基类
/// &/summary&
public class DomainBase
/// &summary&
/// &/summary&
public int Id { get; set; }
/// &summary&
/// 创建时间
/// &/summary&
public DateTime CreateTime { get; set; }
DomainBase
数据访问基类接口 
MyFrame.IDao.IDaoBase:封装了增删改查方法以及分页等
1 using System.Collections.G
2 using PagedL
4 namespace MyFrame.IDao
/// &summary&
/// 数据访问层的基类接口
/// &/summary&
public interface IDaoBase&T& where T:class
/// &summary&
/// &/summary&
/// &param name="domain"&实体&/param&
/// &returns&&/returns&
int Insert(T domain);
/// &summary&
/// 通过Id删除
/// &/summary&
/// &param name="id"&Id&/param&
/// &returns&&/returns&
bool Delete(int id);
/// &summary&
/// &/summary&
/// &param name="domain"&实体&/param&
/// &returns&&/returns&
bool Delete(T domain);
/// &summary&
/// 更新操作
/// &/summary&
/// &param name="domain"&实体&/param&
/// &returns&&/returns&
bool Update(T domain);
/// &summary&
/// 通过Id查询
/// &/summary&
/// &param name="id"&Id&/param&
/// &returns&&/returns&
T SelectById(int id);
/// &summary&
/// 查询所有
/// &/summary&
/// &returns&&/returns&
IEnumerable&T& SelectAll();
/// &summary&
/// 分页查询
/// &/summary&
/// &typeparam name="T"&&/typeparam&
/// &param name="pageIndex"&&/param&
/// &param name="pageSize"&&/param&
/// &returns&&/returns&
IPagedList&T& SelectPageList(int? pageIndex = 1, int? pageSize = 10);
数据访问实现基类
MyFrame.Dao.DaoBase:需要继承IDaoBase,IDisposable
2 using System.Collections.G
3 using System.Data.E
4 using System.L
5 using MyFrame.D
6 using MyFrame.ID
7 using MyFrame.DataM
8 using PagedL
10 namespace MyFrame.Dao
/// &summary&
/// 数据访问层基类
/// &/summary&
public class DaoBase&T&
: IDisposable, IDaoBase&T& where T : DomainBase
protected readonly DbContext DbC
public DaoBase()
DbContext = new DataBaseContext();
int Insert(T t)
t.CreateTime = DateTime.N
DbContext.Entry&T&(t);
DbContext.Set&T&().Add(t);
return SaveChanges();
public bool Delete(int id)
T domain = DbContext.Set&T&().FirstOrDefault(s =& s.Id == id);
if (domain == null)
return false;
DbContext.Set&T&().Attach(domain);
DbContext.Set&T&().Remove(domain);
return SaveChanges() & 0;
public bool Delete(T t)
DbContext.Set&T&().Attach(t);
DbContext.Set&T&().Remove(t);
return SaveChanges() & 0;
public bool Update(T t)
DbContext.Set&T&().Attach(t);
DbContext.Entry(t).State = EntityState.M
return SaveChanges() & 0;
public T SelectById(int id)
return DbContext.Set&T&().FirstOrDefault(s =& s.Id == id);
public IEnumerable&T& SelectAll()
return DbContext.Set&T&();
public IPagedList&T& SelectPageList(int? pageIndex, int? pageSize)
IEnumerable&T& list = DbContext.Set&T&().OrderByDescending(s=&s.CreateTime);
return list.ToPagedList(pageIndex??1,pageSize??10);
/// &summary&
/// 提交数据库操作进行异常捕捉
/// &/summary&
/// &returns&&/returns&
private int SaveChanges()
int result = DbContext.SaveChanges();
catch (System.Data.Entity.Infrastructure.DbUpdateException ex)
string message = "error:";
if (ex.InnerException == null)
message += ex.Message + ",";
else if (ex.InnerException.InnerException == null)
message += ex.InnerException.Message + ",";
else if (ex.InnerException.InnerException.InnerException == null)
message += ex.InnerException.InnerException.Message + ",";
throw new Exception(message);
public void Dispose()
DbContext.Dispose();
数据库访问上下文
MyFrame.DataMapping.DataBaseContext
1 using System.Data.E
2 using MyFrame.DataMapping.M
3 using MyFrame.D
5 namespace MyFrame.DataMapping
/// &summary&
/// 数据库访问上下文
/// &/summary&
public class DataBaseContext : DbContext
public DataBaseContext()
: base("Name=EhiBus")
Database.SetInitializer&DataBaseContext&(null);
public DbSet&User& Users { get; set; }
public DbSet&Driver& Drivers { get; set; }
//将实体映射到数据库表
protected override void OnModelCreating(DbModelBuilder modelBuilder)
modelBuilder.Configurations.Add(new UserMap());
modelBuilder.Configurations.Add(new DriverMap());
DataBaseContext
1 using System.Data.Entity.ModelC
2 using MyFrame.D
4 namespace MyFrame.DataMapping.Mapping
public class UserMap : EntityTypeConfiguration&User&
public UserMap()
this.HasKey(t =& t.Id);
this.ToTable("User");
this.Property(t =& t.Id).HasColumnName("Id");
this.Property(t =& t.CreateTime).HasColumnName("CreateTime");
扩展帮助类
MyFrame.Common.Helper:封装了一些常用的方法,我自己用起来比较顺手,增加自己的开发效率
3 namespace MyFrame.Common
public static class Helper
#region 字符串转换为Int
/// &summary&
/// 将字符串转换为Int?类型
/// &/summary&
public static int? ToInt32(this string s)
num = Convert.ToInt32(s);
catch (FormatException formatException)
num = null;
catch (OverflowException overflowException)
num = null;
/// &summary&
/// 将字符串转换为Int类型
/// &/summary&
public static int ToInt32Req(this string s)
int num = Convert.ToInt32(s);
catch (FormatException ex)
throw new Exception(ex.Message);
catch (OverflowException overflowException)
throw new Exception(overflowException.Message);
#endregion
#region 字符串转换为Decimal
/// &summary&
/// 将字符串转换为Decimal?类型
/// &/summary&
public static decimal? ToDecimal(this string s)
num = Convert.ToDecimal(s);
catch (Exception formatException)
num = null;
/// &summary&
/// 将字符串转换为Decimal类型,无法转换抛出异常
/// &/summary&
public static decimal ToDecimalReq(this string s)
decimal num = Convert.ToDecimal(s);
catch (FormatException ex)
throw new Exception(ex.Message);
catch (OverflowException overflowException)
throw new Exception(overflowException.Message);
#endregion
#region 字符串转换为DateTime
/// &summary&
/// 将字符串转换为DateTime?类型
/// &/summary&
public static DateTime? ToDateTime(this string s)
num = Convert.ToDateTime(s);
catch (FormatException formatException)
num = null;
/// &summary&
/// 将字符串转换为DateTime类型,无法转换抛出异常
/// &/summary&
public static DateTime ToDateTimeReq(this string s)
DateTime num = Convert.ToDateTime(s);
catch (FormatException ex)
throw new Exception(ex.Message);
#endregion
#region 字符串转换为bool
/// &summary&
/// 将字符串转换为bool?类型
/// &/summary&
public static bool? ToBool(this string s)
num = Convert.ToBoolean(s);
catch (FormatException formatException)
num = null;
/// &summary&
/// 将字符串转换为bool类型,无法转换抛出异常
/// &/summary&
public static bool ToBoolReq(this string s)
bool num = Convert.ToBoolean(s);
catch (FormatException ex)
throw new Exception(ex.Message);
#endregion
#region 根据Text转换为Enum
/// &summary&
/// 根据Text转换为Enum?类型
/// &/summary&
public static T? ToEnumByText&T&(this string s) where T:struct
t = (T) Enum.Parse(typeof (T), s);
catch (Exception ex)
/// &summary&
///根据Text转换为Enum类型,无法转换抛出异常
/// &/summary&
public static T ToEnumReqByText&T&(this string s) where T : struct
T t= (T)Enum.Parse(typeof (T), s);
catch (ArgumentNullException argumentNullException)
throw new Exception(argumentNullException.Message);
catch (ArgumentException argumentException)
throw new Exception(argumentException.Message);
catch (OverflowException overflowException)
throw new Exception(overflowException.Message);
#endregion
#region 根据Value转换为Enum
/// &summary&
/// 根据Value转换为Enum?类型
/// &/summary&
public static T? ToEnumByValue&T&(this int s) where T : struct
t = (T)Enum.Parse(typeof(T), s.ToString());
catch (Exception ex)
/// &summary&
///根据Value转换为Enum类型,无法转换抛出异常
/// &/summary&
public static T ToEnumByValueReq&T&(this int s) where T : struct
T t = (T)Enum.Parse(typeof(T), s.ToString());
catch (ArgumentNullException argumentNullException)
throw new Exception(argumentNullException.Message);
catch (ArgumentException argumentException)
throw new Exception(argumentException.Message);
catch (OverflowException overflowException)
throw new Exception(overflowException.Message);
#endregion
我用得是PagedList,Nuget里搜索安装PagedList.MVC即可,然后自己封装了一下,封装得在DaoBase里SelectPageList()
为了让这个控件扩展性更强,写了一个分部试图_PageList,定义了一个分页Model,
为什么要自己写个而不是用它自己封装好的,因为后期页码可能需要跳转&首页&,&末页&等
1 using PagedL
3 namespace MyFrame.Web.Models
public class PageListModel&T& where T:class
public IPagedList&T& PageList { get; set; }
public string Action { get; set; }
public string Controller { get; set; }
PageListModel
1 &div class="page-box"&
@if (Model.PageList.HasPreviousPage)
&a href="@Url.Action(Model.Action, Model.Controller, new { pageIndex = (Model.PageList.PageNumber - 1) })"&上一页&/a&
@for (int i = 1; i &= Model.PageList.PageC i++)
&a class="@(i == Model.PageList.PageNumber ? "currentpage" : "")" href="@Url.Action(Model.Action, Model.Controller, new { pageIndex = i })"&@i&/a&
@if (Model.PageList.HasNextPage)
&a href="@Url.Action(Model.Action, Model.Controller, new { pageIndex = (Model.PageList.PageNumber + 1) })"&下一页&/a&
1 /*分页*/
2 .page-box{ width:770px; height:40px; background:#FFF; padding-top:15px; text-align:right; padding-right:20px;}
3 .page-box a{text-decoration: none; padding:3px 7px; display:inline-block; text-align:center; border:1px solid #CFCFCF; color:#666; font-size:12px;}
4 .page-box a:hover{ background:#A4A4A4; color:#fff;}
5 .page-box .currentpage{ background:#CCC;}
怎么调用呢?跟调用分部试图方法一样,只是需要传进一个PageListModel
2 using System.Collections.G
3 using System.L
4 using System.W
5 using System.Web.M
6 using MyFrame.C
7 using MyFrame.D
8 using MyFrame.D
9 using MyFrame.ID
10 using PagedL
12 namespace MyFrame.Web.Controllers
public class HomeController : Controller
private readonly IUserDao _userD
private readonly IDriverDao _driverD
public HomeController(IUserDao userDao,IDriverDao driverDao)
_userDao = userD
_driverDao = driverD
public ActionResult Index(int? pageIndex=1)
IPagedList&Driver& drivers = _driverDao.SelectPageList(pageIndex,2);
return View(drivers);
Controller
1 @using MyFrame.Domain
2 @using MyFrame.Web.Models
3 @model PagedList.IPagedList&MyFrame.Domain.Driver&
ViewBag.Title = "Index";
Layout = "~/Views/Shared/_Layout.cshtml";
9 @foreach (var driver in Model)
&p&@driver.Id&/p&
&p&@driver.DriverName&/p&
&p&@driver.Phone&/p&
17 @Html.Partial("_PageList", new PageListModel&Driver& { PageList = Model, Action = "Index", Controller = "Home" })
Autofac组件
控制反转,类似于Ioc容器的组件,通过配置接口对应具体的实现类
然后调用我们只需要调接口就行了,降低耦合性。
组件Nuget里有自己下载安装就行
在Globl.asax里配置
2 using System.Collections.G
3 using System.L
4 using System.R
5 using System.W
6 using System.Web.H
7 using System.Web.M
8 using System.Web.O
9 using System.Web.R
10 using A
11 using Autofac.Integration.M
12 using MyFrame.C
13 using MyFrame.D
14 using MyFrame.ID
15 using MyFrame.IS
16 using MyFrame.S
18 namespace MyFrame.Web
// 注意: 有关启用 IIS6 或 IIS7 经典模式的说明,
// 请访问 http://go.microsoft.com/?LinkId=9394801
public class MvcApplication : System.Web.HttpApplication
private void SetupResolveRules(ContainerBuilder builder)
//Components are wired to services using the As() methods on ContainerBuilder
builder.RegisterType&UserDao&().As&IUserDao&();
builder.RegisterType&UserService&().As&IUserService&();
builder.RegisterType&DriverDao&().As&IDriverDao&();
protected void Application_Start()
AreaRegistration.RegisterAllAreas();
// 依赖注入
var builder = new ContainerBuilder();
SetupResolveRules(builder);
builder.RegisterControllers(Assembly.GetExecutingAssembly());
var container = builder.Build();
DependencyResolver.SetResolver(new AutofacDependencyResolver(container));
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
通过控制器里的构造方法,调用即可
2 using System.Collections.G
3 using System.L
4 using System.W
5 using System.Web.M
6 using MyFrame.C
7 using MyFrame.D
8 using MyFrame.D
9 using MyFrame.ID
10 using PagedL
12 namespace MyFrame.Web.Controllers
public class HomeController : Controller
private readonly IUserDao _userD
private readonly IDriverDao _driverD
public HomeController(IUserDao userDao,IDriverDao driverDao)
_userDao = userD
_driverDao = driverD
public ActionResult Index(int? pageIndex=1)
IPagedList&Driver& drivers = _driverDao.SelectPageList(pageIndex,2);
return View(drivers);
其实配置接口对应哪个具体实体的关系,应该放到config文件比较好,这个后期再慢慢优化把。
这是一个初级版本,后期肯定要再好好完善,比如加入Transaction事务管理,排序,条件查询等等。
大家如果有什么好的建议,尽管提,互相促进互相学习。
转载请注明出处,谢谢!
源代码下载地址:
来源:http://www.cnblogs.com/sggx/p/4555255.html温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!&&|&&
LOFTER精选
网易考拉推荐
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
本文转载自新瑞腾达
  同样是架构级别的,相同的地方在于他们都有一个表现层,但是他们不同的地方在于其他的两个层。  在三层架构中没有定义Controller的概念。这是我认为最不同的地方。而MVC也没有把业务的逻辑访问看成两个层,这是采用三层架构或MVC搭建程序最主要的区别。当然了。在三层中也提到了Model,但是三层架构中Model的概念与MVC中Model的概念是不一样的,“三层”中典型的Model层是以实体类构成的,而MVC里,则是由业务逻辑与访问数据组成的。当然啊,你要明白三层架构的MVC的区别和联系:三层架构是最基本的项目分层结果,而MVC则是三层架构的一个变体,MVC是一种好的开发模式。首先你要明白MVC分别代表的是什么意思.M 即Model(模型层),主要负责出来业务逻辑以及数据库的交互V 即View(视图层),主要用于显示数据和提交数据C 即Controller(控制器),主要是用作捕获请求并控制请求转发三层:UI 界面层 BLL 业务逻辑层,DAL数据访问层,Model 实体层MVC中的的M 不是三层中的Model(实体层),他其实包括三层中的 BLL,DAL,Model,这是非常要注意的,这也是他们之间的区别的关键所在其有点有如下:低耦合性高重用性和可适用性较低的生命周期成本快速的部署可维护性有利于软件工程化管理当然优点也有缺点,那就是内部结构复杂,不容易理解,文件数量大,管理难度自然也就大MVC设计模式…三层架构…他们细分之后得到的是:View(UI)、BIZ(BLL)、DAO(DAL)、Entity(Model)、ControllerMVC把 BIZ(BLL)、DAO(DAL)、Model(Entity) 统一称之为&模型(MODEL),得到:View、Controller、模型(MODEL)三层 在我使用中 暂未体会到控制器的存在,完全是:UI、DAO、BLL他们相同的设计理念就是:把视图设计与数据持久化进行分离,从而降低耦合性,易于扩展,提高团队开发效率。三层是基于业务逻辑来分的,而mvc是基于页面来分的根本就没有什么可比性。其实两个一起用我感觉很好MVC模式是一种复合设计模式,一种解决方案三层是种软件架构,通过接口实现编程三层模式是体系结构模式,MVC是设计模式三层模式又可归于部署模式,MVC可归于表示模式引用楼主 daijun17 的回复:如何在三层架构和mvc之间进行取舍呢?没有什么取舍的,说的根本不是一回事。在所谓的“三层”中,它要求你将BLL层独立出来,它只是告诉你表示层和业务逻辑层之间的静态关系。而MVC则告诉你在这个具体的地方如何处理其动态驱动流程,尽管mvc仍然粗糙(甚至mvp也是粗糙的),但是已经比所谓三层更细致一些了。谢谢大家的关注,这几天都在忙面试,没来结贴。再次谢谢大家。我大概明白了:三层架构和mvc设计模式侧重点不一样,三层是一种笼统的架构思想,没有限制具体的设计;而mvc就比较具体的说明它的设计方法。还是自己动手做一下,理解会更深一些,以前都是用三层架构的方法---------------------------------------------------------------------------------------------------------------ASP.NET MVC 与 WebForm 三层架构 区别1.传统WebForm开发中存在的一些问题传统的ASP.NET开发中,微软的开发团队为开发者设计了一个在可视化设计器中拖放控件,编写代码响应事件的快速开发环境。然而,它所带来的负面效应是:由于控件封装了很多东西,开发者很难了解这背后的HTML是如何运作的容易得到一个包含大量ViewState的页面,使得页面尺寸远远超过所需的内容,使得页面的打开速度较慢不容易被测试2.什么是MVC?MVC(Model-View-Controller,模型-视图-控制器模式)是软件工程中的一种软件架构模式。它把软件系统分为三个基本部分:模型(Model)、视图(View)和控制器(Controller)。3.什么是ASP.NET MVC?ASP.NET MVC是微软的开发团队基于MVC开发的一个易于被测试的框架。它具有以下特性:没有数据回传没有在页面中保存视图状态开发者可以完全掌控页面的呈现过程易于单元测试易于测试驱动开发可扩展、可替换支持WebForm中的有关特性,如:用户控件、母版页、数据绑定、本地化等不在基于文件目录结构,而是将URL映射到控制器中4.&为什么使用ASP.NET MVC?易于进行单元测试易于进行测试驱动开发避免了WebForm中大量的ViewState导致页面文件变得臃肿5.&MVC与三层架构?MVC是一种模式ASP.NET MVC是一个基于MVC模式的开发框架三层架构是一种架构至于区别,可以严格的从概念上区分开来。下图是MVC与三层架构的对应关系6. MVC与Webform如何抉择?7. 两种技术并存ASP.NET MVC框架只是给开发者提供欧诺个了开发web应用程序的一种选择,并不是要取代Webform这两种技术各有优缺点,开发者需要根据实际情况,选择对应的技术有时候,可以在同一个项目中混合使用这两种技术8.ASP.NET MVC与Webform技术的架构图总结:看完本文,相信ASP.NET WebForm与ASP.NET MVC的选择相信大家应该可以做到心中有数了,我始终觉得,很多时候并不是什么技术好不好的问题,而是适合不适合不适合的问题或者能否把它用好的问题。打个比方:如果让千里马犁地,恐怕未必能达到理想的效果,最终可能还会抱怨,什么破马,一点劲都没有。========================================================================&同样是架构级别的,它们有什么相同点和不同点呢?这篇文章讨论一下它们的异同点。希望能帮助读者理解其中的玄机。 :)其实它们相同的地方在于他们都有一个表现层。但是他们不同的地方在于其他的两个层。首先先解释一下MVC。V即View.是视图的意思。C即Controler.是控制器的意思。而M即Model,是模型的意思。这三个里.最不容易理解的应该是Model.就是什么是Model,而为什么叫Model。我先不说为什么叫Model,先解释Controler。Controller是控制器的意思,所谓控制器,就是将用户请求转发给模型层,经过处理后把结果返回到界面展现的一个中间层,那么Controler到底管什么工作呢?先不说.先来看下在Java Web中这三个层一般的定义,一般在Java Web里,JSP充当V,Servlet充当C,JavaBean充当M,这里的Servlet管什么工作呢?接受输入,转到Model层去处理,处理结果保存后转发到JSP,然后展现数据。所以它的功能就是控制器的基本功能,它就管转发,在V和M之间转来转去。再来说说M,即Model,在Java Web里说的是JavaBean,我认识的很多人都把JavaBean误认为是实体类,其实JavaBean有比实体类更丰富的定义,在JavaBean中除了其属性和字段,还可以有行为及其事件,JavaBean可以理解为普通Java对象。Java普通对象,就是符合Java规范的所有对象,这和实体类完全是两回事。所以,我认为在MVC中。业务逻辑和数据访问应该放在Model层,也就是V负责展示数据,Controler除了转发不做业务逻辑。真正的逻辑事务,数据访问,甚至算法都放到Model去。再说三层架构。三层其实很好理解,界面,业务,数据访问,就这三个,从字面都可以理解出它们的意思。我要说的是它和MVC的区别。在三层架构中没有定义Controler的概念。这是我认为最不同的地方。而MVC也没有把业务的逻辑访问看成两个层,这是采用三层架构或MVC搭建程序最主要的区别。当然了。在三层中也提到了Model,但是三层架构中Model的概念与MVC中Model的概念是不一样的,“三层”中典型的Model层是已实体类构成的,而MVC里,则是由业务逻辑与访问数据组成的。不一样的概念。虽然名字一样。&&&&asp.net mvc和三层架构联系与区别首先,MVC和三层架构,是不一样的。  三层架构中,DAL(数据访问层)、BLL(业务逻辑层)、WEB层各司其职,意在职责分离。  MVC是 Model-View-Controller,严格说这三个加起来以后才是三层架构中的WEB层,也就是说,MVC把三层架构中的WEB层再度进行了分化,分成了控制器、视图、实体三个部分,控制器完成页面逻辑,通过实体来与界面层完成通话;而C层直接与三层中的BLL进行对话。  所以,&.net的三层结构中,并没有action这个概念。  asp.net mvc&是微软新发布的一种网站开发架构。为了解决传统asp.net开发中不能分离Model,View和Controller而设计的。  普通的网站为了解决可移植,可维护,可扩展等问题,会把网站设计成三个独立的模块,Model负责数据库部分,View负责网页的界面,而Controller负责界面与数据的交互及业务逻辑,这样设计的网站如果想设计或者重新开发某一个模块对其他的模块是没有影响的。但是asp.net的页面后台代码与每个页面代码都是一一对应的,业务逻辑在某些情况下不可避免的被写到了与View关联的后台代码中。这样就不能保证View与Controller的分离,也就很难实现网站的重写和升级。  而在MVC中页面代码并不是与后台代码一一对应,而是分别被存放成Controller和View两个部分,彻底的解决了,View和Controller不能独立的问题。从而改善网站的重写和升级过程。  但是MVC也有其缺点,由于在页面代码中不再可以使用服务器控件,因此给某些asp.net服务器端控件的使用带来了麻烦,而且MVC也页面的设计工作带来了很多障碍。  ASP.NET MVC&是微软在2009年4月份发布的一种新的网站开发架构,http://msdn.microsoft.com/en-us/library/dd394709.a spx,它是把传统意义上的MVC开发思想融合到了ASP.NET的开发当中。  那么我也来讲讲我对这两者的理解吧。  首先对这个题目,本身是存在问题的,"XX结构"与"XX模式"的区别?请问中国社会制度与美国人生活方式有什么区别?  这两者本身讲的是不同方向与角度的问题,在实际应用中他们的确存在一些相似的特点,在很多书籍中也没有深入讲解,以致于造成困惑,为了更好的理解他们,姑且来说说区别吧。  首先N层结构是一种软件抽象的层次结构,是对复杂软件的一种纵向切分,每一层次中完成同一类型的操作,以便将各种代码以其完成的使命作为依据来分割,以将低软件的复杂度,提高其可维护性。一般来说,层次之间是向下依赖的,下层代码未确定其接口(契约)前,上层代码是无法开发的,下层代码接口(契约)的变化将使上层的代码一起变化。三层结构是N层结构的一种,是人产在长时间使用中得出来的一种应用场合广泛的N层结构,被当作一种典型的软件层次结构而广为流传甚至写入教科书。  MVC模式是一种复合设计模式,一种在特定场合用于解决某种实际问题来得出的可以反复实践的解决方案。巧合的是他也有三个事物组成,于是乎人们就有了一种想当然的对应关系:展示层-View;业务逻辑层-Control;持久层-Model。首先MVC中的三个事物之间并不存在明显的层次结构,没有明显的向下依赖关系,相反的,View和Model往往是比较独立的,而Control是连接两者的桥梁,他们更像是横向的切分。这样一来就出现一个结果,MVC中每个块都是可以独立测试的,而三层结构中,上层模块的运行测试势必要提供下层代码或者提供相同接口的桩。相对来说,MVC复杂得多,但是结构更清晰,耦合性更低。  另外,MVC中每一块内部特别是Model内部经常被设计为多层的。在我认为的一个良好的MVC模式构建的结构中,Control是核心,小且较为稳定的,可以作为一个核心框架来提供,有扩展点,但基本上可以简单配置不需要任何代码就可以运行。而View则可能是一套或多种可选择的视图引擎,决定了软件展示给用于的界面,使用时的主要工作量在于扩展点以及根据需要而数量不同的视图模板。Model则是业务提供者,决定了软件提供的功能,其内部可能是一些普通的类或者是实现了某些接口的类,在这一块当中可能根据业务的不同而色彩缤纷,对于复杂的软件可能会分成很多层,如业务逻辑层、业务提供层、系统提供层、数据提供层、数据访问层等。  我经常用于比喻MVC的例子是小时候玩的那种卡带式游戏机,Control是主机,一般来说我买一个主机就行了,只要他不坏,他就能一直让我玩这一类的游戏。View则是电视机和游戏手柄,电视机可以独立工作,他不管输入的是电视信号、影碟机信号还是游戏机信号,他只管显示,而且他决定了我们看到的效果是怎么样的,如果我想要个尺寸更大的或者彩色的显示效果,我只需要买个相应的电视机就行了,手柄也是可以换的,要遥杆还是带震动的。Model则是游戏卡带,他绝定了我玩的是什么游戏,是魂斗罗还是超级玛莉,而且游戏机主机和电视机生产厂家永远也不知道在上面有可能会运行什么样的游戏。卡带中可能会有游戏代码和存储单元,都根据游戏的需要而设计。  有朋友提到游戏主机提供的卡带插槽的接口,在设计中,有时也由Control提供一组接口,以用于Model或View的实现,这样就形成了依赖。一般来说这样设计也没有太大的问题,只是会提高模块间的耦合度,也会带来一些侵入性。为了更完美,可以不用接口来提供契约,可以用配置信息(或称元数据信息)+反射来提供契约,那么这个类接口就可以退化到只要符合CLS就可以了,也就是普通的类,就像现在的计算机接口广泛采用USB,无论是U盘、打印机、扫描仪或者是加密狗,他们都是普通的USB设备而已。  提到USB有一个题外话,模块的可插拔性设计甚至是热插拔设计,系统可以在不停止运行的情况下动态的挂载或移除模块,动态挂载模块需要系统能够自动发现新模块并根据自描述的信息进行自动配置,移除可能情况更复杂一点,需要"安全删除硬件"类似的功能。  在设计广泛重用的框架时会考虑多种情况以达到更大的适应性,一般项目中应用MVC模式可以较为随意。
阅读(23025)|
用微信&&“扫一扫”
将文章分享到朋友圈。
用易信&&“扫一扫”
将文章分享到朋友圈。
历史上的今天
loftPermalink:'',
id:'fks_',
blogTitle:'【转载】终于明白了!三层架构和MVC不是一个事!',
blogAbstract:'又看到有人在问三层架构和MVC的关系,感觉这种问题有点教条化了。因为它们都在逻辑上将应用程序划为三块,凑了一个数字3,就有人非要把它们联系到一起了。  这两个东西我接触有几年了,有一点体会,表达一下:  三层是三层,MVC是MVC,它们毫无关系的。三层是从整个应用程序架构的角度来分的三层(如果程序需要,还可以分多层)。',
blogTag:'',
blogUrl:'blog/static/7',
isPublished:1,
istop:false,
modifyTime:0,
publishTime:7,
permalink:'blog/static/7',
commentCount:0,
mainCommentCount:0,
recommendCount:7,
bsrk:-100,
publisherId:0,
recomBlogHome:false,
currentRecomBlog:false,
attachmentsFileIds:[],
groupInfo:{},
friendstatus:'none',
followstatus:'unFollow',
pubSucc:'',
visitorProvince:'',
visitorCity:'',
visitorNewUser:false,
postAddInfo:{},
mset:'000',
remindgoodnightblog:false,
isBlackVisitor:false,
isShowYodaoAd:false,
hostIntro:'有容乃大
\r\n奋发以求',
hmcon:'1',
selfRecomBlogCount:'0',
lofter_single:''
{list a as x}
{if x.moveFrom=='wap'}
{elseif x.moveFrom=='iphone'}
{elseif x.moveFrom=='android'}
{elseif x.moveFrom=='mobile'}
${a.selfIntro|escape}{if great260}${suplement}{/if}
{list a as x}
推荐过这篇日志的人:
{list a as x}
{if !!b&&b.length>0}
他们还推荐了:
{list b as y}
转载记录:
{list d as x}
{list a as x}
{list a as x}
{list a as x}
{list a as x}
{if x_index>4}{break}{/if}
${fn2(x.publishTime,'yyyy-MM-dd HH:mm:ss')}
{list a as x}
{if !!(blogDetail.preBlogPermalink)}
{if !!(blogDetail.nextBlogPermalink)}
{list a as x}
{if defined('newslist')&&newslist.length>0}
{list newslist as x}
{if x_index>7}{break}{/if}
{list a as x}
{var first_option =}
{list x.voteDetailList as voteToOption}
{if voteToOption==1}
{if first_option==false},{/if}&&“${b[voteToOption_index]}”&&
{if (x.role!="-1") },“我是${c[x.role]}”&&{/if}
&&&&&&&&${fn1(x.voteTime)}
{if x.userName==''}{/if}
网易公司版权所有&&
{list x.l as y}
{if defined('wl')}
{list wl as x}{/list}

我要回帖

更多关于 mvc架构 的文章

 

随机推荐