




版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、第七章 行為型設(shè)計(jì)模式l目錄l【7.1】 模板方法模式模板方法模式(Template method) l 7.2 觀察者模式(Oberserver) 【實(shí)驗(yàn)】l【7.3】 迭代子模式(Iterator) l 7.4 責(zé)任鏈模式(Chain of Responsibility)【實(shí)驗(yàn)】 l 7.5 備忘錄模式(Memento) 【實(shí)驗(yàn)】l 7.6 命令模式 (Command) 【實(shí)驗(yàn)】l 7.7 狀態(tài)模式(State) l【7.8】 訪問(wèn)者模式(訪問(wèn)者模式(Visitor)l【7.9】 中介者模式(中介者模式(Mediator) l【7.10】 策略模式(策略模式(Strategy) 7.1 模
2、板方法(Template Method)模式一、模板方法模式的由來(lái)二、模板方法模式的意圖及適用性三、模板方法模式的結(jié)構(gòu)及參與者四、應(yīng)用舉例五、效果分析7.1.1 模板方法模式的由來(lái)l行為型設(shè)計(jì)模式關(guān)注的焦點(diǎn)之一就是類(lèi)對(duì)象的職責(zé)分配,而模板方法實(shí)現(xiàn)父類(lèi)和子類(lèi)對(duì)象之間職責(zé)的劃分。7.1.1 模板方法模式的由來(lái)ABC類(lèi)類(lèi)CaC.A()7.1.1 模板方法模式的由來(lái)ABC類(lèi)類(lèi)CaC.A()ABCABC7.1.1 模板方法模式的由來(lái)ABC類(lèi)類(lèi)CaC.D()ABCABCD7.1.1 模板方法模式的由來(lái)ABC父類(lèi)父類(lèi)aC.D()ABCABCABCABCABCABCABCABC子類(lèi)子類(lèi)7.1.1 模板方法模式
3、的由來(lái)l比如就本科生如何培養(yǎng)這項(xiàng)工作,教育部制定綱領(lǐng)性政策,l如:軍訓(xùn)-學(xué)文化課-做畢業(yè)設(shè)計(jì)-畢業(yè)l至此,教育部的工作完成了。l接下來(lái)學(xué)生具體怎么軍訓(xùn),怎么上課,怎么做畢業(yè)設(shè)計(jì)等,就是各學(xué)校的職責(zé)了。7.1.1 模板方法模式的由來(lái)l教育部和學(xué)校之間通過(guò)上下級(jí)分工的方式分別完成了制定流程和具體實(shí)現(xiàn)2項(xiàng)工作。l這種思維模式引入到軟件設(shè)計(jì)中,就是Template methodlTemplate method使用繼承機(jī)制使得父類(lèi)和子類(lèi)之間達(dá)到分工合作的目的,父類(lèi)完成流程(算法、框架),子類(lèi)實(shí)現(xiàn)其具體工作。7.1.2 模板方法模式的意圖和適用性l定義一個(gè)操作中算法的骨架,將一些步驟的執(zhí)行延遲到其子類(lèi)中。
4、7.1.2 模板方法模式的意圖和適用性lTemplate Method模式一般應(yīng)用在具有以下條件的應(yīng)用中:l- 具有統(tǒng)一的操作步驟或操作過(guò)程- 具有不同的操作細(xì)節(jié) 即存在多個(gè)具有同樣操作步驟的應(yīng)用場(chǎng)景,但某些具體的操作細(xì)節(jié)卻各不相同 模板方法模式中的兩種方法l代表這些具體邏輯步驟的方法稱(chēng)做基本方法(primitive method);l將這些基本法方法總匯起來(lái)的方法叫做模版方法(template method),這摸板方法(Template Method)模式小結(jié)l 摸板方法(Template Method)模式是一種非常簡(jiǎn)單而又經(jīng)常使用的設(shè)計(jì)模式.先創(chuàng)建一個(gè)父類(lèi),把其中的一個(gè)或多個(gè)方法留給子
5、類(lèi)去實(shí)現(xiàn),這實(shí)際上就是在使用摸板模式.l 所謂的摸板模式可以這樣來(lái)理解:在一個(gè)類(lèi)中定義一個(gè)算法,但將此算法的某些細(xì)節(jié)留到子類(lèi)中去實(shí)現(xiàn).換句話(huà)說(shuō),基類(lèi)是一個(gè)抽象類(lèi),那么你就是在使用一種簡(jiǎn)單形式的摸板模式.l 更近一步可以這樣來(lái)理解:準(zhǔn)備一個(gè)抽象類(lèi),將部分邏輯以具體方法的形式實(shí)現(xiàn),然后申明一些抽象方法來(lái)迫使子類(lèi)實(shí)現(xiàn)剩余的邏輯.不同的子類(lèi)可以以不同的方法實(shí)現(xiàn)這些抽象方法,從而對(duì)剩余的邏輯有不同的實(shí)現(xiàn).7.1.3 模板方法模式的結(jié)構(gòu)和參與者7.1.3 模板方法模式的結(jié)構(gòu)和參與者1)AbstractClass, 定義抽象的原語(yǔ)操作,具體子類(lèi)將重定義他們以實(shí)現(xiàn)一個(gè)算法的各步驟 實(shí)現(xiàn)一個(gè)模板方法,定義一個(gè)算
6、法的骨架。該模板不僅調(diào)用原語(yǔ)操作,也調(diào)用定義在AbstractClass或其他對(duì)象中的操作2)ConcreteClass 實(shí)現(xiàn)原語(yǔ)操作以完成算法中與特定子類(lèi)相關(guān)的步驟教材上的應(yīng)用舉例l取款單模板l.4 應(yīng)用舉例l就前面所舉的本科生培養(yǎng)的例子,給出其代碼實(shí)現(xiàn)的示例。l看看如何實(shí)現(xiàn)父類(lèi)與子類(lèi)的分工,即教育部本科生培養(yǎng)處與各高校的本科生培養(yǎng)處如何實(shí)現(xiàn)職責(zé)劃分7.1.4 應(yīng)用舉例l public abstract class 教育部本科生培養(yǎng)處 /這就是一個(gè),定義了算法的骨架 public void 本科生培養(yǎng)() l 軍訓(xùn)(); 上課(); 畢業(yè)設(shè)計(jì)(); 授予學(xué)位(); /這里還可
7、以有其它培養(yǎng)內(nèi)容l protected abstract void 軍訓(xùn)(); protected abstract void 上課(); protected abstract void 畢業(yè)設(shè)計(jì)(); protected abstract void 授予學(xué)位(); 7.1.4 應(yīng)用舉例 public class 清華大學(xué)本科生培養(yǎng)處 : 教育部本科生培養(yǎng)處 protected override void 軍訓(xùn)() /站軍姿l /正步走 protected override void 上課() /具體課程l protected override 畢業(yè)設(shè)計(jì)() /開(kāi)題,論文,答辯l protec
8、ted override 授予() /授予儀式 7.1.4 應(yīng)用舉例l public class App l l static void Main() l l 教育部本科生培養(yǎng)處 PYC=new 清華大學(xué)本科生培養(yǎng)處();l PYC.本科生培養(yǎng)();l Console.Read(); /等待用戶(hù)輸入 l 實(shí)用例子lHttpServlet技術(shù)l造電腦的示例l數(shù)據(jù)庫(kù)訪問(wèn)的模板方法l有趣的模板方法模式:造悍馬汽車(chē)7.1.5 效果分析l模板方法是一種代碼復(fù)用技術(shù),提取了“子類(lèi)”的公共行為l模板方法導(dǎo)致一種反向的控制結(jié)構(gòu):“你別來(lái)找我,讓我去找你”,即:一個(gè)父類(lèi)調(diào)用子類(lèi)的操作,而不是相反。關(guān)于繼承的討論
9、l模版方法模式鼓勵(lì)恰當(dāng)?shù)厥褂美^承。此模式可以用來(lái)改寫(xiě)一些擁有相同功能的相關(guān)的類(lèi),將可復(fù)用的l一般性的行為代碼移到基類(lèi)里面,而把特殊化的行為代碼移到子類(lèi)里面。l因此,熟悉模版方法模式便成為一個(gè)重新學(xué)習(xí)繼承的好地方。7.2 觀察者模式(Oberserver) 【實(shí)驗(yàn)】 一.觀察者模式的由來(lái)二.觀察者模式的意圖及適用性三.觀察者模式的結(jié)構(gòu)及參與者四.應(yīng)用舉例五.效果說(shuō)明7.2.1 觀察者模式的由來(lái)l在制作系統(tǒng)的過(guò)程中,將一個(gè)系統(tǒng)分割成一系列相互協(xié)作的類(lèi)有一個(gè)常見(jiàn)的副作用:需要維護(hù)相關(guān)對(duì)象間的一致性。我們不希望為了維持一致性而使各類(lèi)緊密耦合,因?yàn)檫@樣降低了他們的可充用性。7.2.1 觀察者模式的由來(lái)
10、例如, 許多圖形用戶(hù)界面工具箱將用戶(hù)應(yīng)用的界面表示與底下的應(yīng)用數(shù)據(jù)分離。定義應(yīng)用數(shù)據(jù)的類(lèi)和負(fù)責(zé)界面表示的類(lèi)可以各自獨(dú)立地復(fù)用。當(dāng)然它們也可一起工作。一個(gè)表格對(duì)象和一個(gè)柱狀圖對(duì)象可使用不同的表示形式描述同一個(gè)應(yīng)用數(shù)據(jù)對(duì)象的信息。表格對(duì)象和柱狀圖對(duì)象互相并不知道對(duì)方的存在,這樣使你可以根據(jù)需要單獨(dú)復(fù)用表格或柱狀圖。但在這里是它們表現(xiàn)的似乎互相知道。當(dāng)用戶(hù)改變表格中的信息時(shí),柱狀圖能立即反映這一變化, 反過(guò)來(lái)也是如此。7.2.1 觀察者模式的由來(lái) 這一行為意味著表格對(duì)象和棒狀圖對(duì)象都依賴(lài)于數(shù)據(jù)對(duì)象, 因此數(shù)據(jù)對(duì)象的任何狀態(tài)改變都應(yīng)立即通知它們。同時(shí)也沒(méi)有理由將依賴(lài)于該數(shù)據(jù)對(duì)象的對(duì)象的數(shù)目限定為兩個(gè),
11、 對(duì)相同的數(shù)據(jù)可以有任意數(shù)目的不同用戶(hù)界面。7.2.2 觀察者模式的意圖和適用性l模式的意圖 定義對(duì)象間的一種一對(duì)多的依賴(lài)關(guān)系,當(dāng)一個(gè)對(duì)象的狀態(tài)發(fā)生改變時(shí),所有依賴(lài)于它的對(duì)象都得到通知并被自動(dòng)更新。 7.2.2 觀察者模式的意圖和適用性l 在下面的三種情況下均可使用Observer模式:l 當(dāng)一個(gè)抽象模型有兩個(gè)方面, 其中一個(gè)方面依賴(lài)于另一方面。將這二者封裝在獨(dú)立的對(duì)象中以使它們可以各自獨(dú)立地改變和復(fù)用。l 當(dāng)對(duì)一個(gè)對(duì)象的改變需要同時(shí)改變其它對(duì)象, 而不知道具體有多少對(duì)象有待改變。l 當(dāng)一個(gè)對(duì)象必須通知其它對(duì)象,而它又不能假定其它對(duì)象是誰(shuí)。換言之, 你不希望這些對(duì)象是緊密耦合的。7.2.3 觀
12、察者模式的結(jié)構(gòu)和參與者l觀察者模式結(jié)構(gòu)圖7.2.3 觀察者模式的結(jié)構(gòu)和參與者 Observerl Subject(目標(biāo)) 目標(biāo)知道它的觀察者??梢杂腥我舛鄠€(gè)觀察者觀察同一個(gè)目標(biāo)。 提供注冊(cè)和刪除觀察者對(duì)象的接口。l Observer(觀察者) 為那些在目標(biāo)發(fā)生改變時(shí)需獲得通知的對(duì)象定義一個(gè)更新接口。l Concrete Subject(具體目標(biāo)) 將有關(guān)狀態(tài)存入各Concrete Observer對(duì)象。 當(dāng)它的狀態(tài)發(fā)生改變時(shí), 向它的各個(gè)觀察者發(fā)出通知。l Concrete Observer(具體觀察者) 維護(hù)一個(gè)指向Concrete Subject對(duì)象的引用。 存儲(chǔ)有關(guān)狀態(tài),這些狀態(tài)應(yīng)與目標(biāo)
13、的狀態(tài)保持一致。 實(shí)現(xiàn)Observer的更新接口以使自身狀態(tài)與目標(biāo)的狀態(tài)保持一致。7.2.4 應(yīng)用舉例 例如:班主任老師有電話(huà)號(hào)碼,學(xué)生需要知道班主任老師的電話(huà)號(hào)碼以便于在合適時(shí)的時(shí)候撥打,在這樣的組合中,老師就是一個(gè)被觀察者(Subject),學(xué)生就是需要知道信息的觀察者,當(dāng)老師的電話(huà)號(hào)碼發(fā)生改變時(shí),學(xué)生得到通知,并更新相應(yīng)的電話(huà)記錄。該應(yīng)用的類(lèi)圖如下圖所示。應(yīng)用舉例7.2.4 應(yīng)用舉例相關(guān)代碼:Subject代碼:package observer; public interface Subject /目標(biāo)類(lèi)的定義public void attach(Observer o); /注冊(cè)一個(gè)觀察
14、者public void detach(Observer o); /刪除一個(gè)觀察者public void notice(); /通知所有觀察者更新Observer代碼:package observer;public interface Observer /觀察者類(lèi)定義public void update(); /更新觀察者7.2.4 應(yīng)用舉例Teacher代碼;package observer;import java.util.Vector;public class Teacher implements Subjectprivate String phone; /電話(huà)號(hào)碼private Vec
15、tor students; /學(xué)生public Teacher()phone = ;students = new Vector();public void attach(Observer o)students.add(o);/注冊(cè)學(xué)生public void detach(Observer o)students.remove(o);刪除學(xué)生public void notice() /通知學(xué)生更新 for(int i=0;istudents.size();i+) (Observer)students.get(i).update();public void setPhone(String phone
16、)this.phone = phone;notice();public String getPhone()return phone;7.2.4 應(yīng)用舉例Student代碼:package observer;public class Student implements Observerprivate String name; /學(xué)生姓名private String phone; /班主任老師電話(huà)private Teacher teacher;public Student(String name,Teacher t) = name;teacher = t;public void
17、 show()System.out.println(Name:+name+nTeachers phone:+phone);public void update() /更新電話(huà)號(hào)碼與老師的保持一致phone = teacher.getPhone(); 7.2.4 應(yīng)用舉例 Client代碼:package observer;import java.util.Vector;public class Clientpublic static void main(String args)Vector students = new Vector(); /定義學(xué)生類(lèi)向量Teacher t = new Tea
18、cher(); /定義老師類(lèi)對(duì)象for(int i= 0 ;i10;i+) Student st = new Student(lili+i,t); students.add(st); /把學(xué)生加到向量中 t.attach(st); /老師注冊(cè)一個(gè)學(xué)生t.setPhone(“123);for(int i=0;i10;i+) (Student)students.get(i).show(); /所有學(xué)生的老師電話(huà)都為123t.setPhone(“456);for(int i=0;i10;i+) (Student)students.get(i).show(); /所有學(xué)生的老師電話(huà)都為4567.2.5
19、 效果分析觀察者模式的應(yīng)用場(chǎng)景:l對(duì)一個(gè)對(duì)象狀態(tài)的更新,需要其他對(duì)象同步更新,而且其他對(duì)象的數(shù)量動(dòng)態(tài)可變。l對(duì)象僅需要將自己的更新通知給其他對(duì)象而不需要知道其他對(duì)象的細(xì)節(jié)。7.2.5 效果分析觀察者模式的優(yōu)點(diǎn):lSubject和Observer之間是松偶合的,分別可以各自獨(dú)立改變。lSubject在發(fā)送廣播通知的時(shí)候,無(wú)須指定具體的Observer,Observer可以自己決定是否要訂閱Subject的通知。l遵守大部分GRASP原則和常用設(shè)計(jì)原則,高內(nèi)聚、低偶合。7.2.5 效果分析觀察者模式的缺陷:l松偶合導(dǎo)致代碼關(guān)系不明顯,有時(shí)可能難以理解。l如果一個(gè)Subject被大量Observer
20、訂閱的話(huà),在廣播通知的時(shí)候可能會(huì)有效率問(wèn)題。7.3迭代子模式(Iterator)一、迭代子模式的由來(lái)二、迭代子模式的意圖及適用性三、迭代子模式的結(jié)構(gòu)及參與者四、應(yīng)用舉例五、效果分析7.3.1 迭代子模式的由來(lái)l 以集合對(duì)象為例,集合是一個(gè)管理和組織數(shù)據(jù)對(duì)象的數(shù)據(jù)結(jié)構(gòu)。這就表明集合首先應(yīng)具備一個(gè)基本屬性,就是集合能夠存儲(chǔ)數(shù)據(jù)。這其中包含存儲(chǔ)數(shù)據(jù)的類(lèi)型、存儲(chǔ)空間的大小、存儲(chǔ)空間的分配、以及存儲(chǔ)的方式和順序。不具備這些特點(diǎn),則該對(duì)象就不成其為集合對(duì)象。也就是說(shuō),上述這些屬性是集合對(duì)象與身俱來(lái)的,是其密不可分的職責(zé)。l 然而,集合對(duì)象除了能夠存儲(chǔ)數(shù)據(jù)外,還必須提供訪問(wèn)其內(nèi)部數(shù)據(jù)的行為方式,這是一種遍歷
21、機(jī)制。同時(shí)這種遍歷方式,或會(huì)根據(jù)不同的情形提供不同的實(shí)現(xiàn),如順序遍歷,逆序遍歷,或是二叉樹(shù)結(jié)構(gòu)的中序、前序、后序遍歷。7.3.1 迭代子模式的由來(lái)順序逆序中序后序存儲(chǔ) 聚合類(lèi)遍歷機(jī)制7.3.1 迭代子模式的由來(lái)順序逆序中序后序存儲(chǔ) 迭代類(lèi)聚合類(lèi)7.3.1 迭代子模式的由來(lái)l 迭代子模式實(shí)際上做的工作就是把對(duì)象的職責(zé)分離。職責(zé)分離,可以最大限度地減少彼此之間的耦合程度,從而建立一個(gè)松散耦合的對(duì)象網(wǎng)絡(luò)。l 職責(zé)分離的要點(diǎn)是對(duì)被分離的職責(zé)進(jìn)行封裝,并以抽象的方式建立起彼此之間的關(guān)系。例如,我們往往將這些可能變化的對(duì)象抽象為接口和抽象類(lèi),從而將原來(lái)的具體依賴(lài)改變?yōu)槌橄笠蕾?lài)。對(duì)象不再受制于具體的實(shí)現(xiàn)細(xì)節(jié)
22、約束7.3.1 迭代子模式的由來(lái)l現(xiàn)在我們已經(jīng)分辨出集合對(duì)象擁有的兩個(gè)職責(zé):一是存儲(chǔ)內(nèi)部數(shù)據(jù);二是遍歷內(nèi)部數(shù)據(jù)。從依賴(lài)性來(lái)看,前者為集合對(duì)象的根本屬性,而后者既是可變化的,又是可分離的。因此,我們將遍歷行為分離出來(lái),抽象為一個(gè)迭代器,專(zhuān)門(mén)提供遍歷集合內(nèi)部數(shù)據(jù)對(duì)象的行為。這就是迭代子模式的本質(zhì)。7.3.2 迭代子模式的意圖和適用性l模式的意圖 迭代子模式的目的是設(shè)計(jì)一個(gè)迭代器,這迭代器提供一種方法,可以順序訪問(wèn)一個(gè)聚合對(duì)象中的各個(gè)元素,但又不暴露該對(duì)象的內(nèi)部表示7.3.2 迭代子模式的意圖和適用性l以下情況可以使用迭代子模式:l1.訪問(wèn)一個(gè)聚合對(duì)象的內(nèi)容而無(wú)需暴露它的內(nèi)部表示。l2.支持對(duì)聚合對(duì)
23、象的多種遍歷。l3.為遍歷不同的聚合結(jié)構(gòu)提供一個(gè)統(tǒng)一的接口 (即, 支持多態(tài)迭代)。7.3.3 迭代子模式的結(jié)構(gòu)和參與者l迭代子模式結(jié)構(gòu)圖7.3.3 迭代子模式的結(jié)構(gòu)和參與者l 迭代器迭代器(Iterator) 迭代器定義訪問(wèn)和遍歷元素的接口。l 具體迭代器具體迭代器(ConcreteIterator)1.具體迭代器實(shí)現(xiàn)迭代器接口。2.對(duì)該聚合遍歷時(shí)跟蹤當(dāng)前位置。l 聚合聚合(Aggregate)聚合定義創(chuàng)建相應(yīng)迭代器對(duì)象的接口。l 具體聚合具體聚合(ConcreteAggregate)具體聚合實(shí)現(xiàn)創(chuàng)建相應(yīng)迭代器的接口,該操作返回 具體迭代器 的一個(gè)適當(dāng)?shù)膶?shí)例。7.3.4 應(yīng)用舉例兩種實(shí)現(xiàn)方式
24、l 1 白箱聚集與外稟迭代子:白箱聚集向外界提供訪問(wèn)自己內(nèi)部元素的接口,從而使得外稟迭代子,可以通過(guò)聚集提供的方法實(shí)現(xiàn)迭代功能。l 2 黑箱聚集內(nèi)稟迭代子:黑箱聚集不向外界提供遍歷自己的元素的接口,因此聚集的成員只能被聚集內(nèi)部的方法訪問(wèn)。由于內(nèi)稟迭代子恰好是聚集的成員,因此可以訪問(wèn)聚集元素。應(yīng)用舉例之白箱例子Aggregate:abstract public class Aggregate public Iterator createIterator() return null; Iterator:public interface Iterator void first(); void nex
25、t(); bool isDone(); Object currentItem();Aggregateiterator思考:兩者如何連接應(yīng)用舉例之白箱例子AggregateiteratorcreateIterator()Aggregate應(yīng)用舉例之白箱例子public class ConcreteAggregate : Aggregate private Object objs = Monk Tang , Monkey, Pigsy, Sandy”; public Iterator createIterator() return new ConcreteIterator(this); publi
26、c Object getElement(int index) if(index objs.Length) return objsindex; else return null; public int size() return objs.Length; createIterator() ConcreteAggregatepublic class ConcreteIterator implements Iterator private ConcreteAggregate agg; private int index = 0; private int size = 0; public Concre
27、teIterator(ConcreteAggregate agg) this.agg = agg; size = agg.size(); index = 0 ; public void first() index = 0 ; public void next() if (index = size); public Object currentItem() return agg.getElement(index); ConcreteIterator 迭代類(lèi)聚合類(lèi)Firstnext聚合類(lèi)引用Client:public class Client private Iterator it; privat
28、e Aggregate agg = new ConcreteAggregate();public void operation() it = agg.createIterator(); while( !it.isDone() ) System.out.println(it.currentItem().toString(); it.next(); public static void main(String args) Client client = new Client(); client.operation(); 應(yīng)用舉例之白箱例子createIterator() ConcreteAggre
29、gate迭代類(lèi)聚合類(lèi)Firstnext應(yīng)用舉例之黑箱例子Iterator:public interface Iterator void first(); void next(); boolean isDone(); Object currentItem();Aggregate:abstract public class Aggregate public Iterator createIterator() return null; ConcreteAggregate:public class ConcreteAggregate extends Aggregate private Object o
30、bjs = Monk Tang,Monkey, Pigs,Sandy, Horse; public Iterator createIterator() return new ConcreteIterator(); private class ConcreteIterator implements Iterator private int currentIndex = 0; public void first() currentIndex = 0; public void next() if ( currentIndex = 0 & request = 10 & request
31、= 20 & request 30 ) Console.WriteLine(0 handled request 1, this, request ); else if( successor != null ) successor.HandleRequest( request ); / Client test public class Client public static void Main( string args ) / Setup Chain of Responsibility Handler h1 = new ConcreteHandler1(); Handler h2 =
32、new ConcreteHandler2(); Handler h3 = new ConcreteHandler3(); h1.SetSuccessor(h2); h2.SetSuccessor(h3); / Generate and process request int requests = 2, 5, 14, 22, 18, 3, 27, 20 ; foreach( int request in requests ) h1.HandleRequest( request ); l 責(zé)任鏈模式并不創(chuàng)建責(zé)任鏈。責(zé)任鏈的創(chuàng)建必須由系統(tǒng)的其它部分創(chuàng)建出來(lái)。l 責(zé)任鏈模式降低了請(qǐng)求的發(fā)送端和接收端之
33、間的耦合,使多個(gè)對(duì)象都有機(jī)會(huì)處理這個(gè)請(qǐng)求。一個(gè)鏈可以是一條線(xiàn),一個(gè)樹(shù),也可以是一個(gè)環(huán)。如下圖所示,責(zé)任鏈?zhǔn)且粋€(gè)樹(shù)結(jié)構(gòu)的一部分。1) 優(yōu)點(diǎn):責(zé)任鏈模式的最大的一個(gè)有點(diǎn)就是給系統(tǒng)降低了耦合性,請(qǐng)求的發(fā)送者完全不必知道該請(qǐng)求會(huì)被哪個(gè)應(yīng)答對(duì)象處理,極大地降低了系統(tǒng)的耦合性。 2) 缺點(diǎn):消息傳遞和處理不當(dāng)會(huì)出現(xiàn)消息的循環(huán)重復(fù)執(zhí)行。7.4.5 效果分析7.5 備忘錄模式(Memento) 【實(shí)驗(yàn)】一、備忘錄模式的由來(lái)二、備忘錄模式的意圖及適用性三、備忘錄模式的結(jié)構(gòu)及參與者四、應(yīng)用舉例五、效果分析7.5.1 備忘錄模式的由來(lái)l沒(méi)有人想犯錯(cuò)誤,但是沒(méi)有人能夠不犯錯(cuò)誤。犯了錯(cuò)誤一般只能改過(guò),卻很難改正(恢復(fù))
34、。世界上沒(méi)有后悔藥,但是我們?cè)谶M(jìn)行軟件系統(tǒng)的設(shè)計(jì)時(shí)候是要給用戶(hù)后悔的權(quán)利(實(shí)際上可能也是用戶(hù)要求的權(quán)利),我們對(duì)一些關(guān)鍵性的操作肯定需要提供諸如撤銷(xiāo) (Undo)的操作。那這個(gè)后悔藥就是 Memento 模式提供的。7.5.2 備忘錄模式的意圖和適用性模式的意圖 在不破壞封裝性的前提下,捕獲一個(gè)對(duì)象的內(nèi)部狀態(tài),并在該對(duì)象之外保存這個(gè)狀態(tài)。這樣以后就可將該對(duì)象恢復(fù)到原先保存的狀態(tài)7.5.2 備忘錄模式的意圖和適用性在以下情況下使用備忘錄模式:l必須保存一個(gè)對(duì)象在某一個(gè)時(shí)刻的 (部分)狀態(tài), 這樣以后需要時(shí)它才能恢復(fù)到先前的狀態(tài)。l如果一個(gè)用接口來(lái)讓其它對(duì)象直接得到這些狀態(tài),將會(huì)暴露對(duì)象的實(shí)現(xiàn)細(xì)節(jié)
35、并破壞對(duì)象的封裝性。7.5.3備忘錄模式的結(jié)構(gòu)和參與者備忘錄模式結(jié)構(gòu)圖:7.5.3 備忘錄模式的結(jié)構(gòu)和參與者:1) 備忘錄(Memento):備忘錄存儲(chǔ)原發(fā)器對(duì)象的內(nèi)部狀態(tài);防止原發(fā)器以外的其他對(duì)象訪問(wèn)備忘錄。2) 原發(fā)器(Originator):原發(fā)器創(chuàng)建一個(gè)備忘錄,用以記錄當(dāng)前時(shí)刻它的內(nèi)部狀態(tài);使用備忘錄恢復(fù)內(nèi)部狀態(tài)。/Originatorclass Originator public: typedef string State; Originator(); Originator(const State& sdt); Originator(); Memento* CreateMem
36、ento(); void SetMemento(Memento* men); void RestoreToMemento(Memento* mt); State GetState(); void SetState(const State& sdt); void PrintState(); private: State _sdt; Memento* _mt; ; 7.5.4 應(yīng)用舉例Originator:Originator() _sdt = ; _mt = 0; Originator:Originator(const State& sdt) _sdt = sdt; _mt =
37、0; Originator:Originator() Memento* Originator:CreateMemento() return new Memento(_sdt); State Originator:GetState() return _sdt; void Originator:SetState(const State& sdt) _sdt = sdt; void Originator:PrintState() cout_sdt._sdt = mt-GetState(); / Mementoclass Memento private: friend class Origin
38、ator; /這是最關(guān)鍵的地方,將Originator為friend類(lèi),可以訪問(wèn)內(nèi)部信息,但是其他類(lèi)不能訪問(wèn) typedef string State; Memento(); Memento(const State& sdt); Memento(); void SetState(const State& sdt); State GetState(); private: State _sdt; ; /class Memento Memento:Memento() Memento: Memento() Memento:Memento(const State& sdt) _s
39、dt = sdt; State Memento:GetState() return _sdt; void Memento:SetState(const State& sdt) _sdt = sdt; /main.cpp int main(int argc,char* argv) Originator* o = new Originator(); o-SetState(“old”); /備忘前狀態(tài) o-PrintState(); Memento* m = o-CreateMemento(); /將狀態(tài)備忘 o-SetState(“new”); /修改狀態(tài) o-PrintState();
40、o-RestoreToMemento(m); /恢復(fù)修改前狀態(tài) o-PrintState(); return 0; 優(yōu)點(diǎn):1)保持封裝邊界;使用備忘錄可以避免暴露一些只應(yīng)由原發(fā)器管理卻又必須存儲(chǔ)在原發(fā)器之外的信息。該模式把可能很復(fù)雜的原發(fā)器內(nèi)部信息對(duì)其他對(duì)象屏蔽起來(lái),從而保持了封裝邊界。2)簡(jiǎn)化原發(fā)器;在其他的保持封裝性的設(shè)計(jì)中 ,原發(fā)器負(fù)責(zé)保持客戶(hù)請(qǐng)求過(guò)的內(nèi)部狀態(tài)版本。這就把所有存儲(chǔ)管理的重任交給了原發(fā)器。讓客戶(hù)管理它們請(qǐng)求的狀態(tài)將會(huì)簡(jiǎn)化原發(fā)器,并且使得客戶(hù)工作結(jié)束時(shí)無(wú)需通知原發(fā)器。缺點(diǎn):1)定義窄接口和寬接口;在一些語(yǔ)言中可能難以保證只有原發(fā)器可訪問(wèn)備忘錄的狀態(tài)。2)使用備忘錄可能代價(jià)很高
41、;如果原發(fā)器在生成備忘錄時(shí)必須拷貝并存儲(chǔ)大量的信息 ,或者客戶(hù)非常頻繁地創(chuàng)建備忘錄和恢復(fù)原發(fā)器狀態(tài),可能會(huì)導(dǎo)致非常大的開(kāi)銷(xiāo)。除非封裝和恢復(fù)原發(fā)器狀態(tài)的開(kāi)銷(xiāo)不大,否則該模式可能并不合適。7.5.5 效果分析7.6 命令模式 (Command) 【實(shí)驗(yàn)】一.命令模式的由來(lái)二.模式意圖和適用性三.模式結(jié)構(gòu)和參與者四. 實(shí)例說(shuō)明五. 效果分析7.6.1 命令模式的由來(lái) 將一個(gè)請(qǐng)求封裝為一個(gè)對(duì)象,從而使我們可用不同的請(qǐng)求對(duì)客戶(hù)進(jìn)行參數(shù)化;對(duì)請(qǐng)求排隊(duì)或記錄請(qǐng)求日志,以及支持可撤消的操作。一個(gè)菜單控件的例子PasteCommand命令OpenCommand命令MacroCommand命令腳本7.6.3 命令
42、模式的意圖和適用性意圖:l將一個(gè)請(qǐng)求封裝為一個(gè)對(duì)象,從而使你可用不同的請(qǐng)求對(duì)客戶(hù)進(jìn)行參數(shù)化;對(duì)請(qǐng)求排隊(duì)或記錄請(qǐng)求日志,以及支持可取消的操作 7.6.3 命令模式的意圖和適用性適用性:抽象出待執(zhí)行的動(dòng)作以參數(shù)化某對(duì)象在不同的時(shí)刻指定、排列和執(zhí)行請(qǐng)求支持取消操作(Unexecute)支持修改日志用構(gòu)建在原語(yǔ)操作上的高層操作構(gòu)造一個(gè)系統(tǒng)7.6.4 命令模式的結(jié)構(gòu)和參與者7.6.4 命令模式的結(jié)構(gòu)和參與者Commandu聲明執(zhí)行操作的接口ConcreteCommandu將一個(gè)接收者對(duì)象綁定于一個(gè)動(dòng)作u調(diào)用接收者相應(yīng)的操作,以實(shí)現(xiàn)ExecuteClient(Application)u創(chuàng)建一個(gè)具體命令對(duì)象
43、并設(shè)定它的接收者Invoker(MenuItem)u要求該命令執(zhí)行這個(gè)請(qǐng)求Receiver(Document,Application) u知道如何實(shí)施與執(zhí)行一個(gè)請(qǐng)求相關(guān)的操作7.6.4 應(yīng)用舉例菜單控件的代碼實(shí)例Command抽象類(lèi)OpenCommand命令PasteCommand命令7.6.5 命令模式效果分析Command模式將調(diào)用操作的對(duì)象與知道如何實(shí)現(xiàn)該操作的對(duì)象解耦Command是頭等 的對(duì)象,它們可像其他的對(duì)象一樣被操縱和擴(kuò)展可將多個(gè)命令裝配成一個(gè)復(fù)合命令可以很容易的增加新的Command對(duì)象,因?yàn)檫@無(wú)需改變已有的類(lèi)。7.7 狀態(tài)模式(State)一.模式的由來(lái)二.狀態(tài)狀態(tài)模式的意
44、圖及適用性三.狀態(tài)模式的結(jié)構(gòu)及參與者四.應(yīng)用舉例五.效果說(shuō)明7.7.1 狀態(tài)模式的由來(lái) 一個(gè)對(duì)象有多種狀態(tài),在不同的狀態(tài)下,對(duì)象可以有不同的行為。7.7.1 狀態(tài)模式的由來(lái)狀態(tài)變量sSwitch s Case 1 do o1 s=3 Case 2 do o2 s=2 End switchContext類(lèi)初始狀態(tài)1狀態(tài)變化:13 2思考:缺陷在哪里?O1O2O3操作7.7.1 狀態(tài)模式的由來(lái)Context類(lèi)狀態(tài)1類(lèi)狀態(tài)2類(lèi)狀態(tài)3類(lèi)狀態(tài)類(lèi)思考:兩者如何連接?O1O2O37.7.1 狀態(tài)模式的由來(lái)狀態(tài)對(duì)象Context類(lèi)狀態(tài)1類(lèi)狀態(tài)2類(lèi)狀態(tài)3類(lèi)狀態(tài)類(lèi)初始化思考:狀態(tài)操作放在哪里?O1O2O37.7.
45、1 狀態(tài)模式的由來(lái)狀態(tài)對(duì)象Context類(lèi)狀態(tài)1類(lèi)狀態(tài)2類(lèi)狀態(tài)3類(lèi)狀態(tài)類(lèi)初始化O1O2O37.7.1 狀態(tài)模式的由來(lái)狀態(tài)對(duì)象1Context類(lèi)狀態(tài)1類(lèi)狀態(tài)2類(lèi)狀態(tài)3類(lèi)狀態(tài)類(lèi)Context對(duì)象如何完成狀態(tài)變化?初始化O1O2O3O17.7.1 狀態(tài)模式的由來(lái)狀態(tài)對(duì)象1Context類(lèi)狀態(tài)1類(lèi)狀態(tài)2類(lèi)狀態(tài)3類(lèi)狀態(tài)類(lèi)Context對(duì)象如何完成狀態(tài)變化?初始化Changestate()O1O2O3O1狀態(tài)3類(lèi)O3替換Changestate(s)7.7.1 狀態(tài)模式的由來(lái)狀態(tài)對(duì)象1Context類(lèi)狀態(tài)1類(lèi)狀態(tài)2類(lèi)狀態(tài)3類(lèi)狀態(tài)類(lèi)Context對(duì)象如何完成狀態(tài)變化?初始化Changestate()O1O2O
46、3O1狀態(tài)3類(lèi)O3替換Changestate(s)調(diào)用思考:O1有沒(méi)有權(quán)調(diào)用changestate()7.7.1 狀態(tài)模式的由來(lái)狀態(tài)對(duì)象1Context類(lèi)狀態(tài)1類(lèi)狀態(tài)2類(lèi)狀態(tài)3類(lèi)狀態(tài)類(lèi)初始化Changestate()O1O2O3O1狀態(tài)2類(lèi)O2替換Changestate(s)調(diào)用能不能保留context類(lèi)的o1,o2,o3操作接口?以支持兼容7.7.1 狀態(tài)模式的由來(lái)狀態(tài)對(duì)象1Context類(lèi)狀態(tài)1類(lèi)狀態(tài)2類(lèi)狀態(tài)3類(lèi)狀態(tài)類(lèi)能不能保留context類(lèi)的o1,o2,o3操作接口?以支持兼容初始化Changestate()O1O2O3O1狀態(tài)2類(lèi)O2替換Changestate(s)調(diào)用O1O2O3調(diào)
47、用一個(gè)TCPConnection的例子7.7.2 狀態(tài)模式的意圖和適用性意圖:讓一個(gè)對(duì)象在其內(nèi)部狀態(tài)改變的時(shí)候,其行為也隨之改變。 在下面的兩種情況下均可使用S t a t e模式: 一個(gè)對(duì)象的行為取決于它的狀態(tài), 并且它必須在運(yùn)行時(shí)刻根據(jù)狀態(tài)改變它的行為。 一個(gè)操作中含有龐大的多分支的條件語(yǔ)句,且這些分支依賴(lài)于該對(duì)象的狀態(tài)。這個(gè)狀態(tài)通常用一個(gè)或多個(gè)枚舉常量表示。通常, 有多個(gè)操作包含這一相同的條件結(jié)構(gòu)。S t a t e模式將每一個(gè)條件分支放入一個(gè)獨(dú)立的類(lèi)中。這使得我們可以根據(jù)對(duì)象自身的情況將對(duì)象的狀態(tài)作為一個(gè)對(duì)象,這一對(duì)象可以不依賴(lài)于其他對(duì)象而獨(dú)立變化。7.7.3 狀態(tài)模式的結(jié)構(gòu)和參與者7
48、.7.3 狀態(tài)模式的結(jié)構(gòu)和參與者 Context( (狀態(tài)管理器,如狀態(tài)管理器,如TCPConnection) )定義客戶(hù)感興趣的接口。,這個(gè)實(shí)例定義當(dāng)前狀態(tài)。 State(狀態(tài),如狀態(tài),如TCPState )定義一個(gè)接口以封裝與Context的一個(gè)特定狀態(tài)相關(guān)的行為。 ConcreteState subclasses(具體狀態(tài)子類(lèi),如具體狀態(tài)子類(lèi),如TCPEstablished, TCPListen, TCPClosed) 每一子類(lèi)實(shí)現(xiàn)一個(gè)與Context的一個(gè)狀態(tài)相關(guān)的行為。7.7.4 TCPConnection代碼實(shí)例 TCPConnection內(nèi)部操作改變實(shí)例目標(biāo)狀態(tài)實(shí)例每種狀態(tài)實(shí)例都
49、具有這些操作TCPState抽象類(lèi)友元操作TCPEstablished狀態(tài)轉(zhuǎn)移到新建listen狀態(tài)靜態(tài)成員實(shí)例TCPListen狀態(tài)轉(zhuǎn)移到新建established狀態(tài)TCPClosed狀態(tài)7.7.5 狀態(tài)模式的效果分析n 多態(tài)性的實(shí)現(xiàn)class Contextpublic: a(); b(); c(); void Operation() state- Operation(this); private: friend class State; Changestate();private: State state;class Statepublic: virtual void Operatio
50、n (Context* ) = 0; protect: bool ChangeState(Context* con,State* st) con.Chagestate(st); 7.7.5 狀態(tài)模式的效果分析class ConcreteStateA: public Statepublic: virtual void Operation(Context* con);protect:private:void ConcreteStateA:Operation(Context* con) con.a();友元+多態(tài)7.7.5 狀態(tài)模式的效果分析class ConcreteStateB: public
51、Statepublic: virtual void Operation(Context* con);protect:private:void ConcreteStateB:Operation(Context* con) con.b();7.7.5 狀態(tài)模式的效果分析class ConcreteStateC: public Statepublic: virtual void Operation(Context* con);protect:private:void ConcreteStateC:Operation(Context* con) con.c();7.7.5 狀態(tài)模式的效果分析未使用ST
52、ATEmain() var state; if(state=A) a(); if(state=B) b(); if(state=C) c();使用STATEmain() State state=; Context con(state); con.Operation(); 狀態(tài)切換邏輯7.7.5 狀態(tài)模式的效果分析n 狀態(tài)的自動(dòng)切換void ConcreteStateA:Operation(Context* con) con.a(); Changestate(con, new ConcreteStateB();void ConcreteStateB:Operation(Context* con)
53、 con.b(); Changestate(con, new ConcreteStateC();void ConcreteStateC:Operation(Context* con) con.c(); Changestate(con, new ConcreteStateA();使用STATEmain() State state=new ConcreteStateA(); Context con(state); while(con.getstate()!=A); /等待起始狀態(tài)A do con.Operation(); while(con.getstate()!=C); /未進(jìn)入結(jié)束狀態(tài),則執(zhí)行
54、當(dāng) 前狀態(tài)的動(dòng)作 con.Operation();7.7.5 狀態(tài)模式的效果分析未使用STATEmain() var state; if(state=A) a(); state=B; if(state=B) b(); state=C; if(state=C) c(); state=A; 使用STATE模式,動(dòng)作完成后,可以自動(dòng)切換到下一個(gè)狀態(tài),客戶(hù)無(wú)須知道具體的切換邏輯。每一個(gè)ConcreteState實(shí)例只需知道本狀態(tài)后可能過(guò)渡到哪些狀態(tài)及相應(yīng)條件即可。 傳統(tǒng)的面向過(guò)程方法則要求用戶(hù)流程的具體細(xì)節(jié)了如指掌。n 實(shí)現(xiàn)了與狀態(tài)相關(guān)的行為的局部化 n 使用狀態(tài)模式將狀態(tài)的切換邏輯放到STATE的派
55、生類(lèi)中,動(dòng)作的實(shí)現(xiàn)供派生類(lèi)進(jìn)行調(diào)用,實(shí)現(xiàn)了邏輯和動(dòng)作的解耦。7.8 訪問(wèn)者模式(Visitor)一.訪問(wèn)者模式的由來(lái)二.訪問(wèn)者模式的意圖及適用性三.訪問(wèn)者模式的結(jié)構(gòu)及參與者四.應(yīng)用舉例五.效果說(shuō)明AA1A2A2m()A1m()A1A2A2A1A1A1IFListi is A1 Listi.A1m()If Listi is A2 Listi.A2m()ListAA1A2A2m()A1m()A1A2A2A1A1A1Listi.Am()List思考:能不能有一個(gè)統(tǒng)一的訪問(wèn)方法?某位同學(xué)的解決辦法Ma(A *a) if a is A1 a.a1m() if a is A2 a.a2m Ma() a1(
56、)A1m()Ma()A2m()A2m()AA1A2A1A2A2A1A1A1Listi.ma(this)List思考:這樣做的缺陷?Ma()Ma()A3m()A3m()A3Class visitor visit(A1 a) a.a1m() visit(A2 a) a.a2m Ma()A1m()Ma()A2m()AA1A2A1A2A2A1A1A1Listi.Am(this)List思考:這樣做的缺陷?Ma(A *a) ? 抽象AA1A2Visitor-Visit(A1 a)a.A1m()Visit(A2 a)a.A2m()Accept(visitor v) v.visit(this)A1m()A1
57、A2A2A1A1A1Listi.accept(visitor)List7.8.1 訪問(wèn)者模式的由來(lái)l如何擴(kuò)展一個(gè)現(xiàn)有的類(lèi)層次結(jié)構(gòu)來(lái)實(shí)現(xiàn)新行為?一 般的方法是給類(lèi)添加新的方法。l但是萬(wàn)一新行為和現(xiàn)有對(duì)象模型不兼容怎么辦?l還有,類(lèi)層次結(jié)構(gòu)設(shè)計(jì)人員可能無(wú)法預(yù)知以后開(kāi)發(fā) 過(guò)程中將會(huì)需要哪些功能。 l還有,如果已有的類(lèi)層次結(jié)構(gòu)不允許修改代碼,怎 么能擴(kuò)展行為呢? 7.8.2 訪問(wèn)者模式的意圖和適用性l模式的意圖作用于某個(gè)對(duì)象群中各個(gè)對(duì)象的操作。它可以使你在不改變這些對(duì)象本身的情況下,定義作用于這些對(duì)象的新操作。 7.8.2 訪問(wèn)者模式的意圖和適用性l在下面的四種情況下均可使用Visitor模式:l1
58、一個(gè)對(duì)象結(jié)構(gòu)包含很多類(lèi)對(duì)象,它們有不同的接口,而你想對(duì)這些對(duì)象實(shí)施一些依賴(lài)于其具體類(lèi)的操作。l2 需要對(duì)一個(gè)對(duì)象結(jié)構(gòu)中的對(duì)象進(jìn)行很多不同的并且不相關(guān)的操作,而你想避免讓這些操作“污染”這些對(duì)象的類(lèi)。Visitor使得你可以將相關(guān)的操作集中起來(lái)定義在一個(gè)類(lèi)中。7.8.2 訪問(wèn)者模式的意圖適用性l3 當(dāng)該對(duì)象結(jié)構(gòu)被很多應(yīng)用共享時(shí),用Visitor模式讓每個(gè)應(yīng)用僅包含需要用到的操作。l4 定義對(duì)象結(jié)構(gòu)的類(lèi)很少改變,但經(jīng)常需要在此結(jié)構(gòu)上定義新的操作。改變對(duì)象結(jié)構(gòu)類(lèi)需要重定義對(duì)所有訪問(wèn)者的接口,這可能需要很大的代價(jià)。如果對(duì)象結(jié)構(gòu)類(lèi)經(jīng)常改變,那么可能還是在這些類(lèi)中定義這些操作較好。7.8.3 訪問(wèn)者模式的
59、結(jié)構(gòu)和參與者l訪問(wèn)者模式結(jié)構(gòu)圖7.8.3 訪問(wèn)者模式的結(jié)構(gòu)和參與者 Visitorl 訪問(wèn)者角色(Visitor):為該對(duì)象結(jié)構(gòu)(ObjectStructure)中的具體元素提供一個(gè)訪問(wèn)操作接口。該操作接口的名字和參數(shù)標(biāo)識(shí)了要訪問(wèn)的具體元素角色。這樣訪問(wèn)者就可以通過(guò)該元素角色的特定接口直接訪問(wèn)它。l 具體訪問(wèn)者角色(ConcreteVisitor):實(shí)現(xiàn)Vistor接口的操作。l 元素角色( Element ):該接口定義一個(gè)accept操作接受具體的訪問(wèn)者。l 具體元素角色(ConcreteElement):實(shí)現(xiàn)Element的accept操作。l 對(duì)象結(jié)構(gòu)角色(ObjectStructur
60、e):這是使用訪問(wèn)者模式必備的角色。它要具備以下特征:能枚舉它的元素;可以提供一個(gè)高層的接口以允許該訪問(wèn)者訪問(wèn)它的元素;可以是一個(gè)復(fù)合(組合模式)或是一個(gè)集合,如一個(gè)列表或一個(gè)無(wú)序集合。7.8.4 應(yīng)用舉例先看以下代碼: public interface ITest1 /定義接口ITest1 String GetStr1();public class Test1:ITest1 /Test1實(shí)現(xiàn)接口ITest1 public String GetStr1() return “Test1”;public interface ITest2 /定義接口ITest2 String GetStr2();public class Test2:ITest2 /Test2實(shí)現(xiàn)接口ITest
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 北海市檢測(cè)合同范例
- 代建房屋租賃合同范本
- 企業(yè)消防合同范本
- 主體變更合同范本
- 個(gè)人建設(shè)工程合同范本
- 農(nóng)村房屋驗(yàn)收合同范本
- 辦證代理合同范本
- 代理土地合同范本
- 乳膠卷材供貨合同范本
- 加工輔料采購(gòu)合同范本
- 滲漉法胡鵬講解
- 【道 法】學(xué)會(huì)自我保護(hù)+課件-2024-2025學(xué)年統(tǒng)編版道德與法治七年級(jí)下冊(cè)
- 2025屆高考英語(yǔ)讀后續(xù)寫(xiě)提分技巧+講義
- 買(mǎi)房協(xié)議書(shū)樣板電子版
- 2024年無(wú)錫科技職業(yè)學(xué)院高職單招數(shù)學(xué)歷年參考題庫(kù)含答案解析
- 河南航空港發(fā)展投資集團(tuán)有限公司2025年社會(huì)招聘題庫(kù)
- 綿陽(yáng)市高中2022級(jí)(2025屆)高三第二次診斷性考試(二診)語(yǔ)文試卷(含答案)
- 常州初三強(qiáng)基數(shù)學(xué)試卷
- 《吞咽障礙膳食營(yíng)養(yǎng)管理規(guī)范》(T-CNSS 013-2021)
- 《經(jīng)濟(jì)學(xué)的研究方法》課件
- 仁愛(ài)七年級(jí)下冊(cè)英語(yǔ)教學(xué)計(jì)劃
評(píng)論
0/150
提交評(píng)論