一区二区三区日韩精品-日韩经典一区二区三区-五月激情综合丁香婷婷-欧美精品中文字幕专区

分享

企業(yè)模式之Unit Of Work模式

 ThinkTank_引擎 2015-06-15

  在開始UnitOfWork模式之前有必要回顧下我們耳熟能詳?shù)腄ata Access Object(DAO)模式,即數(shù)據(jù)訪問對象。DAO是一種簡單的模式,我們構(gòu)建應(yīng)用的時候經(jīng)常會使用到它,它的功能就是將DAL元素從應(yīng)用程序中分離出來,在經(jīng)典的三層架構(gòu)中,我們會將數(shù)據(jù)持久化工作單獨(dú)分離出來,封裝成DAL層。但是,DAO并沒有隱藏它面對是一張張數(shù)據(jù)表,而且通常情況我們會為數(shù)據(jù)庫中的每一張表創(chuàng)建一個DAO類,想必大家對這種方式的極度的不爽了,。


     由于DAO模式與數(shù)據(jù)表是一對一匹配的關(guān)系,因此DAO模式很好的配合了Active Record和Transaction Script業(yè)務(wù)模式,尤其是Table Module。正因?yàn)檫@種與數(shù)據(jù)表一對一匹配關(guān)系,使我對DAO模式深惡痛絕。


  Unit Of Work模式,即工作單元,它是一種數(shù)據(jù)訪問模式。它是用來維護(hù)一個由已經(jīng)被業(yè)務(wù)修改(如增加、刪除和更新等)的業(yè)務(wù)對象組成的列表。它負(fù)責(zé)協(xié)調(diào)這些業(yè)務(wù)對象的持久化工作及并發(fā)問題。那它是怎么來維護(hù)的一系列業(yè)務(wù)對象組成的列表持久化工作的呢?通過事務(wù)。Unit Of Work模式會記錄所有對象模型修改過的信息,在提交的時候,一次性修改,并把結(jié)果同步到數(shù)據(jù)庫。 這個過程通常被封裝在事務(wù)中。所以在DAL中采用Unit Of Work模式好處就在于能夠確保數(shù)據(jù)的完整性,如果在持有一系列業(yè)務(wù)對象(同屬于一個事務(wù))的過程中出現(xiàn)問題,就可以將所有的修改回滾,以確保數(shù)據(jù)始終處于有效狀態(tài),不會出現(xiàn)臟數(shù)據(jù)。


  在這里我們,使用一個簡單的銀行領(lǐng)域?qū)蓚€賬號之間的轉(zhuǎn)賬進(jìn)行舉例


     首先如圖進(jìn)行分層搭建基礎(chǔ)框架


     


  總共分為四層依次是:    ---> 引用關(guān)系


  UnitOfWork.Console        --->UnitOfWork.Infrastructure、UnitOfWork.Model、UnitOfWork.Repository


  UnitOfWork.Infrastructure


  UnitOfWork.Model    --->UnitOfWork.Infrastructure


  UnitOfWork.Repository  --->UnitOfWork.Model、UnitOfWork.Infrastructure


  這不是經(jīng)典的領(lǐng)域驅(qū)動架構(gòu),因?yàn)闃I(yè)務(wù)簡單就進(jìn)行簡單搭建。


  UnitOfWork.Infrastructure:


  首先,在UnitOfWork.Infrastructure建了一個Domain文件夾,里面只建了一個IAggregateRoot接口,Unit Of Work操作的實(shí)體必須是實(shí)現(xiàn)IAggregateRoot接口的。


復(fù)制代碼

    /// <summary>
    /// 標(biāo)識接口,定義聚合根
    /// </summary>
    public class IAggregateRoot
    {

    }

復(fù)制代碼

  建立UnitOfWork文件夾,在里面添加一個IUnitOfWorkRepository接口


復(fù)制代碼

    public interface IUnitOfWorkRepository
    {
        //新增
        void PersistCreationOf(IAggregateRoot entity);
        //更新
        void PersistUpdateOf(IAggregateRoot entity);
        //刪除
        void PersistDeletionOf(IAggregateRoot entity);
    }

