一区二区久久-一区二区三区www-一区二区三区久久-一区二区三区久久精品-麻豆国产一区二区在线观看-麻豆国产视频

領(lǐng)域模型管理與AOP

  英文原文:ASPects of Domain Model Management

  (作者:Mats Helander,譯者:王麗娟)

  2007-12-23

  導(dǎo)言

  正如從像《領(lǐng)域驅(qū)動設(shè)計(jì)》[Evans DDD]和《領(lǐng)域驅(qū)動設(shè)計(jì)和模式應(yīng)用[Nilsson ADDDP]這些書中學(xué)到的一樣,在應(yīng)用架構(gòu)中引入領(lǐng)域模型模式(《企業(yè)應(yīng)用架構(gòu)模式》[Fowler PoEAA])一定會有很多益處,但是它們并不是無代價(jià)的。

  使用領(lǐng)域模型,很少會像創(chuàng)建實(shí)際領(lǐng)域模型類、然后使用它們那么簡單。很快你就會發(fā)現(xiàn),領(lǐng)域模型必須得到相當(dāng)數(shù)量的基礎(chǔ)架構(gòu)代碼的支持。

  領(lǐng)域模型所需基礎(chǔ)架構(gòu)當(dāng)中最顯著的當(dāng)然是持久化——通常是持久化到關(guān)系型數(shù)據(jù)庫中,也就是對象/關(guān)系(O/R)映射出場的地方。但是,情況并不止持久化那么簡單。在一個(gè)復(fù)雜的應(yīng)用中,用來在運(yùn)行時(shí)管理領(lǐng)域模型對象的部分占了基礎(chǔ)架構(gòu)的很大一部分。我將基礎(chǔ)架構(gòu)的這部分稱為領(lǐng)域模型管理(Domain Model Management)[Helander DMM],或簡稱為DMM。

  基礎(chǔ)架構(gòu)代碼放在哪里?

  隨著基礎(chǔ)架構(gòu)代碼的增長,找到一個(gè)處理它的優(yōu)良架構(gòu)變得越來越重要。問題主要在于——我們是否允許把一些基礎(chǔ)架構(gòu)代碼放在我們的領(lǐng)域模型類里面,還是無論如何應(yīng)該避免這樣做?

  避免基礎(chǔ)架構(gòu)代碼進(jìn)入領(lǐng)域模型類的論點(diǎn)是強(qiáng)有力的:領(lǐng)域模型應(yīng)該表示應(yīng)用程序所處理的核心業(yè)務(wù)概念。對于想大量使用其領(lǐng)域模型的應(yīng)用來說,保持這些類干凈、輕量級、易于維護(hù)是一個(gè)極好的架構(gòu)目標(biāo)。

  另一方面,我們接下來將會看到,保持領(lǐng)域模型類完全不含基礎(chǔ)架構(gòu)代碼——通常被稱為使用POJO/POCO(Plain Old Java/CLR Objects)領(lǐng)域模型,這種極端的路線也被證明是有問題的。最終往往導(dǎo)致采用笨重的、低效率的變通方法來解決問題——而且有些功能用這種方式根本不可能實(shí)現(xiàn)。

  也就是說,我們遇到的還是一個(gè)權(quán)衡利弊的情況,我們應(yīng)該盡量在領(lǐng)域模型類里面只放必不可少的基礎(chǔ)架構(gòu)代碼,決不超出這個(gè)限度。我們付出領(lǐng)域模型的輕微發(fā)胖,換來效率的提高以及使一些必要領(lǐng)域模型管理功能有可能實(shí)現(xiàn)。畢竟,軟件架構(gòu)很大程度上是關(guān)于如何做一筆好買賣。

  重構(gòu)的時(shí)機(jī)到了

  不幸的是,長遠(yuǎn)看來,臺面上的交易條件可能不夠好。為了支持許多最有用和最強(qiáng)大的功能,你需要在領(lǐng)域模型類中放入基礎(chǔ)架構(gòu)代碼實(shí)在太多了。其數(shù)量之大,很可能你的系統(tǒng)還沒完成,業(yè)務(wù)邏輯代碼就已經(jīng)被淹沒了。

  也就是說,除非我們能找到一種方法魚和熊掌兼得。本文試圖分析我們能否找到這樣一種方式,既能將必要的基礎(chǔ)架構(gòu)代碼分布到領(lǐng)域模型中,卻又不會使領(lǐng)域模型類變得雜亂。

  我們先從一個(gè)應(yīng)用看起,它將所有有關(guān)的基礎(chǔ)架構(gòu)代碼都放到了領(lǐng)域模型類中。接著我們將重構(gòu)這個(gè)應(yīng)用,并且只用眾所周知的、可靠的、真正面向?qū)ο蟮脑O(shè)計(jì)模式,使應(yīng)用最后能具備相同的功能,但是基礎(chǔ)架構(gòu)代碼卻不會弄亂領(lǐng)域模型類。最后,我們將看看我們?nèi)绾问褂妹嫦蚍矫婢幊蹋?a href=/itjie/ASPjishu/ target=_blank class=infotextkey>ASPect Oriented Programming,AOP)來更簡單地達(dá)到相同的效果。

  但是,為了看出AOP為何能幫助我們處理DMM需求,我們首先看看沒有AOP的時(shí)候我們的代碼會是什么樣——首先是“最原始”的形式,這種形式里,所有的基礎(chǔ)架構(gòu)代碼都放在領(lǐng)域模型類里面,然后是重構(gòu)后的形式,其中基礎(chǔ)架構(gòu)代碼已經(jīng)被分離出領(lǐng)域模型類——雖然仍然分布在領(lǐng)域模型中!

  重構(gòu)肥領(lǐng)域模型

  大部分的領(lǐng)域模型運(yùn)行時(shí)管理是基于攔截的——也就是說,當(dāng)你在代碼中訪問領(lǐng)域模型對象時(shí),你所有對對象的訪問都會根據(jù)相應(yīng)功能的需要被攔截下來。

  一個(gè)明顯的例子就是臟跟蹤(dirty tracking。它可以用于應(yīng)用的很多部分,以了解一個(gè)對象什么時(shí)候已經(jīng)被修改了、但是仍未保存(它處于“臟”狀態(tài))。用戶界面可以利用該信息提醒用戶是否打算放棄任何未保存的修改,而持久化機(jī)制則可以利用它來辨明哪些對象是真正需要被保存到持久化介質(zhì)中的,從而避免保存所有的對象。

  臟跟蹤的一種方法是保持領(lǐng)域?qū)ο笞畛醯摹⑽葱薷陌姹镜目截悾⒃诿看蜗胫酪粋€(gè)對象是否已經(jīng)被修改的時(shí)候去比較它們。這個(gè)方案的問題是既浪費(fèi)內(nèi)存,又慢。一個(gè)更有效率的方法是攔截對領(lǐng)域?qū)ο髎etter方法的調(diào)用,以便每當(dāng)調(diào)用對象的一個(gè)setter方法的時(shí)候,都為該對象設(shè)置一個(gè)臟標(biāo)記。

  臟標(biāo)記放在哪里?

  現(xiàn)在我們來看看把臟標(biāo)記放在哪里的問題。一種是將它放在一個(gè)字典結(jié)構(gòu)中,對象和標(biāo)記分別作為鍵和值。這樣做的問題在于,我們必須讓程序中所有需要它的部分都能訪問到這個(gè)字典。前面的例子已經(jīng)可以看出,需要訪問字典的包括用戶界面和持久化機(jī)制這樣截然不同的部分。


