日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

大话设计模式(十三 有了门面,程序员的程序会更加体面!)

發(fā)布時(shí)間:2025/3/21 asp.net 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 大话设计模式(十三 有了门面,程序员的程序会更加体面!) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

小菜編程成長記(十三 有了門面,程序員的程序會更加體面!)

(續(xù)上篇)
??????? 大鳥說道:“實(shí)際上沒有學(xué)過設(shè)計(jì)模式去理解三層架構(gòu)會有失偏頗的,畢竟分層是更高一級別的模式,所謂的架構(gòu)模式。不過在程序中,有意識的遵循設(shè)計(jì)原則,卻也可以有效的做出好的設(shè)計(jì)。”
????? “不要告訴我,剛才講的‘迪米特法則’就會在分層中用得上?”小菜說。
???? “當(dāng)然用得上,否則講它干嗎,你當(dāng)我是在安慰你而臨時(shí)編個(gè)法則來騙騙你呀?來,再來看看你上次寫的代碼。”

private void Form1_Load(object sender, EventArgs e)2 {3 //讀配置文件4 ds = new DataSet();5 ds.ReadXml(Application.StartupPath + "\\CashAcceptType.xml");6 //將讀取到的記錄綁定到下拉列表框中7 foreach (DataRowView dr in ds.Tables[0].DefaultView)8 {9 cbxType.Items.Add(dr["name"].ToString()); 10 } 11 cbxType.SelectedIndex = 0; 12 }
? ?“這是Form_Load的代碼,里面有沒有什么與界面無關(guān)的東西?”大鳥問道。

?????? “第4、5行是讀配置文件的代碼,它應(yīng)該屬于DAL層。對吧?”
????? “很好,再看下面的這段,里面又有哪些呢?”

?1????????private?void?btnOk_Click(object?sender,?EventArgs?e)
?2????????{
?3????????????CashContext?cc?=?new?CashContext();
?4????????????//根據(jù)用戶的選項(xiàng),查詢用戶選擇項(xiàng)的相關(guān)行
?5????????????DataRow?dr?=?((DataRow[])ds.Tables[0].Select("name='"?+?cbxType.SelectedItem.ToString()+"'"))[0];
?6????????????//聲明一個(gè)參數(shù)的對象數(shù)組
?7????????????object[]?args?=null;
?8????????????//若有參數(shù),則將其分割成字符串?dāng)?shù)組,用于實(shí)例化時(shí)所用的參數(shù)
?9????????????if?(dr["para"].ToString()?!=?"")
10????????????????args?=?dr["para"].ToString().Split(',');
11????????????//通過反射實(shí)例化出相應(yīng)的算法對象
12????????????cc.setBehavior((CashSuper)Assembly.Load("商場管理軟件").CreateInstance("商場管理軟件."?+?dr["class"].ToString(),?
13????????????????????????????????false,?BindingFlags.Default,?null,?args,?null,?null));
14????????????
15????????????double?totalPrices?=?0d;
16????????????totalPrices?=?cc.GetResult(Convert.ToDouble(txtPrice.Text)?*?Convert.ToDouble(txtNum.Text));
17????????????total?=?total?+?totalPrices;
18????????????lbxList.Items.Add("單價(jià):"?+?txtPrice.Text?+?"?數(shù)量:"?+?txtNum.Text?+?"?"+cbxType.SelectedItem+?"?合計(jì):"?+?totalPrices.ToString());
19????????????lblResult.Text?=?total.ToString();
20????????}

???? “這里3-13行,是為確定哪種算法而創(chuàng)建CashContext對象,其中用到了反射技術(shù),為計(jì)算做準(zhǔn)備。第16行是真正的計(jì)算打折價(jià)或返利,17-19是界面顯示的部分。所以應(yīng)該把3-16行都搬到BLL層去。不過,我還有些疑問,這樣做會讓配置文件的數(shù)據(jù)要先從DAL轉(zhuǎn)到BLL,再轉(zhuǎn)到表示層,多麻煩呀,什么不直接表示層讀DAL,它想要數(shù)據(jù)就去讀DAL,它想算結(jié)果就去請求BLL處理?”
???? “那是說明你沒有真的了解什么叫迪米特法則,象你那樣說,不就等于,你小菜又要認(rèn)識小張,又要認(rèn)識小李了,這不就耦合過度嗎?本來你只需要認(rèn)識一個(gè)人就可以了,這樣依賴才會小呀!”
???? “可是我就得在BLL里寫一個(gè)專門返回從DAL里得到數(shù)據(jù)的方法,這個(gè)方法不屬于現(xiàn)在的任何類,我就還得再寫一個(gè)類來做這種傳聲筒的角色。而且由于界面還要涉及到其它的類,如CashContext,感覺UI和BLL耦合還是很高。”
???? “說得沒錯(cuò),你的確是講到點(diǎn)子上了,由于表示層UI需要與BLL有兩個(gè)類進(jìn)行交互,這是很麻煩,不過前輩們就想了了一個(gè)較好的辦法,另一個(gè)設(shè)計(jì)模式,‘門面模式’(Facade)或叫外觀模式”

(以下源自呂震宇?博客)
門面模式要求一個(gè)子系統(tǒng)的外部與其內(nèi)部的通信必須通過一個(gè)統(tǒng)一的門面(Facade)對象進(jìn)行。門面模式提供一個(gè)高層次的接口,使得子系統(tǒng)更易于使用。?

門面模式的結(jié)構(gòu)

門面模式是對象的結(jié)構(gòu)模式。門面模式?jīng)]有一個(gè)一般化的類圖描述,下圖演示了一個(gè)門面模式的示意性對象圖:

