亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? 0122.htm

?? 關于java的開發文檔
?? HTM
?? 第 1 頁 / 共 4 頁
字號:
<html>

<head>
<title>新時代軟件教程:操作系統 主頁制作 服務器 設計軟件 網絡技術 編程語言 文字編輯</title>
<meta http-equiv="Content-Type" content="text/html; charset=gb2312">
<style>
<!--
body, table {font-size: 9pt; font-family: 宋體}
a {text-decoration:none}
a:hover {color: red;text-decoration:underline}
.1  {background-color: rgb(245,245,245)}
-->
</style>
</head>
<p align="center"><script src="../../1.js"></script></a>
    <p align="center"><big><strong>第16章 設計范式</strong></big></p>

<div align="right">---(原著/Bruce Eckel 翻譯/Trans Bot)</div>

<br>
本章要向大家介紹重要但卻并不是那么傳統的“范式”(Pattern)程序設計方法。<br>
在向面向對象程序設計的演化過程中,或許最重要的一步就是“設計范式”(Design 
Pattern)的問世。它在由Gamma,Helm和Johnson編著的《Design Patterns》一書中被定義成一個“里程碑”(該書由Addison-Wesley于1995年出版,注釋①)。那本書列出了解決這個問題的23種不同的方法。在本章中,我們準備伴隨幾個例子揭示出設計范式的基本概念。這或許能激起您閱讀《Design 
Pattern》一書的欲望。事實上,那本書現在已成為幾乎所有OOP程序員都必備的參考書。<br>
<br>
①:但警告大家:書中的例子是用C++寫的。<br>
<br>
本章的后一部分包含了展示設計進化過程的一個例子,首先是比較原始的方案,經過逐漸發展和改進,慢慢成為更符合邏輯、更為恰當的設計。該程序(仿真垃圾分類)一直都在進化,可將這種進化作為自己設計方案的一個原型——先為特定的問題提出一個適當的方案,再逐步改善,使其成為解決那類問題一種最靈活的方案。<br>
<br>
16.1 范式的概念<br>
在最開始,可將范式想象成一種特別聰明、能夠自我適應的手法,它可以解決特定類型的問題。也就是說,它類似一些需要全面認識某個問題的人。在了解了問題的方方面面以后,最后提出一套最通用、最靈活的解決方案。具體問題或許是以前見到并解決過的。然而,從前的方案也許并不是最完善的,大家會看到它如何在一個范式里具體表達出來。<br>
盡管我們稱之為“設計范式”,但它們實際上并不局限于設計領域。思考“范式”時,應脫離傳統意義上分析、設計以及實施的思考方式。相反,“范式”是在一個程序里具體表達一套完整的思想,所以它有時可能出現在分析階段或者高級設計階段。這一點是非常有趣的,因為范式具有以代碼形式直接實現的形式,所以可能不希望它在低級設計或者具體實施以前顯露出來(而且事實上,除非真正進入那些階段,否則一般意識不到自己需要一個范式來解決問題)。<br>
范式的基本概念亦可看成是程序設計的基本概念:添加一層新的抽象!只要我們抽象了某些東西,就相當于隔離了特定的細節。而且這后面最引人注目的動機就是“將保持不變的東西身上發生的變化孤立出來”。這樣做的另一個原因是一旦發現程序的某部分由于這樣或那樣的原因可能發生變化,我們一般都想防止那些改變在代碼內部繁衍出其他變化。這樣做不僅可以降低代碼的維護代價,也更便于我們理解(結果同樣是降低開銷)。<br>
為設計出功能強大且易于維護的應用項目,通常最困難的部分就是找出我稱之為“領頭變化”的東西。這意味著需要找出造成系統改變的最重要的東西,或者換一個角度,找出付出代價最高、開銷最大的那一部分。一旦發現了“領頭變化”,就可以為自己定下一個焦點,圍繞它展開自己的設計。<br>
所以設計范式的最終目標就是將代碼中變化的內容隔離開。如果從這個角度觀察,就會發現本書實際已采用了一些設計范式。舉個例子來說,繼承可以想象成一種設計范式(類似一個由編譯器實現的)。在都擁有同樣接口(即保持不變的東西)的對象內部,它允許我們表達行為上的差異(即發生變化的東西)。合成亦可想象成一種范式,因為它允許我們修改——動態或靜態——用于實現類的對象,所以也能修改類的運作方式。<br>
在《Design Patterns》一書中,大家還能看到另一種范式:“繼承器”(即Iterator,Java 
1.0和1.1不負責任地把它叫作Enumeration,即“枚舉”;Java1.2的集合則改回了“繼承器”的稱呼)。當我們在集合里遍歷,逐個選擇不同的元素時,繼承器可將集合的實施細節有效地隱藏起來。利用繼承器,可以編寫出通用的代碼,以便對一個序列里的所有元素采取某種操作,同時不必關心這個序列是如何構建的。這樣一來,我們的通用代碼即可伴隨任何能產生繼承器的集合使用。<br>
<br>
16.1.1 單子<br>
或許最簡單的設計范式就是“單子”(Singleton),它能提供對象的一個(而且只有一個)實例。單子在Java庫中得到了應用,但下面這個例子顯得更直接一些:<br>
<br>
909-910頁程序<br>
<br>
創建單子的關鍵就是防止客戶程序員采用除由我們提供的之外的任何一種方式來創建一個對象。必須將所有構建器都設為private(私有),而且至少要創建一個構建器,以防止編譯器幫我們自動同步一個默認構建器(它會自做聰明地創建成為“友好的”——friendly,而非private)。<br>
此時應決定如何創建自己的對象。在這兒,我們選擇了靜態創建的方式。但亦可選擇等候客戶程序員發出一個創建請求,然后根據他們的要求動態創建。不管在哪種情況下,對象都應該保存為“私有”屬性。我們通過公用方法提供訪問途徑。在這里,getHandle()會產生指向Singleton的一個句柄。剩下的接口(getValue()和setValue())屬于普通的類接口。<br>
Java也允許通過克隆(Clone)方式來創建一個對象。在這個例子中,將類設為final可禁止克隆的發生。由于Singleton是從Object直接繼承的,所以clone()方法會保持protected(受保護)屬性,不能夠使用它(強行使用會造成編譯期錯誤)。然而,假如我們是從一個類結構中繼承,那個結構已經過載了clone()方法,使其具有public屬性,并實現了Cloneable,那么為了禁止克隆,需要過載clone(),并擲出一個CloneNotSupportedException(不支持克隆違例),就象第12章介紹的那樣。亦可過載clone(),并簡單地返回this。那樣做會造成一定的混淆,因為客戶程序員可能錯誤地認為對象尚未克隆,仍然操縱的是原來的那個。<br>
注意我們并不限于只能創建一個對象。亦可利用該技術創建一個有限的對象池。但在那種情況下,可能需要解決池內對象的共享問題。如果不幸真的遇到這個問題,可以自己設計一套方案,實現共享對象的登記與撤消登記。<br>
<br>
16.1.2 范式分類<br>
《Design Patterns》一書討論了23種不同的范式,并依據三個標準分類(所有標準都涉及那些可能發生變化的方面)。這三個標準是:<br>
(1) 
創建:對象的創建方式。這通常涉及對象創建細節的隔離,這樣便不必依賴具體類型的對象,所以在新添一種對象類型時也不必改動代碼。<br>
(2) 
結構:設計對象,滿足特定的項目限制。這涉及對象與其他對象的連接方式,以保證系統內的改變不會影響到這些連接。<br>
(3) 
行為:對程序中特定類型的行動進行操縱的對象。這要求我們將希望采取的操作封裝起來,比如解釋一種語言、實現一個請求、在一個序列中遍歷(就象在繼承器中那樣)或者實現一種算法。本章提供了“觀察器”(Observer)和“訪問器”(Visitor)的范式的例子。<br>
<br>
《Design Patterns》為所有這23種范式都分別使用了一節,隨附的還有大量示例,但大多是用C++編寫的,少數用Smalltalk編寫(如看過這本書,就知道這實際并不是個大問題,因為很容易即可將基本概念從兩種語言翻譯到Java里)。現在這本書并不打算重復《Design 
Patterns》介紹的所有范式,因為那是一本獨立的書,大家應該單獨閱讀。相反,本章只準備給出一些例子,讓大家先對范式有個大致的印象,并理解它們的重要性到底在哪里。<br>
<br>
16.2 觀察器范式<br>
觀察器(Observer)范式解決的是一個相當普通的問題:由于某些對象的狀態發生了改變,所以一組對象都需要更新,那么該如何解決?在Smalltalk的MVC(模型-視圖-控制器)的“模型-視圖”部分中,或在幾乎等價的“文檔-視圖結構”中,大家可以看到這個問題。現在我們有一些數據(“文檔”)以及多個視圖,假定為一張圖(Plot)和一個文本視圖。若改變了數據,兩個視圖必須知道對自己進行更新,而那正是“觀察器”要負責的工作。這是一種十分常見的問題,它的解決方案已包括進標準的java.util庫中。<br>
在Java中,有兩種類型的對象用來實現觀察器范式。其中,Observable類用于跟蹤那些當發生一個改變時希望收到通知的所有個體——無論“狀態”是否改變。如果有人說“好了,所有人都要檢查自己,并可能要進行更新”,那么Observable類會執行這個任務——為列表中的每個“人”都調用notifyObservers()方法。notifyObservers()方法屬于基礎類Observable的一部分。<br>
在觀察器范式中,實際有兩個方面可能發生變化:觀察對象的數量以及更新的方式。也就是說,觀察器范式允許我們同時修改這兩個方面,不會干擾圍繞在它周圍的其他代碼。<br>
下面這個例子類似于第14章的ColorBoxes示例。箱子(Boxes)置于一個屏幕網格中,每個都初始化一種隨機的顏色。此外,每個箱子都“實現”(implement)了“觀察器”(Observer)接口,而且隨一個Observable對象進行了注冊。若點擊一個箱子,其他所有箱子都會收到一個通知,指出一個改變已經發生。這是由于Observable對象會自動調用每個Observer對象的update()方法。在這個方法內,箱子會檢查被點中的那個箱子是否與自己緊鄰。若答案是肯定的,那么也修改自己的顏色,保持與點中那個箱子的協調。<br>
<br>
912-914頁程序<br>
<br>
如果是首次查閱Observable的聯機幫助文檔,可能會多少感到有些困惑,因為它似乎表明可以用一個原始的Observable對象來管理更新。但這種說法是不成立的;大家可自己試試——在BoxObserver中,創建一個Observable對象,替換BoxObservable對象,看看會有什么事情發生。事實上,什么事情也不會發生。為真正產生效果,必須從Observable繼承,并在衍生類代碼的某個地方調用setChanged()。這個方法需要設置“changed”(已改變)標志,它意味著當我們調用notifyObservers()的時候,所有觀察器事實上都會收到通知。在上面的例子中,setChanged()只是簡單地在notifyObservers()中調用,大家可依據符合實際情況的任何標準決定何時調用setChanged()。<br>
BoxObserver包含了單個Observable對象,名為notifier。每次創建一個OCBox對象時,它都會同notifier聯系到一起。在OCBox中,只要點擊鼠標,就會發出對notifyObservers()方法的調用,并將被點中的那個對象作為一個參數傳遞進去,使收到消息(用它們的update()方法)的所有箱子都能知道誰被點中了,并據此判斷自己是否也要變動。通過notifyObservers()和update()中的代碼的結合,我們可以應付一些非常復雜的局面。<br>
在notifyObservers()方法中,表面上似乎觀察器收到通知的方式必須在編譯期間固定下來。然而,只要稍微仔細研究一下上面的代碼,就會發現BoxObserver或OCBox中唯一需要留意是否使用BoxObservable的地方就是創建Observable對象的時候——從那時開始,所有東西都會使用基本的Observable接口。這意味著以后若想更改通知方式,可以繼承其他Observable類,并在運行期間交換它們。<br>
<br>
16.3 模擬垃圾回收站<br>
這個問題的本質是若將垃圾丟進單個垃圾筒,事實上是未經分類的。但在以后,某些特殊的信息必須恢復,以便對垃圾正確地歸類。在最開始的解決方案中,RTTI扮演了關鍵的角色(詳見第11章)。<br>
這并不是一種普通的設計,因為它增加了一個新的限制。正是這個限制使問題變得非常有趣——它更象我們在工作中碰到的那些非常麻煩的問題。這個額外的限制是:垃圾抵達垃圾回收站時,它們全都是混合在一起的。程序必須為那些垃圾的分類定出一個模型。這正是RTTI發揮作用的地方:我們有大量不知名的垃圾,程序將正確判斷出它們所屬的類型。<br>
<br>
915-917頁程序<br>
<br>
要注意的第一個地方是package語句:<br>
package c16.recyclea;<br>
這意味著在本書采用的源碼目錄中,這個文件會被置入從c16(代表第16章的程序)分支出來的recyclea子目錄中。第17章的解包工具會負責將其置入正確的子目錄。之所以要這樣做,是因為本章會多次改寫這個特定的例子;它的每個版本都會置入自己的“包”(package)內,避免類名的沖突。<br>
其中創建了幾個Vector對象,用于容納Trash句柄。當然,Vector實際容納的是Object(對象),所以它們最終能夠容納任何東西。之所以要它們容納Trash(或者從Trash衍生出來的其他東西),唯一的理由是我們需要謹慎地避免放入除Trash以外的其他任何東西。如果真的把某些“錯誤”的東西置入Vector,那么不會在編譯期得到出錯或警告提示——只能通過運行期的一個違例知道自己已經犯了錯誤。<br>
Trash句柄加入后,它們會丟失自己的特定標識信息,只會成為簡單的Object句柄(上溯造型)。然而,由于存在多形性的因素,所以在我們通過Enumeration 
sorter調用動態綁定方法時,一旦結果Object已經造型回Trash,仍然會發生正確的行為。sumValue()也用一個Enumeration對Vector中的每個對象進行操作。<br>
表面上持,先把Trash的類型上溯造型到一個集合容納基礎類型的句柄,再回過頭重新下溯造型,這似乎是一種非常愚蠢的做法。為什么不只是一開始就將垃圾置入適當的容器里呢?(事實上,這正是撥開“回收”一團迷霧的關鍵)。在這個程序中,我們很容易就可以換成這種做法,但在某些情況下,系統的結構及靈活性都能從下溯造型中得到極大的好處。<br>
該程序已滿足了設計的初衷:它能夠正常工作!只要這是個一次性的方案,就會顯得非常出色。但是,真正有用的程序應該能夠在任何時候解決問題。所以必須問自己這樣一個問題:“如果情況發生了變化,它還能工作嗎?”舉個例子來說,厚紙板現在是一種非常有價值的可回收物品,那么如何把它集成到系統中呢(特別是程序很大很復雜的時候)?由于前面在switch語句中的類型檢查編碼可能散布于整個程序,所以每次加入一種新類型時,都必須找到所有那些編碼。若不慎遺漏一個,編譯器除了指出存在一個錯誤之外,不能再提供任何有價值的幫助。<br>
RTTI在這里使用不當的關鍵是“每種類型都進行了測試”。如果由于類型的子集需要特殊的對待,所以只尋找那個子集,那么情況就會變得好一些。但假如在一個switch語句中查找每一種類型,那么很可能錯過一個重點,使最終的代碼很難維護。在下一節中,大家會學習如何逐步對這個程序進行改進,使其顯得越來越靈活。這是在程序設計中一種非常有意義的例子。<br>
<br>

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
国产精品久久久久久亚洲毛片| 欧美日韩一区二区电影| 久久久亚洲精品石原莉奈| 免费人成网站在线观看欧美高清| 欧美日韩亚洲综合一区二区三区| 亚洲国产视频一区二区| 欧美日韩精品一区二区天天拍小说| 一区二区三区精品在线观看| 在线观看日韩av先锋影音电影院| 亚洲综合久久久| 91精品国产色综合久久久蜜香臀| 精品制服美女久久| 欧美激情一区在线观看| 91啦中文在线观看| 日韩国产在线一| 久久亚洲精华国产精华液| 成人免费看视频| 亚洲一区免费在线观看| 欧美一区二区黄| 国产91在线观看| 亚洲一区二区在线观看视频| 日韩精品在线网站| av在线不卡免费看| 天堂一区二区在线| 久久久精品免费观看| 91在线云播放| 美女一区二区在线观看| 国产精品久久久久永久免费观看 | 国产99久久久久久免费看农村| 欧美高清在线视频| 7777精品伊人久久久大香线蕉超级流畅| 麻豆国产欧美一区二区三区| 亚洲国产成人一区二区三区| 欧美色视频在线| 国产精品夜夜爽| 五月天国产精品| 国产精品免费丝袜| 91精品免费在线观看| 99久久精品国产导航| 日韩精品国产欧美| 中文字幕在线一区二区三区| 欧美一区二区精品久久911| 99久久免费视频.com| 久久国产精品第一页| 一区二区激情小说| 国产拍欧美日韩视频二区| 91精品国产乱码| 色综合久久久久网| 国产jizzjizz一区二区| 日本不卡视频在线| 亚洲成人中文在线| 亚洲人成影院在线观看| 国产日韩欧美高清| 日韩女优av电影在线观看| 在线观看日韩电影| 91视频国产资源| 国产·精品毛片| 精品一区二区三区视频在线观看| 亚洲国产一区二区视频| 亚洲欧美日韩精品久久久久| 国产日韩精品一区二区三区在线| 51精品国自产在线| 欧美日韩一区久久| 欧美视频日韩视频在线观看| 91日韩一区二区三区| av网站一区二区三区| 高清成人在线观看| 国产jizzjizz一区二区| 国产精品18久久久久久久久久久久| 日本不卡视频一二三区| 日韩一区精品字幕| 亚洲超丰满肉感bbw| 性做久久久久久久免费看| 一区二区三区四区亚洲| 亚洲美女免费在线| 亚洲欧洲制服丝袜| 最新国产精品久久精品| 国产精品进线69影院| 亚洲视频你懂的| 亚洲男人天堂av| 亚洲最新视频在线播放| 午夜久久久久久久久| 天天色综合天天| 毛片一区二区三区| 国产精品综合一区二区三区| 国产伦精品一区二区三区免费迷| 国产剧情一区在线| 粉嫩aⅴ一区二区三区四区| 成人免费av资源| 91香蕉视频黄| 欧美午夜影院一区| 91精品国产综合久久久蜜臀图片 | 国产日韩三级在线| 日本一二三不卡| 亚洲色图制服丝袜| 亚洲午夜免费电影| 蜜臀久久99精品久久久画质超高清| 奇米色777欧美一区二区| 国内成人精品2018免费看| 欧美人xxxx| 国产精品久久久久久久久久久免费看| 国产婷婷色一区二区三区在线| 久久久综合视频| 国产精品理论片在线观看| 亚洲综合激情网| 蜜桃视频免费观看一区| 国产精品系列在线播放| 色偷偷久久一区二区三区| 91精品免费在线| 国产精品每日更新在线播放网址| 亚洲日穴在线视频| 日本不卡的三区四区五区| 九九国产精品视频| 91在线国产福利| 欧美男生操女生| 中文字幕精品一区二区精品绿巨人| 亚洲欧美日韩中文播放| 蜜桃精品在线观看| 成人久久18免费网站麻豆| 7777精品久久久大香线蕉| 国产精品久久久久永久免费观看| 天天爽夜夜爽夜夜爽精品视频| 国产一区二区三区在线观看免费视频 | 国产精品网友自拍| 午夜激情久久久| 成人网页在线观看| 欧美视频你懂的| 亚洲国产电影在线观看| 日韩av在线播放中文字幕| 成人免费的视频| 精品国产三级a在线观看| 亚洲欧美乱综合| 国产成人综合在线观看| 欧美精品在线观看播放| 国产精品高清亚洲| 蜜芽一区二区三区| 在线免费一区三区| 国产精品福利在线播放| 久久99精品国产麻豆婷婷| 欧美三级电影一区| 亚洲人xxxx| 成人h动漫精品一区二区| 日韩三级中文字幕| 亚洲成人www| 色国产精品一区在线观看| 国产欧美一区二区精品性| 免费av成人在线| 在线播放日韩导航| 亚洲国产精品久久艾草纯爱| 99久久精品费精品国产一区二区| 欧美经典一区二区三区| 国产在线观看免费一区| 精品成a人在线观看| 美国欧美日韩国产在线播放 | 日韩欧美一区二区免费| 亚洲国产精品麻豆| 日本高清不卡在线观看| 亚洲欧洲精品成人久久奇米网| 国产精品456露脸| 久久久国产综合精品女国产盗摄| 久久国产剧场电影| 欧美tickling挠脚心丨vk| 午夜精品久久久久久久久| 91麻豆成人久久精品二区三区| 久久精品男人的天堂| 国产麻豆欧美日韩一区| 精品日韩在线观看| 美女视频黄 久久| 日韩午夜激情av| 精品一区二区三区免费观看| 日韩欧美中文字幕一区| 免播放器亚洲一区| 精品久久国产老人久久综合| 久久电影国产免费久久电影| 精品日韩99亚洲| 激情综合网天天干| 久久久av毛片精品| 国产99一区视频免费| 国产精品女同一区二区三区| av一区二区不卡| 夜夜夜精品看看| 欧美老肥妇做.爰bbww| 日韩av高清在线观看| 精品国产1区2区3区| 国产成人免费视频一区| 中文字幕在线播放不卡一区| 91麻豆福利精品推荐| 日韩精品一二三四| 久久夜色精品国产噜噜av| 成人污视频在线观看| 亚洲国产精品久久久久秋霞影院| 欧美久久久久久久久久| 免费的成人av| 中文字幕av一区 二区| 色婷婷精品久久二区二区蜜臀av| 天天免费综合色| 久久久精品蜜桃| 欧美在线观看视频一区二区| 激情综合一区二区三区| 亚洲精品国产视频|