在实际项目中如何应用门面模式(Facade)
? ? ? 我選擇在項目中采用Nhibernate+Spring.Net+Asp.Net + Jquery 來作為我的主要.Net技術(shù),我的框架的設(shè)計借鑒了博客園博主 傳說中的弘哥博主的大量的技術(shù)思路?http://www.cnblogs.com/legendxian/?結(jié)合了自己在實際項目中的經(jīng)驗,下面介紹我選擇這套技術(shù)的思路和理由:
? ? ? 1.技術(shù)選擇Nhibernate理由:
? ? ? 對象關(guān)系映射技術(shù)(ORM)的最主要目的是為了解決關(guān)系數(shù)據(jù)庫與面向?qū)ο缶幊碳夹g(shù)不匹配的阻抗問題,通常所說的面向?qū)ο蟮念愅即嬖诶^承和類間關(guān)系與數(shù)據(jù)庫的表不是—對應(yīng)的,ORM 技術(shù)可屏蔽掉數(shù)據(jù)庫訪問的技術(shù)細(xì)節(jié),讓我們更專注于業(yè)務(wù)和UI實現(xiàn),另外不能強(qiáng)制要求客戶使用固定的數(shù)據(jù)庫產(chǎn)品,Nhibernate 很大程度上屏蔽了不同數(shù)據(jù)庫產(chǎn)品之間差異,使我們不必對不同數(shù)據(jù)庫產(chǎn)品寫具體實現(xiàn),類庫設(shè)計的原則:高內(nèi)聚,低耦合。?
(1)系統(tǒng)結(jié)構(gòu)類圖
?1. 數(shù)據(jù)訪問層:
? ? ?主要用NHibernate訪問數(shù)據(jù)庫,但也有可能去訪問其他模塊或系統(tǒng)的WebService,也有可能用Linq去訪問一些緩存(內(nèi)存中的)數(shù)據(jù)。
?2. 業(yè)務(wù)領(lǐng)域?qū)?#xff1a;
? ? ?所有與數(shù)據(jù)訪問無關(guān)的業(yè)務(wù)邏輯都應(yīng)該內(nèi)聚在這里,業(yè)務(wù)領(lǐng)域?qū)ο罄碚撋蠎?yīng)該是充血的,內(nèi)聚自己的業(yè)務(wù)邏輯。但有一些業(yè)務(wù)邏輯在設(shè)計的時候涉及到了多個業(yè)務(wù)領(lǐng)域?qū)ο?,我們很難決定放在哪個具體的業(yè)務(wù)對象里,所以我們有一個Service層來放這種業(yè)務(wù)邏輯。
?3. 門面層:
? ? ?把數(shù)據(jù)訪問接口,業(yè)務(wù)領(lǐng)域?qū)ο蟮臉I(yè)務(wù)邏輯,Service接口簡單的封裝一下成為Facade層接口供展示層UI或SOA層調(diào)用,這個層可以避免界面和數(shù)據(jù)庫的平凡的交互。
?
數(shù)據(jù)訪問層
IRepository.cs 定義數(shù)據(jù)訪問接口 public?interface?IRepository<T>?where?T:Entity
????{
????????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 數(shù)據(jù)訪問層采用Nhibernate 實現(xiàn)
?
using?System;
using?System.Collections.Generic;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
????}
}?
?
?
?
業(yè)務(wù)領(lǐng)域?qū)?#xff1a;???IMenuRepository 菜單模塊業(yè)務(wù)領(lǐng)域邏輯
?using?System;
using?System.Collections.Generic;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>排除用戶沒權(quán)限的菜單</remarks>
????????///?</summary>
????????///?<param?name="userId">用戶Id</param>
????????///?<returns></returns>
????????IList<MenuNode>?GetUserFavoriteList(string?userId);
????}
}
? ??
?門面層接口:IMenuFacade.cs 此處設(shè)計一個抽象的外觀類可以方便擴(kuò)張和需求的變化
using?System;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 實現(xiàn)IMenuFacade.cs 對業(yè)務(wù)邏輯的封裝,便于界面的類的調(diào)用。
??using?System;
using?System.Collections.Generic;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?業(yè)務(wù)領(lǐng)域邏輯具體實現(xiàn)
?
?using?System;
using?System.Collections.Generic;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;
????????}
????}
}
?
? ? ?初學(xué)者在學(xué)習(xí)設(shè)計模式的過程中,很難理解設(shè)計模式在具體項目中如何應(yīng)用,我非常喜歡設(shè)計模式,設(shè)計模式蘊(yùn)含著軟件設(shè)計的很重要的思想,真正的要描述設(shè)計模式在實際項目中如何運用其實還是比較難的,主要是代碼會很多,建議初學(xué)者去看一些比較好的源代碼,去研究別人的設(shè)計思想,這樣會有很大的提高。
? ? ? 門面模式介紹 ?http://blog.csdn.net/lovelion/article/details/7798064?
?
?
轉(zhuǎn)載于:https://www.cnblogs.com/binb/archive/2012/08/05/zoubin_Nhibernate.html
總結(jié)
以上是生活随笔為你收集整理的在实际项目中如何应用门面模式(Facade)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: splunk 实例
- 下一篇: hdu 4109 Instrction