設計模式

閱讀(21991) 更新時間(2022-04-13)

設計模式(Design pattern)是一套被重複使用、多數人知曉的、經過分類編目的、程式碼設計經驗的總結。使用設計模式是為了可重複使用程式碼、讓程式碼更容易被他人理解、保證程式碼可靠性。毫無疑問,設計模式於己於他人於系統都是多贏的;設計模式使程式碼編寫真正工程化;設計模式是軟體工程的基石脈絡,如同大廈的結構一樣。


设计模式(英语 design pattern)是对面向对象设计中反复出现的问题的解决方案。这个术语是在1990年代由Erich Gamma等人从建筑设计领域引入到计算机科学中来的。这个术语的含义还存有争议。算法不是设计模式,因为算法致力于解决问题而非设计问题。设计模式通常描述了一组相互紧密作用的类与对象。设计模式提供一种讨论软件设计的公共语言,使得熟练设计者的设计经验可以被初学者和其他设计者掌握。设计模式还为软件重构提供了目标。

随着软件开发社群对设计模式的兴趣日益增长,已经出版了一些相关的专著,定期召开相应的研讨会,而且Ward Cunningham为此发明了WikiWiki用来交流设计模式的经验。

提示:本教程将通过 Java 实例,一步一步向您讲解设计模式的概念。所以你需要对Java知识有所了解。

表述格式

表述一个软件设计模式的格式根据作者的不同,划分和名称等都会有所不同。常用的GoF描述模式的格式大致分为以下这些部分:

  • 模式名:每一个模式都有自己的名字,模式的名字使得我们可以讨论我们的设计。

  • 问题:在面向对象的系统设计过程中反复出现的特定场合,它导致我们采用某个模式。

  • 解决方案:上述问题的解决方案,其内容给出了设计的各个组成部分,它们之间的关系、职责划分和协作方式。

  • 别名:一个模式可以有超过一个以上的名称。这些名称应该要在这一节注明。

  • 动机:在哪种情况使用该模式,是本节提供的方案(包括问题与来龙去脉)的责任。

  • 适用性:模式适用于哪些情况、模式的背景等等。

  • 结构:这部分常用类图与交互图阐述此模式。

  • 参与者:这部分提供一份本模式用到的类与对象清单,与它们在设计下扮演的角色。

  • 合作:描述在此模式下,类与对象间的交互。

  • 影响:采用该模式对软件系统其他部分的影响,比如对系统的扩充性、可移植性的影响。影响也包括负面的影响。这部分应描述使用本模式后的结果、副作用、与权衡(trade-off)

  • 实现:这部分应描述实现该模式、该模式的部分方案、实现该模式的可能技术、或者建议实现模式的方法。

  • 示例:简略描绘出如何以编程语言来使用模式。

  • 已知应用:业界已知的实现示例。

  • 相关模式:这部分包括其他相关模式,以及与其他类似模式的不同。

提示:我們的《設計模式》教學將幫助您學習所有設計模式知識。如果你有任何疑問,請前往PHP中文網社群提出你的問題,會有熱心網友為你解答。

模式原則

大家都開始注意設計模式。那麼,到底我們為什麼要用設計模式呢?這麼多設計模式為什麼要怎麼設計呢?

說實話,以前我還真沒搞清楚。就是看大家一口一個"Design pattern",心就有點發虛。於是就買了本"四人幫"的設計模式,結果看得似懂非懂:看得時候好像是懂了,過一會兒就忘了。可能是本人比較"愚鈍"吧:))最近,有了點感悟。 "獨樂不如眾樂",與大家分享一下,還望指教! 

為什麼要提倡"Design Pattern"呢?根本原因是為了程式碼復用,增加可維護性。

那麼要怎麼實現程式碼重複使用呢? OO界有前輩的幾個原則:"開-閉"原則(Open Closed Principal)、里氏代換原則、合成復用原則。設計模式就是實現了這些原則,因此達到了程式碼重複使用、增加可維護性的目的。

  • 開-閉原則

此原則是由"Bertrand Meyer"提出的。原文是:"Software entities should be open for extension,but closed for modification"。是說模組應對擴充開放,而對修改關閉。模組應盡量在不修改原(是"原",指原來的程式碼)程式碼的情況下進行擴充。那要怎麼擴展呢?我們看工廠模式"factory pattern":假設中關村有一個賣盜版盤和毛片的小子,我們給他設計一"光碟銷售管理軟體"。我們應該先設計一"光碟"介面。如圖:【pre】______________|<>|| 光碟 ||_____________|| 賣() || ||_____________|【/pre】而盜版盤和毛片是其子類。小子透過"DiscFactory"來管理這些光碟。代碼為:

