欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

DDD分層架構(gòu)之值對象

張軍 3168 0

我對DDD的認(rèn)識雖然還很膚淺,用得也很山寨,但這可能更加適合初步接觸DDD的朋友。還是那句老話,你不是搞學(xué)術(shù)研究的,你并不需要挖掘DDD的學(xué)術(shù)價(jià)值,而是要把它切實(shí)的用到你的項(xiàng)目上,并產(chǎn)生回報(bào)。你不應(yīng)該問對或錯(cuò),而應(yīng)該多看看哪些東西對你真正起作用,一方面需要多學(xué)習(xí)DDD理論知識,另一方面可以多參考其它人的用法,并琢磨出一套適合自己習(xí)慣的架構(gòu)。特別是初學(xué)DDD的朋友,這一點(diǎn)更加重要,DDD水很深,盲目的采用某些你搞不懂的技術(shù),只會增加負(fù)擔(dān)。你也不需要把DDD所有東西都用起來,使用DDD不是為了趕時(shí)髦,如果某些東西讓你感覺復(fù)雜,你先了解下就可以了,把搞懂的東西加入你的工具箱,然后項(xiàng)目上慢慢體驗(yàn),時(shí)間稍長,你就能產(chǎn)生突破并從中受益。但你如果人云亦云,把注意力放到純概念和一些名詞術(shù)語上,把別人的經(jīng)驗(yàn)生搬硬套到自己的項(xiàng)目,由于別人的思想你可能沒有真正搞懂,另外別人的項(xiàng)目需求、團(tuán)隊(duì)水平、所用技術(shù)可能和你都不同,這樣可能導(dǎo)致你維護(hù)了一個(gè)龐大的架構(gòu),但卻沒有撈到一丁點(diǎn)好處。

我這個(gè)系列重點(diǎn)不在DDD,而是如何搭建自己的應(yīng)用程序框架。介紹DDD分層架構(gòu)只是保證本系列的完整性,所以我不會非常詳細(xì)的介紹。另外很多朋友迫切需要示例,我在此回復(fù)一下,本系列前期主要進(jìn)行框架建設(shè),包括一些公共操作類和層超類型,待底子打牢之后,我會向大家展示我的山寨DDD用法,以及如何通過應(yīng)用程序框架快速開發(fā)項(xiàng)目。之所以不上來就搞一堆代碼,是希望你通過這個(gè)系列能真正受益,你不僅需要知道框架怎么用,更需要知道這玩意是怎么弄出來的,以及重要代碼的思考和演化過程。所以我寫得可能非常啰嗦,我希望.Net初學(xué)者也能看懂。我的時(shí)間比較有限,更新時(shí)間不會太快,不過只要有人愿意繼續(xù)看,我會堅(jiān)持寫完它。

下面回到正文上來,本篇將完成DDD值對象的層超類型開發(fā),所有代碼都從網(wǎng)上搜集整理,如果大家有更好的請把你的代碼發(fā)上來供大家參考,另外最好詳細(xì)介紹你的代碼為何更好,以免大家憑空瞎猜。

首先,在Util.Domains類庫中創(chuàng)建一個(gè)名為ValueObjectBase的抽象類。

考慮值對象的相等性測試,怎樣才能認(rèn)為兩個(gè)值對象是相等的?這可以通過比較兩個(gè)值對象的所有屬性值都相等來判斷,換句話說,兩個(gè)值對象有任何一個(gè)屬性值不同,都不相等。我們需要重寫Equals、GetHashCode 、==、!=這幾個(gè)方法或運(yùn)算符。

在相等性比較中,我們可以通過反射來獲取所有屬性,并一一比較,以測試相等性。另外,GetHashCode將各屬性值的哈希碼使用簡單的異或操作計(jì)算出來。如果覺得性能不好,子類可以重寫相關(guān)實(shí)現(xiàn)。

另外,值對象有時(shí)候需要創(chuàng)建一個(gè)副本,可以增加一個(gè)克隆方法Clone,采用淺表復(fù)制進(jìn)行創(chuàng)建,由于值對象不可變,所以不同的值對象共享相同的屬性值就不是什么問題。為了讓Clone更加好用,可以讓它創(chuàng)建出強(qiáng)類型的值對象,而不是一個(gè)object,這需要將值對象層超類型修改為泛型,將值對象作為泛型參數(shù)傳遞到基類。

另外,前面介紹的實(shí)體狀態(tài)輸出和驗(yàn)證方法對值對象同樣適用,所以需要在實(shí)體和值對象層超類型之上再增加一個(gè)基類,命名為DomainBase。

由于值對象層超類型比較簡單,我就簡要介紹到這,下面是相關(guān)代碼,如有疑問請留言。

測試樣例Address類代碼如下,為了簡單,我只留下兩個(gè)屬性。 

namespace Util.Domains.Tests.Samples {

    /// <summary>

    /// 地址

    /// </summary>

    public class Address : ValueObjectBase<Address> {

        /// <summary>

        /// 初始化地址

        /// </summary>