?

?

在這個(gè)對象圖中,出現(xiàn)了兩個(gè)角色:

門面(Facade)角色:客戶端可以調(diào)用這個(gè)角色的方法。此角色知曉相關(guān)的(一個(gè)或者多個(gè))子系統(tǒng)的功能和責(zé)任。在正常情況下,本角色會將所有從客戶端發(fā)來的請求委派到相應(yīng)的子系統(tǒng)去。

子系統(tǒng)(subsystem)角色:可以同時(shí)有一個(gè)或者多個(gè)子系統(tǒng)。每一個(gè)子系統(tǒng)都不是一個(gè)單獨(dú)的類,而是一個(gè)類的集合。每一個(gè)子系統(tǒng)都可以被客戶端直接調(diào)用,或者被門面角色調(diào)用。子系統(tǒng)并不知道門面的存在,對于子系統(tǒng)而言,門面僅僅是另外一個(gè)客戶端而已。

?????? “哦,你這樣一講,我就明白了。”小菜說,“上篇所講的IT部,其實(shí)可以由部門主管就是門面,我們只需要找到部門主管,就可以通過他安排相關(guān)的人來提供服務(wù),我們不需要了解IT部的具體情況了。”
?????? “其實(shí)現(xiàn)實(shí)中這樣的例子很多。比如以前上海市沒有新聞發(fā)言人,當(dāng)要到春運(yùn)時(shí),所有的記者都跑到交通部去了解信息,當(dāng)有非典或禽流感時(shí),所有的記者又跑到衛(wèi)生部去打聽情況,突然這時(shí)候樓市大跌,記者們又得馬不停蹄前往建設(shè)部收集新聞。辛苦呀,有什么辦法呢,吃這口飯的。但其實(shí)辛苦地又何止只是記者。各個(gè)政府部門都需要專人來應(yīng)付這些記者,不能多說話,不能說錯(cuò)話,但也不能不說話。也辛苦呀,誰叫他們是政府呢。”大鳥仿佛自己感同身受似的描述著,“于是,新聞發(fā)言人橫空出世,一位知識女性焦揚(yáng),代表上海市政府發(fā)言,從此,老記們不需要頭頂驕陽奔跑于各大政府部門之間,只需要天天等在新聞發(fā)言廳門口守著就可以寫出準(zhǔn)確及時(shí)的新聞。而政府部門也不用專人來應(yīng)付老記們的圍追堵截,有更多的時(shí)間為人民做實(shí)事辦好事。這里就只辛苦一個(gè)人。”
????? “那一定是新聞發(fā)言人自己了,因?yàn)樗枰扰c政府部門溝通好,要說些什么、如何說、如何回答刁鉆問題。然后要站在鎂光燈下承受壓力接受記者的訪問。不過,干這一行就是需要辛苦的,這是政府的門面呀。”小菜感慨到。

