使用NHibernate 3.2实现Repository(ORuM)(二)DDD、Entity、ValueObject、Repository、ORM、NHibernate...

mac2022-06-30  26

领域驱动设计(简称 DDD) 的提出是由Eric Evans在其《Domain-Driven Design –Tackling Complexity in the Heart of Software》(中文译名:领域驱动设计—软件核心复杂性应对之道)一书提出。

领域驱动设计事实上是针对OOAD的一个扩展和延伸,DDD基于面向对象分析与设计技术,对技术架构进行了分层规划,同时对每个类进行了策略和类型的划分。

领域模型是领域驱动的核心。采用DDD的设计思想,业务逻辑不再集中在几个大型的类上,而是由大量相对小的领域对象(类)组成,这些类具备自己的状态和行为,每个类是相对完整的独立体,并与现实领域的业务对象映射。领域模型就是由这样许多的细粒度的类组成。基于领域驱动的设计,保证了系统的可维护性、扩展性和复用性,在处理复杂业务逻辑方面有着先天的优势。

领域驱动设计的分层架构分为四层,其核心就是领域层(Domain),所有的业务逻辑应该在领域层实现,具体描述如下:  用户界面/展现层:负责向用户展现信息以及解释用户命令。   应用层:很薄的一层,用来协调应用的活动。它不包含业务逻辑。它不保留业务对象的状态,但它保有应用任务的进度状态。   领域层:本层包含关于领域的信息。这是业务软件的核心所在。在这里保留业务对象的状态,对业务对象和它们状态的持久化被委托给了基础设施层。   基础设施层:本层作为其他层的支撑库存在。它提供了层间的通信,实现对业务对象的持久化,包含对用户界面层的支撑库等作用。

领域驱动设计除了对系统架构进行了分层描述,还对对象(Object)做了明确的职责和策略划分:   实体(Entity):具备唯一ID,能够被持久化,具备业务逻辑,对应现实世界业务对象。  值对象(Value object):不具有唯一ID,由对象的属性描述,一般为内存中的临时对象,可以用来传递参数或对实体进行补充描述。  工厂(Factory):主要用来创建实体,目前架构实践中一般采用IOC容器来实现工厂的功能。  仓储(Repository):用来管理实体的集合,封装持久化框架。  服务(Service):为上层建筑提供可操作的接口,负责对领域对象进行调度和封装,同时可以对外提供各种形式的服务。 

 

实体基类