publicclassDiscFactory{
publicstatic光盘
getDisc(Stringname){
return(光盘)Class.forName(name).getInstance();
}
}

有人要買盜版盤,要怎麼實現?

public class 小子{ public static void main(String【】 args){ 光碟d=DiscFactory.getDisc("盜版碟"); 光碟.賣(); } }

#如果有有一天,這小子良心發現了,開始賣正版軟體。沒關係,我們只要再創建一個"光碟"的子類"正版軟體"就可以了。不需要修改原結構和程式碼。怎麼樣?對擴充開放,對修改關閉。 "開-閉原則" 工廠模式是對具體產品進行擴展,有的項目可能需要更多的擴展性,要對這個"工廠"也進行擴展,那就成了"抽象工廠模式"。

  • 里氏代換原則

里氏代換原則是由"Barbara Liskov"提出的。如果呼叫的是父類別的話,那麼換成子類別也完全可以運作。例如: 光碟 d=new 盜版盤(); d.賣(); 要將"盜版盤"類改為"毛片"類,沒問題,完全可以運行。 Java編譯程式會檢查程式是否符合里氏代換原則。還記得java繼承的一個原則嗎?子類別override方法的存取權限不能小於父類別對應方法的存取權限。例如"光碟"中的方法"賣"存取權限是"public",那麼"盜版盤"和"毛片"中的"賣"方法就不能是protected或private,編譯不能通過。為什麼要這樣呢?你想啊:如果"盜版盤"的"賣"方法是private。那麼下面這段程式碼就不能執行了: 光碟 d=new 盜版盤(); d.賣();可以說:里氏代換原則是繼承復用的一個基礎。

  • 合成復用原則

就是要少用繼承,多用合成關係來實現。我曾經這樣寫過程式:有幾個類別要與資料庫打交道,就寫了一個資料庫操作的類,然後別的跟資料庫打交道的類別都繼承這個。結果後來,我修改了資料庫操作類別的一個方法,各個類別都需要改動。 "牽一發而動全身"!物件導向是要把波動限制在盡量小的範圍。

在Java中,應盡量針對Interface編程,而非實作類別。這樣,更換子類別不會影響呼叫它方法的程式碼。要讓各個類別盡可能少的跟別人聯繫,"不要與陌生人說話"。這樣,城門失火,才不至於殃及池魚。擴展性和維護性才能提高

了解這些原則,再看設計模式,只是在具體問題上怎麼實現這些原則而已。張無忌學太極拳,忘了所有招式,打倒了"玄冪二老",所謂"心中無招"。設計模式可謂招數,如果先學通了各種模式,又忘掉了所有模式而隨心所欲,可謂OO之最高境界。呵呵,搞笑,搞笑! (JR)

依賴倒轉原則抽像不應該依賴與細節,細節應依

  • 依賴倒轉原則

  • #要針對介面編程,而不是針對實作編程。傳遞參數,或在組合聚合關係中,盡量引用層次高的類別。主要是在建構對象時可以動態的創建各種具體對象,當然如果一些具體類比較穩定,就不必在弄一個抽象類做它的父類,這樣有畫舌添足的感覺接口隔離原則定制服務的例子,每一

介面隔離原則

  • 一種角色,不多不少,不干不該幹的事,該幹的事都要乾抽象類別抽象類別不會有實例

    #######抽象類別###

類別為子類別繼承,一般包含這個系的共同屬性和方法。注意:好的繼承關係中,只有葉節點是具體類,其他節點應該都是抽象類,也就是說具體類別是不被繼承的。將盡可能多的共同程式碼放到抽象類別中。 7 迪米特法則最少知識原則。不要和陌生人說話。

本設計模式教學手冊涵蓋的內容

本設計模式教學涵蓋所有設計模式介紹,包含了工廠模式(Factory Pattern)、抽象工廠模式(Abstract Factory Pattern)、單例模式(Singleton Pattern)、建造者模式(Builder Pattern)、原型模式(Prototype Pattern)等等。

提示:本教學的每一章都包含了許多Java實例,透過這些範例將幫助您更好地學習理解設計模式。

最新章節


传输对象模式 2016-10-18
服务定位器模式 2016-10-18
拦截过滤器模式 2016-10-18
前端控制器模式 2016-10-18
数据访问对象模式 2016-10-18
组合实体模式 2016-10-18
业务代表模式 2016-10-18
MVC 模式 2016-10-18