設(shè)計(jì)模式詳解——復(fù)合模式

前言
復(fù)合模式是指在一個(gè)解決方案中結(jié)合兩個(gè)或多個(gè)模式,以解決一般或重發(fā)發(fā)生的問題。由于設(shè)計(jì)模式比較多,所以復(fù)合出來的復(fù)合模式就更多了,這里關(guān)于復(fù)合模式就不再展開分析了,下面我們來通過一種非常普遍的復(fù)合模式,來簡單演示下復(fù)合模式的通常應(yīng)用。
MVC模式
關(guān)于MVC想必各位小伙伴絕對不陌生,凡是學(xué)過java web相關(guān)內(nèi)容的小伙伴,肯定都學(xué)過最基本的Model 2的MVC模式,也就是我們今天要分享的內(nèi)容,下面是MVC模式的模型圖:

其中Model模型層就是我們存取的數(shù)據(jù)對象,View試圖層表示需要呈現(xiàn)的試圖內(nèi)容,Controller控制器主要是用來操作模型和試圖的。
要點(diǎn)
MVC是復(fù)合模式,結(jié)合了觀察者模式、策略模式和組合模式模型使用觀察者模式,以便觀察者更新,同時(shí)保持兩者之間的解耦 控制器是試圖的策略,試圖可以使用不同的控制器實(shí)現(xiàn),得到不同的行為 視圖使用組合模式實(shí)現(xiàn)用戶界面,用戶界面通常組合了嵌套的組件,像面板、框架和按鈕等 這些模式攜手合作,把 MVC模型的三次解耦,這樣既可以保持設(shè)計(jì)干凈,又有彈性適配器模式用來將新的模型適配成已有的試圖和控制器 Model 2是MVC在Web上的應(yīng)用在 Mdodel 2中,控制器實(shí)現(xiàn)成了Servlet,而JSP/Html是視圖層
示例
模型層
模型層通常采用觀察者模式,更準(zhǔn)確地說是它和視圖層共同組成觀察者模式,當(dāng)數(shù)據(jù)數(shù)據(jù)模型發(fā)生變化時(shí)(被觀察對象),可以實(shí)時(shí)將結(jié)果反饋給視圖層(觀察者)。
使用觀察者模式,可以讓模型完全獨(dú)立于視圖和控制器,同一個(gè)模型可以使用不同的視圖,甚至可以使用多種視圖。
這里我們的代碼演示的是最基本的數(shù)據(jù)模型,也就是我們web開發(fā)中的bean:
public?class?StudentModel?{
????private?String?rollNo;
????private?String?name;
????public?String?getRollNo()?{
????????return?rollNo;
????}
????public?void?setRollNo(String?rollNo)?{
????????this.rollNo?=?rollNo;
????}
????public?String?getName()?{
????????return?name;
????}
????public?void?setName(String?name)?{
????????this.name?=?name;
????}
}
視圖層
視圖層在某些場景下,是可能需要同時(shí)顯示多種數(shù)據(jù)模型和數(shù)據(jù)展示組件的,所以通常情況下視圖會是一個(gè)或多個(gè)組件構(gòu)成,所以視圖層的實(shí)現(xiàn)是需要用到組合設(shè)計(jì)模式的。
這里我們也僅僅演示一種最簡單的視圖模型,它主要用來打印模型的基本信息:
public?class?StudentView?{
????public?void?printStudentDetails(String?studentName,?String?studentRollNo){
????????System.out.println("Student:?");
????????System.out.println("Name:?"?+?studentName);
????????System.out.println("Roll?No:?"?+?studentRollNo);
????}
}
控制層
視圖層和控制器實(shí)現(xiàn)了經(jīng)典的策略模式,視圖是一個(gè)對象,可以被調(diào)整使用不同的策略,而控制器提供了策略。視圖只關(guān)心系統(tǒng)中可視的部分,對于任何邏輯行為,都委托給控制器處理。
使用策略模式也可以讓視圖和模型之間的關(guān)系解耦,因?yàn)榭刂破髫?fù)責(zé)和模型交互來傳遞用戶的請求,對于實(shí)際請求是如何處理的,視圖并不需要關(guān)心。
這里的控制層也很簡單,由控制層直接操作視圖和模型,然后完成相關(guān)操作:
public?class?StudentController?{
????private?StudentModel?model;
????private?StudentView?view;
????public?StudentController(StudentModel?model,?StudentView?view){
????????this.model?=?model;
????????this.view?=?view;
????}
????public?void?setStudentName(String?name){
????????model.setName(name);
????}
????public?String?getStudentName(){
????????return?model.getName();
????}
????public?void?setStudentRollNo(String?rollNo){
????????model.setRollNo(rollNo);
????}
????public?String?getStudentRollNo(){
????????return?model.getRollNo();
????}
????public?void?updateView(){
????????view.printStudentDetails(model.getName(),?model.getRollNo());
????}
}
測試代碼
首先分別創(chuàng)建模型和視圖的示例,然后由控制器統(tǒng)一調(diào)度處理,最后視圖根據(jù)模型結(jié)果將數(shù)據(jù)予以展示:
?@Test
????public?void?testMVC()?{
????????//從數(shù)據(jù)庫獲取學(xué)生記錄
????????StudentModel?model?=?retrieveStudentFromDatabase();
????????//創(chuàng)建一個(gè)視圖:把學(xué)生詳細(xì)信息輸出到控制臺
????????StudentView?view?=?new?StudentView();
????????StudentController?controller?=?new?StudentController(model,?view);
????????controller.updateView();
????????//更新模型數(shù)據(jù)
????????controller.setStudentName("syske");
????????controller.updateView();
????}
????private?static?StudentModel?retrieveStudentFromDatabase()?{
????????StudentModel?student?=?new?StudentModel();
????????student.setName("云中志");
????????student.setRollNo("10");
????????return?student;
????}
由于MVC模式相比其他模式,我們都比較熟悉,所以這里就不再過多說明了。
總結(jié)
今天其實(shí)在MVC模式的示例中有點(diǎn)偷懶了,這一點(diǎn)我自己也明顯地感覺到了,設(shè)計(jì)模式確實(shí)學(xué)起來挺枯燥的,所以我在分析相關(guān)設(shè)計(jì)模式的時(shí)候,基本上都是按部就班的調(diào)調(diào),內(nèi)容上也是馬馬虎虎,整個(gè)過程根本就沒有我分享demo時(shí)的那種興奮感,但是退一步講,關(guān)于本次的設(shè)計(jì)模式分享,我覺得自己還是有收獲的:
首先我自己對設(shè)計(jì)模式有了整體的認(rèn)知,在此之前,很多設(shè)計(jì)模式可能只知道它的名字,關(guān)于它的設(shè)計(jì)原理和基本思想,根本就不了解,但是學(xué)了這么幾天之后,我覺得我已經(jīng)發(fā)現(xiàn)了我們常用框架中的設(shè)計(jì)模式,同時(shí)也覺得要不斷加強(qiáng)設(shè)計(jì)模式的實(shí)踐,希望能真正將這些東西應(yīng)用起來,這樣堅(jiān)持才有意義……
最后,用一句話結(jié)束今天的內(nèi)容:堅(jiān)持最大的意義就是堅(jiān)持,堅(jiān)持最大的動力也是堅(jiān)持,愿你的愿望終能實(shí)現(xiàn),愿你想去的地方終能到達(dá),每一步都是起點(diǎn),每一步都不是終點(diǎn)……大家共勉!感謝!晚安咯!
- END -