        /// <param name="city">城市</param>

        /// <param name="street">街道</param>

        public Address( string city, string street ) {

            City = city;

            Street = street;

        }


        /// <summary>

        /// 城市

        /// </summary>

        public string City { get; private set; }

        /// <summary>

        /// 街道

        /// </summary>

        public string Street { get; private set; }

    }

}

 


  值對象單元測試類ValueObjectBaseTest代碼如下。


 


using Microsoft.VisualStudio.TestTools.UnitTesting;

using Util.Domains.Tests.Samples;


namespace Util.Domains.Tests {

    /// <summary>

    /// 值對象測試

    /// </summary>

    [TestClass]

    public class ValueObjectBaseTest {

        /// <summary>

        /// 地址1

        /// </summary>

        private Address _address1;

        /// <summary>

        /// 地址2

        /// </summary>

        private Address _address2;

        /// <summary>

        /// 地址3

        /// </summary>

        private Address _address3;


        /// <summary>

        /// 測試初始化

        /// </summary>

        [TestInitialize]

        public void TestInit() {

            _address1 = new Address("a","b");

            _address2 = new Address( "a", "b" );

            _address3 = new Address( "1", "" );

        }


        /// <summary>

        /// 測試對象相等性

        /// </summary>

        [TestMethod]

        public void TestEquals() {

            Assert.IsFalse( _address1.Equals( null ) );

            Assert.IsFalse( _address1 == null );

            Assert.IsFalse( null == _address1 );

            Assert.IsFalse( _address1.Equals(new Test()) );

            Assert.IsTrue( _address1.Equals( _address2 ), "_address1.Equals( _address2 )" );

            Assert.IsTrue( _address1 == _address2, "_address1 == _address2" );

            Assert.IsFalse( _address1 != _address2, "_address1 != _address2" );

            Assert.IsFalse( _address1 == _address3, "_address1 == _address3" );

        }


        /// <summary>

        /// 測試哈希

        /// </summary>

        [TestMethod]

        public void TestGetHashCode() {

            Assert.IsTrue( _address1.GetHashCode() == _address2.GetHashCode(), "_address1.GetHashCode() == _address2.GetHashCode()" );

            Assert.IsFalse( _address1.GetHashCode() == _address3.GetHashCode(), "_address1.GetHashCode() == _address3.GetHashCode()" );

        }


        /// <summary>

        /// 測試克隆

        /// </summary>

        [TestMethod]

        public void TestClone() {

            _address3 = _address1.Clone();

            Assert.IsTrue( _address1 == _address3 );

        }

    }

}

 


  DomainBase代碼如下。


 


using System.Collections.Generic;

using System.Text;

using Util.Validations;


namespace Util.Domains {

    /// <summary>

    /// 領(lǐng)域?qū)禹敿壔?/p>

    /// </summary>

    public abstract class DomainBase {


        #region 構(gòu)造方法


        /// <summary>

        /// 初始化領(lǐng)域?qū)禹敿壔?/p>

        /// </summary>

        protected DomainBase() {

            _rules = new List<IValidationRule>();

            _handler = new ValidationHandler();

        }


        #endregion


        #region 字段


        /// <summary>

        /// 描述

        /// </summary>

        private StringBuilder _description;

        /// <summary>

        /// 驗(yàn)證規(guī)則集合

        /// </summary>

        private readonly List<IValidationRule> _rules;

        /// <summary>

        /// 驗(yàn)證處理器

        /// </summary>

        private IValidationHandler _handler;


        #endregion


        #region ToString(輸出領(lǐng)域?qū)ο蟮臓顟B(tài))


        /// <summary>

        /// 輸出領(lǐng)域?qū)ο蟮臓顟B(tài)

        /// </summary>

        public override string ToString() {

            _description = new StringBuilder();

            AddDescriptions();

            return _description.ToString().TrimEnd().TrimEnd( ',' );

        }


        /// <summary>

        /// 添加描述

        /// </summary>

        protected virtual void AddDescriptions() {

        }


        /// <summary>

        /// 添加描述

        /// </summary>

        protected void AddDescription( string description ) {

            if ( string.IsNullOrWhiteSpace( description ) )

                return;

            _description.Append( description );

        }


        /// <summary>

        /// 添加描述

        /// </summary>

        protected void AddDescription<T>( string name, T value ) {

            if ( string.IsNullOrWhiteSpace( value.ToStr() ) )

                return;

            _description.AppendFormat( "{0}:{1},", name, value );

        }


        #endregion


        #region SetValidationHandler(設(shè)置驗(yàn)證處理器)


        /// <summary>

        /// 設(shè)置驗(yàn)證處理器

        /// </summary>

        /// <param name="handler">驗(yàn)證處理器</param>

        public void SetValidationHandler( IValidationHandler handler ) {

            if ( handler == null )

                return;

            _handler = handler;

        }


        #endregion


        #region AddValidationRule(添加驗(yàn)證規(guī)則)


        /// <summary>

        /// 添加驗(yàn)證規(guī)則

