工作单元模式

   最近趁过年期间上网了解一些设计模式,无意中看到工作单元模式,眼睛一亮,之前的项目怎么就不懂用到这个模式呢?后悔不已,进园这么久也没留下什么,今天抽空写篇博文好好说说工作单元模式,在项目中的运用,它的好处还有自己的几个疑点。

   什么是工作单元模式呢?术语上解释为:维护一个受业务事务影响的对象列表,并协调写入更改内容和并发问题的解决方案。

  举个简单例子,有2张表,一张是文章类别表,一张是文章表,文章表中有一个外键对应着文章类别表ID,现在有个业务删除某个类别的同时需要删除该类别下的文章,我们可以把这个业务看成一个工作单元,在该工作单元下分别有2个步骤,第一删除该类别下的所有文章,第二在类别表中删除该类。就在这时意外出现了,在执行第一步操作的时候程序运行正常,非常perfection,但是在执行第二步骤的时候出现荡机,数据库崩溃了或者其他的意外,第二步并没执行!大家会觉得处理这种情况直接加一个事务来处理不就行了,出现意外直接回滚,也确实如此,但是大量的数据增删改操作中,我们没办法对每一个操作进行事务处理,除了给编码增加负担外,有些操作也没必要这么处理,而且在大量的数据操作中,很容易出现并发的问题,而这个工作单元模式就可以很有效的改良此问题。

    工作单元需要知道应该跟踪哪个对象,在这里需要先明白2个基本方法,调用者注册(对象的用户必须记得注册到工作单元),对象注册(对象把自身注册到工作单元)

    OK! 直接上源码

 

先写一个工作单元接口 里面有注册添加  更改 删除  和把所有已经注册的数据进行提交 的Commit操作

这里有2个参数 第一个object 即为要跟踪的对象 这里可以是数据实体。

第二个参数工作单元的一个数据操作接口 每个对象所对应的仓储需继承并实现其方法。

代码
using System;
namespace UnitOfWork
{
publicinterface IUnitOfWork
{
void RegisterAdded(object entity, IUnitOfWorkRepository repository);
void RegisterChanged(object entity, IUnitOfWorkRepository repository);
void RegisterRemoved(object entity, IUnitOfWorkRepository repository);
void Commit();
}
}

仓储操作接口

代码
using System;


namespace UnitOfWork
{
publicinterface IUnitOfWorkRepository
{
void NewItem(object item);
void UpdatedItem(object item);
void DeletedItem(object item);
}
}

之后建UnitOfWork.cs 文件实现该IUnitOfWork类 这里用TransactionScope 来实现事务的处理,用 字典来缓存注册的信息

代码
using System;
using System.Collections.Generic;
using System.Transactions;
namespace UnitOfWork
{
publicclass UnitOfWork : IUnitOfWork
{
private Dictionary<object, IUnitOfWorkRepository> addedEntities;
private Dictionary<object, IUnitOfWorkRepository> changedEntities;
private Dictionary<object, IUnitOfWorkRepository> deletedEntities;

///<summary>
/// 实例化工作单元
///</summary>
public UnitOfWork()
{
this.addedEntities =new Dictionary<object,
IUnitOfWorkRepository
>();
this.changedEntities =new Dictionary<object,
IUnitOfWorkRepository
>();
this.deletedEntities =new Dictionary<object,
IUnitOfWorkRepository
>();
}

#region IUnitOfWork 方法

///<summary>
/// 注册添加操作
///</summary>
///<param name="entity"></param>
///<param name="repository"></param>
publicvoid RegisterAdded(object entity, IUnitOfWorkRepository repository)
{
this.addedEntities.Add(entity, repository);
}
///<summary>
/// 注册更改操作
///</summary>
///<param name="entity"></param>
///<param name="repository"></param>
publicvoid RegisterChanged(object entity, IUnitOfWorkRepository repository)
{
this.changedEntities.Add(entity, repository);
}
///<summary>
/// 注册删除操作
///</summary>
///<param name="entity"></param>
///<param name="repository"></param>
publicvoid RegisterRemoved(object entity, IUnitOfWorkRepository repository)
{
this.deletedEntities.Add(entity, repository);
}

///<summary>
/// 执行内存列表保存的操作
///</summary>
publicvoid Commit()
{
using (TransactionScope scope =new TransactionScope())
{
foreach (object entity inthis.deletedEntities.Keys)
{
this.deletedEntities[entity].DeletedItem(entity);
}

foreach (object entity inthis.addedEntities.Keys)
{
this.addedEntities[entity].NewItem(entity);
}

foreach (object entity inthis.changedEntities.Keys)
{
this.changedEntities[entity].UpdatedItem(entity);
}

scope.Complete();
}

this.deletedEntities.Clear();
this.addedEntities.Clear();
this.changedEntities.Clear();
}

#endregion
}
}

框架都搭好之后 我们建一个TestRepository.cs 测试的仓储 继承IUnitOfWorkRepository

代码
using System;
using System.Collections.Generic;


namespace UnitOfWork
{
publicclass TestRepository : IUnitOfWorkRepository
{
private IUnitOfWork unitOfWork;
private IUnitOfWork TestUnitOfWork
{
get { returnthis.unitOfWork; }
}

public TestRepository(IUnitOfWork unitOfWork)
{
this.unitOfWork = unitOfWork;

}
publicvoid Add(object _object)
{
TestUnitOfWork.RegisterAdded( _object,
this);

Console.WriteLine(
"注册添加数据"+ _object);

}
publicvoid Delete(object _object)
{
TestUnitOfWork.RegisterRemoved(_object,
this);
Console.WriteLine(
"注册删除数据"+ _object);
}
publicvoid update(object _object)
{
TestUnitOfWork.RegisterChanged(_object,
this);
Console.WriteLine(
"注册更新数据"+ _object);
}


publicvoid NewItem(object _object)
{
Console.WriteLine(
"执行添加数据"+ _object);
}

publicvoid UpdatedItem(object _object)
{
Console.WriteLine(
"执行更新数据"+ _object);
}

publicvoid DeletedItem(object _object)
{
Console.WriteLine(
"执行删除数据"+ _object);
}
}
}

现在一切准备就绪 当然不能直接用仓储给外部调用 这里要添加个Server层

代码
using System;
using System.Collections.Generic;


namespace UnitOfWork
{
publicclass TestServer
{
privatestatic IUnitOfWork unitOfWork;
privatestatic TestRepository _TestRepository;
static TestServer()
{
TestServer.unitOfWork
=new UnitOfWork();
_TestRepository
=new TestRepository(unitOfWork);

}
publicstaticvoid Add()
{
_TestRepository.Add(
1);
_TestRepository.Add(
2);
_TestRepository.Add(
3);
_TestRepository.Add(
4);
_TestRepository.Add(
5);
unitOfWork.Commit();
}

publicstaticvoid Add(object _object)
{
_TestRepository.Add(_object);
_TestRepository.Delete(_object);
_TestRepository.update(_object);
unitOfWork.Commit();

}
publicstaticvoid Delete(object _object)
{
_TestRepository.Delete(_object);
unitOfWork.Commit();
}
publicstaticvoid Update(object _object)
{
_TestRepository.update(_object);
unitOfWork.Commit();
}

}
}

 这个是调用方式

代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using UnitOfWork;
namespace ConsoleApplication1
{
class Program
{
staticvoid Main(string[] args)
{
TestServer.Add(
1);
Console.WriteLine(
"----------------------------");
TestServer.Add();
Console.Read();
}
}
}

 

posted @ 2011-02-10 10:21  杨光远  阅读(3625)  评论(5)    收藏  举报