好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

在实际项目中如何应用门面模式(Facade)

在实际项目中如何应用门面模式(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层调用,这个层可以避免界面和数据库的平凡的交互。

 

数据访问层

IRepository.cs 定义数据访问接口

     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 数据访问层采用Nhibernate 实现

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

    }

业务领域层:    IMenuRepository 菜单模块业务领域逻辑

  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> 排除用户没权限的菜单 </remarks>
         ///   </summary>
         ///   <param name="userId"> 用户Id </param>
         ///   <returns></returns>
        IList<MenuNode> GetUserFavoriteList( string  userId);
    }
}
    

 门面层接口:IMenuFacade.cs 此处设计一个抽象的外观类可以方便扩张和需求的变化

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 实现IMenuFacade.cs 对业务逻辑的封装,便于界面的类的调用。

   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 业务领域逻辑具体实现

  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 ;
        }

    }
}

     初学者在学习设计模式的过程中,很难理解设计模式在具体项目中如何应用,我非常喜欢设计模式,设计模式蕴含着软件设计的很重要的思想,真正的要描述设计模式在实际项目中如何运用其实还是比较难的,主要是代码会很多,建议初学者去看一些比较好的源代码,去研究别人的设计思想,这样会有很大的提高。

      门面模式介绍   http://blog.csdn.net/lovelion/article/details/7798064  
 

 

分类:  Nhibernate

标签:  门面模式 ,  Facade

作者: Leo_wl

    

出处: http://www.cnblogs.com/Leo_wl/

    

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

版权信息

查看更多关于在实际项目中如何应用门面模式(Facade)的详细内容...

  阅读:57次