圖 1

  將字典放在這些組件的任何一個(gè)內(nèi)部,都會使其它組件難以訪問它。在分層結(jié)構(gòu)中,底層不能調(diào)用其上層(除了中心領(lǐng)域模型,它常常處于一個(gè)公共的、垂直的層里面,能被其它所有的層調(diào)用),因此要么把字典放在需要訪問它的最低一層(圖1),要么放在公共的、垂直的層里面(圖2)。兩種選擇都不是很有吸引力,因?yàn)樗鹆?a href=/pingce/yingyong/ target=_blank class=infotextkey>應(yīng)用組件間不必要的耦合和不均衡的責(zé)任分配。


圖 2

  一個(gè)更吸引人的、順應(yīng)面向?qū)ο笏枷氲倪x擇,是將臟標(biāo)記放到領(lǐng)域?qū)ο蟊旧碇腥ィ@樣每個(gè)領(lǐng)域?qū)ο蠖紟в幸粋€(gè)布爾型的臟屬性,來表明它是不是臟的(圖3)。這樣,任何組件想知道一個(gè)領(lǐng)域?qū)ο笈K與否,可以直接問它。


圖 3

  因此,我們把部分基礎(chǔ)架構(gòu)功能代碼放在領(lǐng)域模型中,其部分原因就是我們希望從應(yīng)用的不同部分都能擁有這些功能,而不會過度地增強(qiáng)耦合。用戶界面部分不該知道如何向持久化組件詢問臟標(biāo)志,并且,我們寧愿在分層的應(yīng)用架構(gòu)中設(shè)計(jì)盡可能少的垂直層。

  這個(gè)理由很重要,單憑它就足以讓一些人考慮采納本文將要檢驗(yàn)的這種方法,不過我們還是先看看其他方法。但是在這樣做之前,我們先粗略地看一下爭論的另一方——我們在領(lǐng)域模型類中限制基礎(chǔ)架構(gòu)代碼的原因。

  肥領(lǐng)域模型反模式

  讓我們看看,引入臟標(biāo)記、并在適當(dāng)時(shí)機(jī)要求攔截喚醒臟標(biāo)記之后,領(lǐng)域類會是什么樣子。這是一個(gè)C#代碼的例子。