復(fù)制代碼

  我們再向UnitOfWork文件夾中添加一個IUnitOfWork接口,IUnitOfWork接口在注冊更新、新增和刪除時,需要IUnitOfWorkRepository,這樣再提交Commit,UnitOfWork可以將真正持久化的工作委托給適合的具體實(shí)現(xiàn)對象,其實(shí)就是將持久化工作交給了IUnitOfWorkRepository的實(shí)現(xiàn)類,我們稍后看看IUnitOfWork的實(shí)現(xiàn)類你就清楚了。


復(fù)制代碼

  public interface IUnitOfWork
    {
        /// <summary>
        /// 更新
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="unitofWorkRepository"></param>
        void RegisterUpdate(IAggregateRoot entity, IUnitOfWorkRepository unitofWorkRepository);
        /// <summary>
        /// 新增
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="unitofWorkRepository"></param>
        void RegisterAdd(IAggregateRoot entity, IUnitOfWorkRepository unitofWorkRepository);
        /// <summary>
        /// 刪除
        /// </summary>
        /// <param name="entity"></param>
        /// <param name="unitofWorkRepository"></param>
        void RegisterRemoved(IAggregateRoot entity, IUnitOfWorkRepository unitofWorkRepository);
        /// <summary>
        /// 提交
        /// </summary>
        void Commit();
    }

復(fù)制代碼

  順便說一句,在UnitOfWork.Infrastructure,我還建立的Common文件夾,Logging文件夾,所要表達(dá)的意思是Infrastructure意為基礎(chǔ)設(shè)施層,我們可以將通用的組件放到這里面,比如日志組件,郵件組件等。


      好了,回顧下,我們在UnitOfWork.Infrastructure中其實(shí)什么業(yè)務(wù)都沒有處理,只定義了三個接口。


  UnitOfWork.Model


  接下來,說說這層干了什么事吧!這一層主要是處理兩個賬戶之間轉(zhuǎn)賬的業(yè)務(wù)。


  向UnitOfWork.Model中添加一個Account類,實(shí)現(xiàn)IAggregateRoot接口,表示它是一個聚合根,可以被Unit Of Work操作。


復(fù)制代碼

    /// <summary>
    /// 賬戶類,表示Account是集合根
    /// </summary>
    public class Account : IAggregateRoot
    {
        public Account(decimal balance)
        {
            Balance = balance;
        }
        /// <summary>
        /// 賬戶余額
        /// </summary>
        public decimal Balance { get; set; }
    }

復(fù)制代碼

  為了持久化Account類,我們添加的一個僅包含了示例有關(guān)的的Repository接口,即IAccountRepository,只是簡單的示例。


復(fù)制代碼

    /// <summary>
    /// 定義持久化操作
    /// </summary>
    public interface IAccountRepository
    {
        /// <summary>
        /// 更新
        /// </summary>
        /// <param name="account"></param>
        void Save(Account account);
        /// <summary>
        /// 新增
        /// </summary>
        /// <param name="account"></param>
        void Add(Account account);
        /// <summary>
        /// 刪除
        /// </summary>
        /// <param name="account"></param>
        void Remove(Account account);
    }

復(fù)制代碼

  為了完成轉(zhuǎn)賬的業(yè)務(wù),我們需要創(chuàng)建一個服務(wù)類來協(xié)調(diào)兩個賬戶之間的轉(zhuǎn)賬工作,如AccountService類,在AccountService類中,通過構(gòu)造函數(shù)初始化了IAccountRepository和IUnitOfWork。在完成轉(zhuǎn)賬后,它們都調(diào)用了賬戶Repository進(jìn)行持久化。最后,通過Unit Of Work的Commit來確保該筆交易的完成。


復(fù)制代碼

    public class AccountService
    {
        private IAccountRepository _accountRepository;
        private IUnitOfWork _unitOfWork;

        public AccountService(IAccountRepository accountRepository,
                              IUnitOfWork unitOfWork)
        {
            _accountRepository = accountRepository;
            _unitOfWork = unitOfWork;
        }

        /// <summary>
        /// 轉(zhuǎn)賬
        /// </summary>
        /// <param name="from"></param>
        /// <param name="to"></param>
        /// <param name="amount"></param>
        public void Transfer(Account from, Account to, decimal amount)
        {
            if (from.Balance >= amount)
            {
                from.Balance -= amount;
                to.Balance += amount;

                _accountRepository.Save(from);
                _accountRepository.Save(to);
                _unitOfWork.Commit();
            }
        }
    }