EntityBase.cs using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.ComponentModel.DataAnnotations;using MVCQuick.Models;namespace MVCQuick.Framework{public abstract class EntityBase {///<summary>/// ///</summary> public virtual int Id { get; set; }///<summary>/// ///</summary> public virtual int Version{ get; set; }///<summary>/// ///</summary>///<param name="other"></param>///<returns></returns> public override bool Equals(object other) {if (this == other) return true; EntityBase entity = other as EntityBase;if (entity == null) return false; if (!this.GetType().Equals(other.GetType()))return false;if (!Id.Equals(entity.Id)) return false;return true; }///<summary>/// ///</summary>///<returns></returns> public override int GetHashCode() {unchecked {int result; result = this.GetType().GetHashCode(); result = 29 * result + Id.GetHashCode();return result; } } } }

 

值对象接口

IValueObject.cs using System;using System.Collections.Generic;using System.Linq;using System.Web;namespace MVCQuick.Framework{public interface IValueObject { }}

 

实体类

Genre.cs using System;using System.Collections.Generic;using System.Linq;using System.Web;using MVCQuick.Framework;namespace MVCQuick.Models{public class Genre : EntityBase {public virtual string Name { get; set; }public virtual string Description { get; set; }public virtual IEnumerable<Album> Albums { get; set; } }}

 

Artist.cs using System;using System.Collections.Generic;using System.Linq;using System.Web;using MVCQuick.Framework;namespace MVCQuick.Models{public class Artist : EntityBase {public virtual string Name { get; set; }public virtual Address Address { get; set; }public virtual IEnumerable<Album> Albums { get; set; } }}

 

Album.cs using System;using System.Collections.Generic;using System.Linq;using System.Web;using MVCQuick.Framework;namespace MVCQuick.Models{public class Album : EntityBase {public virtual string Title { get; set; }public virtual decimal Price { get; set; }public virtual string AlbumArtUrl { get; set; }public virtual Genre Genre { get; set; }public virtual Artist Artist { get; set; } }}

 

值对象

Address.cs using System;using System.Collections.Generic;using System.Linq;using System.Web;using MVCQuick.Framework;namespace MVCQuick.Models{public class Address : IValueObject {public virtual string City { get; set; }public virtual string Country { get; set; }public virtual string State { get; set; }public virtual string Street { get; set; }public virtual string Zip { get; set; } }}

为每种需要全局访问的对象类型创建一个对象,该对象为该类型所有对象在内存中的集合提供影像。用一个众所周知的全局访问接口来设立访问入口,提供增删对象的方法,把数据存储的实际的插入和删除封装起来。提供根据某种标准率选对象的方法,返回完整实例化了的属性值符合标准对象或对象的集合,把实际的存储和查询技术封装起来。仅为确实需要直接访问的聚合根提供仓储。让客户聚焦于模型,把所有对象存储和访问的工作委托给仓储来完成。

仓储具有许多优点:  它们为客户提供了一个简单的模型,来获取持久对象并管理其生命周期  它们把应用和领域设计从持久技术、多种数据库策略或甚至多种数据库来源解耦出来  它们传达了对象访问的设计决策  它们可以很容易被替换为哑实现,以便在测试中使用(通常使用一个内存中的集合)

仓储接口

ITransaction using System;using System.Collections.Generic;using System.Linq;using System.Web;namespace MVCQuick.Framework.Repository{public interface ITransaction : IDisposable {void Commit();void Rollback(); }}

 

IRepository.cs using System;using System.Collections.Generic;using System.Linq;using System.Web;namespace MVCQuick.Framework.Repository{public interface IRepository<TKey, TEntity> : IDisposable {void Save(TEntity entity);void Update(TEntity entity);void SaveOrUpdate(TEntity entity);void Delete(TEntity entity); TEntity Get(TKey id); IList<TEntity> FindAll(); IList<TEntity> Find(string propertyName, object value); ITransaction BeginTransaction(); }}

ORM(Object/Relation Mapping,对象-关系映射),是随着面向对象的软件开发方法发展而产生的。面向对象的开发方法是当今企业级应用开发环境中的主流开发方法,关系数据库是企业级应用环境中永久存放数据的主流数据存储系统。对象和关系数据是业务实体的两种表现形式,业务实体在内存中表现为对象,在数据库中表现为关系数据。内存中的对象之间存在关联和继承关系,而在数据库中,关系数据无法直接表达多对多关联和继承关系。因此,对象-关系映射(ORM)系统一般以中间件的形式存在,主要实现程序对象到关系数据库数据的映射。

NHibernate 是一个基于.Net 的ORM工具。NHibernate 来源于非常优秀的基于Java的ORM工具——Hibernate。NHibernate不仅仅管理.NET类到数据库表的映射(包括.NET 数据类型到SQL数据类型的映射),还提供数据查询和获取数据的方法,可以大幅度减少开发时人工使用SQL和ADO.NET处理数据的时间。NHibernate的目标是对于开发者通常的数据持久化相关的编程任务,解放其中的95%。对于以数据为中心的程序来说,它们往往只在数据库中使用存储过程来实现商业逻辑,NHibernate可能不是最好的解决方案;对于那些在基于.NET的中间层应用中,它们实现面向对象的业务模型和商业逻辑的应用,NHibernate是最有用的。不管怎样,NHibernate一定可以帮助你消除或者包装那些针对特定厂商的SQL代码,并且帮你把结果集从表格式的表示形式转换到一系列的对象中去。

NHibernate实现仓储

NHibernateRepository.cs using System;using System.Collections.Generic;using System.Linq;using System.Web;using NHibernate;using NHibernate.Criterion;using System.Data;namespace MVCQuick.Framework.Repository.NHibernate{public class NHibernateRepository<TKey, TEntity> : IRepository<TKey, TEntity> where TEntity : class {private ISessionFactory sessionFactory;private ISession session;public NHibernateRepository(ISessionFactory sessionFactory) {this.sessionFactory = sessionFactory;this.session = sessionFactory.OpenSession(); }public NHibernateRepository(ISession session) {this.session = session; }public ISessionFactory SessionFactory {get { return this.sessionFactory; } }public ISession Session {get { return this.session; } }public void Save(TEntity entity) { ISession session = Session; session.Save(entity); session.Flush(); }public void Update(TEntity entity) { ISession session = Session; session.Update(entity); session.Flush(); }public void SaveOrUpdate(TEntity entity) { ISession session = Session; session.SaveOrUpdate(entity); session.Flush(); }public void Delete(TEntity entity) { ISession session = Session; session.Delete(entity); session.Flush(); }public TEntity Get(TKey id) { ISession session = Session;return session.Get<TEntity>(id); }public IList<TEntity> FindAll() { ISession session = Session; ICriteria criteria = session.CreateCriteria(typeof(TEntity));return criteria.List<TEntity>(); }public IList<TEntity> Find(string propertyName, object value) {if (value == null)return Find(Expression.IsNull(propertyName));if (value is string)return Find(Expression.Like(propertyName, value));return Find(Expression.Eq(propertyName, value)); }public IList<TEntity> Find(params ICriterion[] criteria) { ISession session = Session; ICriteria crit = RepositoryHelper<TEntity>.CreateCriteriaFromArray(session, criteria);return crit.List<TEntity>(); }public IList<TEntity> Find(Order[] orders, params ICriterion[] criteria) { ISession session = Session; ICriteria crit = RepositoryHelper<TEntity>.CreateCriteriaFromArray(session, criteria);foreach (Order order in orders) { crit.AddOrder(order); }return crit.List<TEntity>(); }public IList<TEntity> Find(int firstResult, int numberOfResults, Order[] selectionOrder, params ICriterion[] criteria) { ISession session = Session; ICriteria crit = RepositoryHelper<TEntity>.CreateCriteriaFromArray(session, criteria); crit.SetFirstResult(firstResult) .SetMaxResults(numberOfResults);foreach (Order order in selectionOrder) { crit.AddOrder(order); }return crit.List<TEntity>(); }public ITransaction BeginTransaction() { ISession session = Session;return new NHibernateTransaction(session); }private void CloseSession() { session.Close(); session.Dispose(); session = null; }public void Dispose() {if (this.session != null) {this.session.Flush(); CloseSession(); } } }internal class RepositoryHelper<T> {public static ICriteria CreateCriteriaFromArray(ISession session, ICriterion[] criteria) { ICriteria crit = session.CreateCriteria(typeof(T));foreach (ICriterion criterion in criteria) { if (criterion == null)continue; crit.Add(criterion); }return crit; } }}

 

NHibernateTransaction.cs using System;using System.Collections.Generic;using System.Linq;using System.Web;using NH=NHibernate;namespace MVCQuick.Framework.Repository.NHibernate{public class NHibernateTransaction : ITransaction { NH.ITransaction transaction;bool isOriginator = true;public NHibernateTransaction(NH.ISession session) { transaction = session.Transaction;if (transaction.IsActive) isOriginator = false; // The method that first opened the transaction should also close it else transaction.Begin(); }#region ITransaction Memberspublic void Commit() {if(isOriginator && !transaction.WasCommitted && !transaction.WasRolledBack) transaction.Commit(); }public void Rollback() {if (!transaction.WasCommitted && !transaction.WasRolledBack) transaction.Rollback(); }#endregion#region IDisposable Membersvoid IDisposable.Dispose() {if(isOriginator) { Rollback(); transaction.Dispose(); } }#endregion }}

 

转载于:https://www.cnblogs.com/guyoung/archive/2011/10/05/2199404.html

相关资源:JAVA上百实例源码以及开源项目
最新回复(0)