public class Person : IDirty
{
protected string name;
public virtual string Name
{
get { return name; }
set
{
if (value != name)
((IDirty)this).Dirty = true;
name = value;
}
}

private bool dirty;
bool IDirty.Dirty
{
get { return dirty; }
set { dirty = value; }
}
}

public interface IDirty
{
bool Dirty { get; set; }
}

it知識庫領(lǐng)域模型管理與AOP,轉(zhuǎn)載需保留來源!

鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請第一時(shí)間聯(lián)系我們修改或刪除,多謝。

主站蜘蛛池模板: 亚洲激情 欧美 | 4hu最新 | 天天操天天干天天插 | 免费成人福利视频 | 91精品观看91久久久久久 | 四虎网站网址 | 日产精品一区二区免费 | 国产欧美在线观看精品一区二区 | 国产伦精品一区二区三区视频小说 | 一本大道久久a久久综合 | 一级做a爰片性色毛片中国 一级做a爰性色毛片 | 一区二区视频免费看 | 成人嗯啊视频在线观看 | 成人精品视频在线观看播放 | 久久久久这里只有精品 | 五月婷婷六月天 | 在线观看视频一区二区三区 | 成人免费观看黄a大片夜月 成人免费观看视频 | 视频一区二区三区免费观看 | 欧美性xxxx人妖 | 久久精品免费全国观看国产 | 一本伊人| 青草草产国视频 | 久久婷婷午色综合夜啪 | 国产自在线拍 | 欧美一区二区精品 | 日韩久久一区二区三区 | 午夜在线视频免费 | 女人的天堂网 | 在线a亚洲视频播放在线观看 | 日韩中文字幕免费观看 | 91小视频在线观看 | 国产激情小视频 | 国产大片黄在线观看 | 中文字幕佐山爱一区二区免费 | 在线色视频网站 | 婷婷六月激情在线综合激情 | 日本精品久久 | 亚洲国产一区在线二区三区 | 国产精品一页 | 韩国在线观看一区二区三区 |