復(fù)制代碼

  總結(jié)下,在UnitOfWork.Model中我們定義的一個Account類,定義了一個持久化Account類的接口,以及轉(zhuǎn)賬業(yè)務(wù)的完成。下面我們要進(jìn)入UnitOfWork.Repository探究Repository和Unit Of Work之間是怎么交互的?


  UnitOfWork.Repository:


  在UnitOfWork.Repository,添加了一個NHUnitOfWork類,實(shí)現(xiàn)了UnitOfWork.Infrastructure.UnitOfWork中的IUnitOfWork接口,為什么定義到這里。因?yàn)樵陧?xiàng)目開發(fā)中你可能有NHbernator的Repository和EF的Repository。還記得我在講解IUnitOfWork接口時,曾說過這樣一句話“IUnitOfWork將持久化工作交給了IUnitOfWorkRepository的實(shí)現(xiàn)類”,在這里你就會找到答案了。


復(fù)制代碼

    public class NHUnitOfWork : IUnitOfWork
    {
        private Dictionary<IAggregateRoot, IUnitOfWorkRepository> addedEntities;
        private Dictionary<IAggregateRoot, IUnitOfWorkRepository> changedEntities;
        private Dictionary<IAggregateRoot, IUnitOfWorkRepository> deletedEntities;

        public NHUnitOfWork()
        {
            addedEntities = new Dictionary<IAggregateRoot, IUnitOfWorkRepository>();
            changedEntities = new Dictionary<IAggregateRoot, IUnitOfWorkRepository>();
            deletedEntities = new Dictionary<IAggregateRoot, IUnitOfWorkRepository>();
        }

        public void RegisterUpdate(IAggregateRoot entity, IUnitOfWorkRepository unitofWorkRepository)
        {
            if (!changedEntities.ContainsKey(entity))
            {
                changedEntities.Add(entity, unitofWorkRepository);
            }
        }

        public void RegisterAdd(IAggregateRoot entity, IUnitOfWorkRepository unitofWorkRepository)
        {
            if (!addedEntities.ContainsKey(entity))
            {
                addedEntities.Add(entity, unitofWorkRepository);
            };
        }

        public void RegisterRemoved(IAggregateRoot entity, IUnitOfWorkRepository unitofWorkRepository)
        {
            if (!deletedEntities.ContainsKey(entity))
            {
                deletedEntities.Add(entity, unitofWorkRepository);
            }
        }

        public void Commit()
        {
            using (TransactionScope scope = new TransactionScope())
            {
                foreach (IAggregateRoot entity in this.addedEntities.Keys)
                {
                    this.addedEntities[entity].PersistCreationOf(entity);
                }

                foreach (IAggregateRoot entity in this.changedEntities.Keys)
                {
                    this.changedEntities[entity].PersistUpdateOf(entity);
                }

                foreach (IAggregateRoot entity in this.deletedEntities.Keys)
                {
                    this.deletedEntities[entity].PersistDeletionOf(entity);
                }

                scope.Complete();
            }
        }

復(fù)制代碼

  接下來,再添加一個AccountRepository類,這個類實(shí)現(xiàn)了兩個接口,IAccountRepository和IUnitOfWorkRepository接口。IAccountRepository中的方法就是簡單得將工作交給了Unit Of Work,傳入待持久化的實(shí)體及Repository(實(shí)現(xiàn)了IUnitOfWorkRepository)引用。最后Unit Of Work 引用Repository的IUnitOfWorkRepository契約來完成真正的持久化工作。


復(fù)制代碼

    public class AccountRepository : IAccountRepository,IUnitOfWorkRepository
    {
        private IUnitOfWork _unitOfWork;

        public AccountRepository(IUnitOfWork unitOfWork)
        {
            _unitOfWork = unitOfWork;
        }

        public void Save(Account account)
        {
            _unitOfWork.RegisterUpdate(account, this);
        }

        public void Add(Account account)
        {
            _unitOfWork.RegisterAdd(account, this);
        }

        public void Remove(Account account)
        {
            _unitOfWork.RegisterRemoved(account, this);
        }

        public void PersistUpdateOf(IAggregateRoot entity)
        {
            // ADO.net code to update the entity...真正的SQL實(shí)現(xiàn)
        }

        public void PersistCreationOf(IAggregateRoot entity)
        {
            // ADO.net code to Add the entity...真正的SQL實(shí)現(xiàn)
        }

        public void PersistDeletionOf(IAggregateRoot entity)
        {
            // ADO.net code to delete the entity...真正的SQL實(shí)現(xiàn)
        }
    }    

復(fù)制代碼

  總結(jié)下,UnitOfWork.Repository這里才是真正糾結(jié)的地方。首先,Unit Of Work加載實(shí)體對象(Accont)和實(shí)體對應(yīng)的Repository對象(AccountRepository);然后通過Unit Of Work的Commit方法,循環(huán)轉(zhuǎn)調(diào)Repository對象(AccountRepository)的持久化方法,進(jìn)行實(shí)體對象(Accont)的持久化工作。多調(diào)試就明白了。


  UnitOfWork.Console:


  接下來,就是最后的控制臺程序了?! ?/p>

復(fù)制代碼

    class Program
    {
        static void Main(string[] args)
        {
            Account a = new Account(1000);
            System.Console.WriteLine("現(xiàn)在張三,存有{0}", a.Balance);
            Account b = new Account(200);
            System.Console.WriteLine("現(xiàn)在李四,存有{0}", b.Balance);
            System.Console.WriteLine("張三準(zhǔn)備轉(zhuǎn)500元給李四,轉(zhuǎn)戰(zhàn)開始了......");

            //聲明要使用的UnitOfWork
            IUnitOfWork nhUnitOfWork = new NHUnitOfWork();

            //聲明要使用的Repository
            IAccountRepository accountRepository = new AccountRepository(nhUnitOfWork);

            AccountService service = new AccountService(accountRepository, nhUnitOfWork);

            service.Transfer(a,b,500);
            System.Console.WriteLine("轉(zhuǎn)賬結(jié)束");
            System.Console.WriteLine("張三當(dāng)前余額:{0}",a.Balance);
            System.Console.WriteLine("李四當(dāng)前余額:{0}",b.Balance);

            System.Console.ReadKey();
        }
    }

復(fù)制代碼

  好了,睡覺了!

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多

    成人精品国产亚洲av久久| 欧美91精品国产自产| 国产日韩欧美国产欧美日韩| 国产日韩精品激情在线观看| 欧美黑人暴力猛交精品| 黄色av尤物白丝在线播放网址| 97人妻精品一区二区三区男同 | 亚洲国产av精品一区二区| 我想看亚洲一级黄色录像| 国产精品欧美一级免费| 日本高清加勒比免费在线| 欧美不卡一区二区在线视频| 日韩精品视频香蕉视频| 五月激情五月天综合网| 高清一区二区三区四区五区| 91日韩欧美中文字幕| 日韩人妻av中文字幕| 91精品日本在线视频| 日本欧美一区二区三区在线播| 国产精品免费视频专区| 婷婷基地五月激情五月| 欧洲亚洲精品自拍偷拍| 色哟哟在线免费一区二区三区| 欧美日韩国产精品自在自线| 亚洲精品偷拍视频免费观看| 亚洲国产黄色精品在线观看| 国产一级精品色特级色国产| 国产乱人伦精品一区二区三区四区 | 好吊视频一区二区在线| 成人午夜激情免费在线| 欧美大胆女人的大胆人体| 亚洲天堂久久精品成人| 老司机激情五月天在线不卡| 激情丁香激情五月婷婷| 国产一级特黄在线观看| 欧洲亚洲精品自拍偷拍| 国产真人无遮挡免费视频一区| 国产欧美精品对白性色| 日本91在线观看视频| 欧美午夜不卡在线观看| 亚洲中文字幕有码在线观看|