在实际项目中如何应用门面模式(Facade)
我选择在项目中采用Nhibernate+Spring.Net+Asp.Net + Jquery 来作为我的主要.Net技术,我的框架的设计借鉴了博客园博主 传说中的弘哥博主的大量的技术思路 http://www.cnblogs.com/legendxian/ 结合了自己在实际项目中的经验,下面介绍我选择这套技术的思路和理由:
1.技术选择Nhibernate理由:
对象关系映射技术(ORM)的最主要目的是为了解决关系数据库与面向对象编程技术不匹配的阻抗问题,通常所说的面向对象的类往往都存在继承和类间关系与数据库的表不是—对应的,ORM 技术可屏蔽掉数据库访问的技术细节,让我们更专注于业务和UI实现,另外不能强制要求客户使用固定的数据库产品,Nhibernate 很大程度上屏蔽了不同数据库产品之间差异,使我们不必对不同数据库产品写具体实现,类库设计的原则:高内聚,低耦合。
(1)系统结构类图
1. 数据访问层:
主要用NHibernate访问数据库,但也有可能去访问其他模块或系统的WebService,也有可能用Linq去访问一些缓存(内存中的)数据。
2. 业务领域层:
所有与数据访问无关的业务逻辑都应该内聚在这里,业务领域对象理论上应该是充血的,内聚自己的业务逻辑。但有一些业务逻辑在设计的时候涉及到了多个业务领域对象 ,我们很难决定放在哪个具体的业务对象里,所以我们有一个Service层来放这种业务逻辑。
3. 门面层:
把数据访问接口,业务领域对象的业务逻辑,Service接口简单的封装一下成为Facade层接口供展示层UI或SOA层调用,这个层可以避免界面和数据库的平凡的交互。
数据访问层
{
T Load(string id);
T Get(string id);
IList<T> GetAll();
void SaveOrUpdate(T entity);
void Update(T entity);
void Delete(string id);
void PhysicsDelete(string id);
}
Repository.cs 数据访问层采用Nhibernate 实现
using System;
using System.Linq;
using System.Text;
using Demo.HIS.FrameWork.DomainBase;
using NHibernate;
using NHibernate.Criterion;
using Demo.HIS.FrameWork.Repository.NHb;
namespace Demo.HIS.FrameWork.Repository.Nhb
{
public class RepositoryNhbImpl<T> : IRepository<T> where T : Entity
{
protected virtual ISession Session
{
get { return SessionBuilder.CreateSession(); }
}
#region IRepository<T> 成员
public virtual T Load(string id)
{
try
{
T reslut = Session.Load<T>(id);
if (reslut == null)
throw new RepositoryException("返回实体为空");
else
return reslut;
}
catch (Exception ex)
{
throw new RepositoryException("获取实体失败", ex);
}
}
public virtual T Get(string id)
{
try
{
T reslut = Session.Get<T>(id);
if (reslut == null)
throw new RepositoryException("返回实体为空");
else
return reslut;
}
catch (Exception ex)
{
throw new RepositoryException("获取实体失败", ex);
}
}
public virtual IList<T> GetAll()
{
return Session.CreateCriteria<T>()
.AddOrder(Order.Asc("CreateTime"))
.List<T>();
}
public virtual void SaveOrUpdate(T entity)
{
try
{
Session.SaveOrUpdate(entity);
Session.Flush();
}
catch (Exception ex)
{
throw new RepositoryException("插入实体失败", ex);
}
}
public virtual void Update(T entity)
{
try
{
Session.Update(entity);
Session.Flush();
}
catch (Exception ex)
{
throw new RepositoryException("更新实体失败", ex);
}
}
public virtual void PhysicsDelete(string id)
{
try
{
var entity = Get(id);
Session.Delete(entity);
Session.Flush();
}
catch (System.Exception ex)
{
throw new RepositoryException("物理删除实体失败", ex);
}
}
public virtual void Delete(string id)
{
try
{
var entity = Get(id);
entity.IsDelete = true;
Update(entity);
}
catch (System.Exception ex)
{
throw new RepositoryException("删除实体失败", ex);
}
}
#endregion
}
}
业务领域层: IMenuRepository 菜单模块业务领域逻辑
using System;
using System.Linq;
using System.Text;
namespace Demo.HIS.Infrastructure.Core.Authority.Repositories
{
public interface IMenuRepository : IRepository<MenuNode>
{
bool IsFieldExist(string fieldName, string fieldValue, string id);
IList<MenuNode> GetListByUserId(string userId);
IList<MenuNode> GetListByRoleId(string roleId);
/// <summary>
/// 获取用户常用菜单列表
/// <remarks>排除用户没权限的菜单</remarks>
/// </summary>
/// <param name="userId">用户Id</param>
/// <returns></returns>
IList<MenuNode> GetUserFavoriteList(string userId);
}
}
门面层接口:IMenuFacade.cs 此处设计一个抽象的外观类可以方便扩张和需求的变化
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Demo.HIS.FrameWork;
using Demo.HIS.FrameWork.DomainBase;
using Demo.HIS.Infrastructure.Core.Authority.Repositories;
using Demo.HIS.Infrastructure.Core.Authority;
namespace Demo.HIS.Infrastructure.Facade.Authority
{
public interface IMenuFacade : IDomainFacade
{
IList<MenuNode> GetAlllist();
bool IsFieldExist(string fieldName, string fieldValue, string id);
void SaveOrUpdate(MenuNode entity);
void Delete(string id);
MenuNode Get(string id);
MenuNode Load(string id);
IList<ActionPermission> QueryActionPlist(string query, int start, int limit, out long total);
IList<MenuNode> GetMenuListByRoleId(string roleId);
}
}
MenuFacadeImpl.cs 实现IMenuFacade.cs 对业务逻辑的封装,便于界面的类的调用。
using System;
using System.Linq;
using System.Text;
using Demo.HIS.Infrastructure.Core.Authority.Repositories;
using Demo.HIS.Infrastructure.Core.Authority;
using Demo.HIS.FrameWork.DomainBase;
using Demo.HIS.Infrastructure.Core.Authority.Services;
namespace Demo.HIS.Infrastructure.Facade.Authority.Impl
{
public class MenuFacadeImpl : IMenuFacade
{
private readonly IMenuRepository MenuRepository;
private readonly IActionPermissionService ActionPermissionService;
public MenuFacadeImpl(IMenuRepository MenuRepository, IActionPermissionService ActionPermissionService)
{
this.MenuRepository = MenuRepository;
this.ActionPermissionService = ActionPermissionService;
}
#region IMenuFacade 成员
public IList<MenuNode> GetAlllist()
{
return MenuRepository.GetAll();
}
public bool IsFieldExist(string fieldName, string fieldValue, string id)
{
return MenuRepository.IsFieldExist(fieldName, fieldValue, id);
}
public void SaveOrUpdate(MenuNode entity)
{
MenuRepository.SaveOrUpdate(entity);
}
public void Delete(string id)
{
MenuRepository.Delete(id);
}
public MenuNode Get(string id)
{
return MenuRepository.Get(id);
}
public MenuNode Load(string id)
{
return MenuRepository.Load(id);
}
public IList<ActionPermission> QueryActionPlist(string query, int start, int limit, out long total)
{
return ActionPermissionService.QueryActionPlist(query,start,limit,out total);
}
public IList<MenuNode> GetMenuListByRoleId(string roleId)
{
return MenuRepository.GetListByRoleId(roleId);
}
#endregion
}
}
MenuRepositoryImpl.cs 业务领域逻辑具体实现
using System;
using System.Linq;
using System.Text;
using Demo.HIS.Infrastructure.Core.Authority.Repositories;
using Demo.HIS.Infrastructure.Core.Authority;
using Demo.HIS.FrameWork.Repository;
using Demo.HIS.FrameWork;
using Demo.HIS.FrameWork.DomainBase;
using Demo.HIS.FrameWork.Repository.Nhb;
namespace Demo.HIS.Infrastructure.Repositories.Authority
{
public class MenuRepositoryImpl : RepositoryNhbImpl<MenuNode>, IMenuRepository
{
public override void SaveOrUpdate(MenuNode entity)
{
if (IsFieldExist("TreeCode", entity.TreeCode, entity.Id, null))
throw new ExistException("TreeCode");
base.SaveOrUpdate(entity);
}
public override void Delete(string id)
{
var entity = Get(id);
if (IsChildForNotLeaf(id))
throw new ValidationException("所选项下面存在子项,无法删除!");
base.Delete(id);
}
#region IMenuRepository 成员
public bool IsFieldExist(string fieldName, string fieldValue, string id)
{
return base.IsFieldExist(fieldName, fieldValue, id, null);
}
public IList<MenuNode> GetListByUserId(string userId)
{
var query = Session.CreateQuery(@"select distinct t
from MenuNode as t
left join t.Roles as r
left join r.Persons p
where p.Id = :UserId and r.IsDelete = 0 and p.IsDelete = 0 and p.State = :PersonState and r.State=:RoleState order by t.Index asc")
.SetString("UserId", userId)
.SetEnum("PersonState", PersonState.Normal)
.SetEnum("RoleState", RoleState.Normal);
return query.List<MenuNode>();
}
public IList<MenuNode> GetListByRoleId(string roleId)
{
var query = Session.CreateQuery(@"select distinct t
from MenuNode as t
left join t.Roles as r
where r.Id = :RoleId and r.IsDelete = 0 and r.State = :RoleState")
.SetString("RoleId", roleId)
.SetEnum("RoleState", RoleState.Normal);
return query.List<MenuNode>();
}
public IList<MenuNode> GetUserFavoriteList(string userId)
{
var query = Session.CreateQuery(@"select distinct t
from MenuNode as t
left join t.FavoritedUsers u
left join u.Roles ur
where u.Id = :UserId and u.IsDelete = 0 and ur.IsDelete = 0 and u.State = :PersonState and ur.State = :RoleState
and exists (select m from MenuNode as m
left join m.Roles as mr
where mr.Id = ur.Id and t.Id = m.Id
and mr.IsDelete = 0 and mr.State = :RoleState)")
.SetString("UserId", userId)
.SetEnum("PersonState", PersonState.Normal)
.SetEnum("RoleState", RoleState.Normal);
return query.List<MenuNode>();
}
#endregion
private bool IsChildForNotLeaf(string id)
{
var query = Session.CreateQuery(@"select count(*) from MenuNode as o where o.ParentId=:ParentId")
.SetString("ParentId", id);
return query.UniqueResult<long>() > 0;
}
}
}
初学者在学习设计模式的过程中,很难理解设计模式在具体项目中如何应用,我非常喜欢设计模式,设计模式蕴含着软件设计的很重要的思想,真正的要描述设计模式在实际项目中如何运用其实还是比较难的,主要是代码会很多,建议初学者去看一些比较好的源代码,去研究别人的设计思想,这样会有很大的提高。
门面模式介绍 http://blog.csdn.net/lovelion/article/details/7798064
转载于:https://www.cnblogs.com/binb/archive/2012/08/05/zoubin_Nhibernate.html
在实际项目中如何应用门面模式(Facade)相关推荐
- 外观模式 门面模式 Facade 结构型 设计模式(十三)
外观模式(FACADE) 又称为门面模式 意图 为子系统中的一组接口提供一个一致的界面 Facade模式定义了一个高层接口,这一接口使得这一子系统更加易于使用. 意图解析 随着项目的持续发展,系统基本 ...
- .net 有哪些主流的设计模式_「设计模式自习室」门面模式 Facade Pattern
前言 <设计模式自习室>系列,顾名思义,本系列文章带你温习常见的设计模式.主要内容有: 该模式的介绍,包括: 引子.意图(大白话解释) 类图.时序图(理论规范) 该模式的代码示例:熟悉该模 ...
- 【设计模式自习室】门面模式 Facade Pattern
前言 <设计模式自习室>系列,顾名思义,本系列文章带你温习常见的设计模式.主要内容有: 该模式的介绍,包括: 引子.意图(大白话解释) 类图.时序图(理论规范) 该模式的代码示例:熟悉该模 ...
- 大熊君说说JS与设计模式之(门面模式Facade)迪米特法则的救赎篇------(监狱的故事)...
一,总体概要 1,笔者浅谈 说起"门面"这个设计模式其实不论新老程序猿都是在无意中就已经运用到此模式了,就像我们美丽的JS程序员一样不经意就使用了闭包处理问题, 1 functio ...
- c++ 门面模式(Facade)
门面模式是比较常用的一种设计模式,我们可能在无意中就会使用,门面模式就是用一个门面类来处理子系统的复杂关系,门面类简单的Api接口供客户端调用.用一个简单的演播室来表示. #include <i ...
- 门面模式(Facade)
门面模式说明 它能将多个不同的子系统接口封装起来,并对外提供统一的高层接口,使复杂的子系统变得更易使用 为了达到高效.便捷的目的,门店会统一对子系统进行整合与调度 外观门面类内部封装了大量的子系统资源 ...
- 门面模式:Facade(转自阿良.NET)
外部与一个子系统的通信必须通过一个统一的门面(Facade)对象进行,这就是门面模式. 医院的例子 用一个例子进行说明,如果把医院作为一个子系统,按照部门职能,这个系统可以划分为挂号.门诊.划价.化验 ...
- 门面模式Facade
完整设计模式目录见:https://blog.csdn.net/u013523089/article/details/82852049 门面模式:将一个固化的流程进行封装,使对外提供的方法更简单 将一 ...
- 设计模式(八): 从“小弟”中来类比外观模式(Facade Pattern)
在此先容我拿"小弟"这个词来扯一下淡.什么是小弟呢,所谓小弟就是可以帮你做一些琐碎的事情,在此我们就拿"小弟"来类比"外观模式".在上面一篇 ...
最新文章
- 大数相乘--极简单的思路
- 使用花生壳自己架设网站:路由器后
- 深圳市收运体系运营管理_房地产企业如何搭建运营管理体系
- java源码阅读LinkedList
- c++实现多态的方法 虚表
- Codeforces 803E--Roma and Poker (DP)
- 多个页面同时跳转到一个页面,然后返回到上级页面
- 【javascript动画系列之网页白板】javascript实现的白板(兼容ff,ie,chrome,……)
- 曲线聚类_R语言确定聚类的最佳簇数:3种聚类优化方法
- 前端学习与“IT界大佬告诉你,程序员接私活的7大平台利器”
- Ruby的Fiber根本不是用来做并发的~
- _DEVOBJ_EXTENSION结构体
- Kotlint集合简单总结
- SpreadJS 15.2.3 黄金十月美好版
- 分享超好用的截动图工具ScreenToGif
- Effective Java目录
- 【Tinking in Java摘录笔记】第六章 初始化和清理
- Linux下如何聊天-irc,MSN,ICQ,QQ你会用了吗?
- android加载.swf flash文件
- java1.8final_你以为你真的了解final吗?
热门文章
- java自定义注解解析及自定义注解
- Hi3516A开发--RTC电路
- 初识Frida--Android逆向之Java层hook (二)
- JZOJ 5415. 【NOIP2017提高A组集训10.22】公交运输
- sql增删改查_快速搞定数据库增删改查|附思维导图
- stk 坐标系_STK中文用户手册.pdf
- 算法心经:数学的应用:概率的应用
- 数学之美 系列十六 (下)- 不要把所有的鸡蛋放在一个篮子里 最大熵模型
- USACO 3.1 Agri-Net 最短网络 (最小生成树)(普里姆算法)
- 不断注册账号能挤满对方服务器吗,为什么不能注册啊