        /// </summary>

        /// <param name="rule">驗(yàn)證規(guī)則</param>

        public void AddValidationRule( IValidationRule rule ) {

            if ( rule == null )

                return;

            _rules.Add( rule );

        }


        #endregion


        #region Validate(驗(yàn)證)


        /// <summary>

        /// 驗(yàn)證

        /// </summary>

        public virtual void Validate() {

            var result = GetValidationResult();

            HandleValidationResult( result );

        }


        /// <summary>

        /// 獲取驗(yàn)證結(jié)果

        /// </summary>

        private ValidationResultCollection GetValidationResult() {

            var result = ValidationFactory.Create().Validate( this );

            Validate( result );

            foreach ( var rule in _rules )

                result.Add( rule.Validate() );

            return result;

        }


        /// <summary>

        /// 驗(yàn)證并添加到驗(yàn)證結(jié)果集合

        /// </summary>

        /// <param name="results">驗(yàn)證結(jié)果集合</param>

        protected virtual void Validate( ValidationResultCollection results ) {

        }


        /// <summary>

        /// 處理驗(yàn)證結(jié)果

        /// </summary>

        private void HandleValidationResult( ValidationResultCollection results ) {

            if ( results.IsValid )

                return;

            _handler.Handle( results );

        }


        #endregion

    }

}

  ValueObjectBase代碼如下。 


using System;

using System.Linq;


namespace Util.Domains {

    /// <summary>

    /// 值對象

    /// </summary>

    /// <typeparam name="TValueObject">值對象類型</typeparam>

    public abstract class ValueObjectBase<TValueObject> : DomainBase, IEquatable<TValueObject> where TValueObject : ValueObjectBase<TValueObject> {


        #region Equals(相等性比較)


        /// <summary>

        /// 相等性比較

        /// </summary>

        public bool Equals( TValueObject other ) {

            return this == other;

        }


        /// <summary>

        /// 相等性比較

        /// </summary>

        public override bool Equals( object other ) {

            return Equals( other as TValueObject );

        }


        #endregion


        #region ==(相等性比較)


        /// <summary>

        /// 相等性比較

        /// </summary>

        public static bool operator ==( ValueObjectBase<TValueObject> valueObject1, ValueObjectBase<TValueObject> valueObject2 ) {

            if ( (object)valueObject1 == null && (object)valueObject2 == null )

                return true;

            if ( (object)valueObject1 == null || (object)valueObject2 == null )

                return false;

            if ( valueObject1.GetType() != valueObject2.GetType() )

                return false;

            var properties = valueObject1.GetType().GetProperties();

            return properties.All( property => property.GetValue( valueObject1 ) == property.GetValue( valueObject2 ) );

        }


        #endregion


        #region !=(不相等比較)


        /// <summary>

        /// 不相等比較

        /// </summary>

        public static bool operator !=( ValueObjectBase<TValueObject> valueObject1, ValueObjectBase<TValueObject> valueObject2 ) {

            return !( valueObject1 == valueObject2 );

        }


        #endregion


        #region GetHashCode(獲取哈希)


        /// <summary>

        /// 獲取哈希

        /// </summary>

        public override int GetHashCode() {

            var properties = GetType().GetProperties();

            return properties.Select( property => property.GetValue( this ) )

                    .Where( value => value != null )

                    .Aggregate( 0, ( current, value ) => current ^ value.GetHashCode() );

        }


        #endregion


        #region Clone(克隆副本)


        /// <summary>

        /// 克隆副本

        /// </summary>

        public virtual TValueObject Clone() {

            return (TValueObject)MemberwiseClone();

        }


        #endregion

    }

}



更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 欧美在线一区二区三区欧美 | 国产精品久久99 | 中文字幕自拍偷拍 | 成人激情综合网 | 国产精品久久久久久久久免费相片 | 日本网站在线播放 | 一区二区三区亚洲 | 国产老女人精品毛片久久 | 小凤仙的故事 电视剧 | jizzjizzjizz亚洲18 | 欧美日韩国产精品一区二区 | 唐人社电亚洲一区二区三区 | 免费黄色片网站 | 色99视频| 国产精品区一区二区三 | 五月天激激婷婷大综合丁香 | 精品永久| 亚洲午夜精品A片久久不卡蜜桃 | 欧美乱妇在线观看 | 亚洲高清资源 | A片A三女人久久7777 | 四虎1515hh海外永久免费在线 | 4hu网站| 久久精品一区 | 狠狠干夜夜操 | 久久狠狠| 国产成人一区二区三区 | 亚洲国产综合精品中文第一区 | 国产片av| 国产精品美女久久久久久久网站 | 国产精品国产精品国产专区不卡 | 国产欧美精品午夜在线播放 | 热久久这里只有精品 | 成人综合网站 | 欧美亚洲福利 | 午夜在线观看视频 | 欧美一级在线观看 | 久久中文字幕久久久久91 | 亚洲精品久久久久久无码AV | 91精品国产免费久久 | 一级大片久久 |