?

?????? “好了,去改寫吧,你一定會感受到分層后代碼的漂亮。”大鳥鼓勵道。

???????? 過一小時(shí)后,小菜給出商場收銀程序的第六份作業(yè)。。

DAL層代碼(目前是讀配置文件,以后可以很容易的修改為訪問數(shù)據(jù)庫)

using System; using System.Collections.Generic; using System.Text; using System.Data;namespace 商場管理軟件.DAL {public class CashAcceptType{public DataSet GetCashAcceptType(){//讀配置文件到DataSetDataSet ds = new DataSet();ds.ReadXml("CashAcceptType.xml");return ds;}} }

BLL層主要代碼(Facade類代碼)

namespace 商場管理軟件.BLL {public class CashFacade{const string ASSEMBLY_NAME = "商場管理軟件.BLL";//得到現(xiàn)金收取類型列表,返回字符串?dāng)?shù)組public string[] GetCashAcceptTypeList(){CashAcceptType cat = new CashAcceptType();DataSet ds = cat.GetCashAcceptType();int rowCount = ds.Tables[0].DefaultView.Count;string[] arrarResult = new string[rowCount];for (int i = 0; i < rowCount; i++){arrarResult[i] = (string)ds.Tables[0].DefaultView[i]["name"];}return arrarResult;}/// <summary>/// 用于根據(jù)商品活動的不同和原價(jià)格,計(jì)算此商品的實(shí)際收費(fèi)/// </summary>/// <param name="selectValue">下拉列表選擇的折價(jià)類型</param>/// <param name="startTotal">原價(jià)</param>/// <returns>實(shí)際價(jià)格</returns>public double GetFactTotal(string selectValue, double startTotal){CashAcceptType cat = new CashAcceptType();DataSet ds = cat.GetCashAcceptType();CashContext cc = new CashContext();DataRow dr = ((DataRow[])ds.Tables[0].Select("name='" + selectValue + "'"))[0];object[] args = null;if (dr["para"].ToString() != "")args = dr["para"].ToString().Split(',');cc.setBehavior((CashSuper)Assembly.Load(ASSEMBLY_NAME).CreateInstance(ASSEMBLY_NAME + "." + dr["class"].ToString(), false, BindingFlags.Default, null, args, null, null));return cc.GetResult(startTotal);}} }

UI層代碼(可以很容易的轉(zhuǎn)換為Web頁面)

double total = 0.0d;//用于總計(jì)CashFacade cf = new CashFacade();private void Form1_Load(object sender, EventArgs e){//讀數(shù)據(jù)綁定下拉列表cbxType.DataSource=cf.GetCashAcceptTypeList();cbxType.SelectedIndex = 0;}private void btnOk_Click(object sender, EventArgs e){double totalPrices = 0d;//傳進(jìn)下拉選擇值和原價(jià),計(jì)算實(shí)際收費(fèi)結(jié)果totalPrices = cf.GetFactTotal(cbxType.SelectedItem.ToString(), Convert.ToDouble(txtPrice.Text) * Convert.ToDouble(txtNum.Text));total = total + totalPrices;lbxList.Items.Add("單價(jià):" + txtPrice.Text + " 數(shù)量:" + txtNum.Text + " "+cbxType.SelectedItem+ " 合計(jì):" + totalPrices.ToString());lblResult.Text = total.ToString();}

項(xiàng)目文件結(jié)構(gòu)圖

?

?????? “大鳥,來看看這下怎么樣,還有沒有可修改的地方?”小菜問道。
?????? “小菜開始謙虛了嗎!以前不是一直信誓旦旦,現(xiàn)在怎么,沒信心了?”
?????? “越學(xué)越覺得自己知道的少,感覺代碼重構(gòu)沒有最好,只有更好呀。”小菜誠心的答道。
?????? “寫得很不錯(cuò)。BLL層的CashFacade類其實(shí)就是新聞發(fā)言人,程序的門面;而應(yīng)用程序或Web其實(shí)就類似CCTV和SMG,都是新聞單位,他們不應(yīng)該也不需要關(guān)心門面后面的實(shí)現(xiàn)是如何的。,現(xiàn)在用了門面模式以后,耦合比以前要少很多了,更改會更加方便,擴(kuò)展也很容易了。你要是再回過頭來看看最初的代碼和現(xiàn)在的代碼,你會體會更深刻,更加明白重構(gòu)的魅力。”

?

???????? 大鳥接著說:“之前的代碼,下拉控件的綁定是硬編碼,所以只要改動需求就得改代碼,現(xiàn)在是讀配置文件,大大增加靈活性;之前的代碼是根據(jù)用戶選擇,分支判斷執(zhí)行相應(yīng)的算法,現(xiàn)在整個(gè)算法類全部搬走,做到了業(yè)務(wù)與界面的分離;之前的代碼由于全寫在form里,所以要更換成Web方式,即C/S改為B/S非常困難,要全部重新寫(注意真實(shí)的軟件系統(tǒng)不會這么簡單,所以簡單復(fù)制不能解決問題),現(xiàn)在的代碼由于把業(yè)務(wù)運(yùn)算分離,所以界面的更改不會影響業(yè)務(wù)的編寫。還有就是現(xiàn)在的代碼由于DAL與BLL分離,配置文件可以很容易的更換為數(shù)據(jù)庫讀取,且不需要影響表示層與業(yè)務(wù)邏輯層的代碼。總的來講,若是程序不會變化,原有的設(shè)計(jì)就沒什么問題,運(yùn)行結(jié)果正確足夠了,但若是程序可能會時(shí)常隨業(yè)務(wù)而變化,新的設(shè)計(jì)就大大提高了應(yīng)變性,這其實(shí)就是應(yīng)用設(shè)計(jì)模式的目的所在。”
?????? “我現(xiàn)在越來越有信心學(xué)好它,設(shè)計(jì)模式真的很有意思,學(xué)它不學(xué)它,寫出來的代碼大不一樣。老大,跟你混,看來沒有錯(cuò)。”
?????? “嗨,小菜,我不做老大已經(jīng)很久了!”大鳥仰身長嘆,揚(yáng)長而去。

(待續(xù))

本文源代碼。其中分四個(gè)項(xiàng)目,DAL、BLL、WebUI和WinUI,可設(shè)置WebUI和WinUI為啟動項(xiàng)目,注意由于只是學(xué)習(xí)源代碼,配置路徑?jīng)]有做處理(實(shí)際應(yīng)用需要config文件),WebUI配置文件CashAcceptType.xml在“\商場管理軟件06分層\”根目錄下,而WinUI的配置文件CashAcceptType.xml在“\商場管理軟件06分層\商場管理軟件\bin\Debug\”目錄下。

出處:http://www.cnblogs.com/cj723/archive/2007/03/28/689955.html

總結(jié)

以上是生活随笔為你收集整理的大话设计模式(十三 有了门面,程序员的程序会更加体面!)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。