3atv精品不卡视频,97人人超碰国产精品最新,中文字幕av一区二区三区人妻少妇,久久久精品波多野结衣,日韩一区二区三区精品

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

设计模式相关

發(fā)布時間:2023/12/14 asp.net 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 设计模式相关 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

設計模式的七大原則

1. 單一職責原則

  • 核心思想:任何一個軟件模塊中,應該有且只有一個被修改的原因。
  • 栗子描述:Java程序猿非常喜歡把各種雜七雜八的功能性函數(shù)放到一個CommonService類里面,打 log 啊,各種查詢啊,鑒權啊。你要修改這個類的時候原因是不是很多?log 樣式要改,查詢條件要改,鑒權要加等等。咳咳,這就違反了單一職責原則啦。

怎么修改呢? 就是一個類只做好一類事情啊,如下圖。這樣你改任何一個類就只有一個理由了。比如你要改日志類,理由就是你要修改日志相關的功能。

總結一下單一職責原則:

  • 優(yōu)點:職責越單一,被修改的原因就越少,類的復雜度降低、可讀性提高、可維護性提高、擴展性提高、降低了變更引起的風險。
  • 缺點:如果類一味追求單一職責,有時會造成類的大爆炸。。。。。。。不過接口和方法肯定要遵循這個原則。
  • 注意:?單一職責原則提出了一個編寫程序的標準,用“職責”或“變化原因”來衡量接口或類設計得是否優(yōu)良,但是“職責”和“變化原因”都是不可以度量的,因項目和環(huán)境而異。

2. 依賴倒置原則

  • 核心思想:高層模塊不應該依賴底層模塊,二者都該依賴其抽象;抽象不應該依賴細節(jié);細節(jié)應該依賴抽象;
  • 說明:高層模塊就是調用端,低層模塊就是具體實現(xiàn)類。抽象就是指接口或抽象類。細節(jié)就是實現(xiàn)類。
  • 通俗來講:依賴倒置原則的本質就是通過抽象(接口或抽象類)使個各類或模塊的實現(xiàn)彼此獨立,互不影響,實現(xiàn)模塊間的松耦合。模塊之間交互應該依賴抽象,而非實現(xiàn)。
  • 優(yōu)點:大幅提高了可擴展性,降低耦合度,使代碼層次更加清晰。

client 直接調用具體實現(xiàn)類。模塊之間交互應該依賴抽象,而非實現(xiàn)。這里違背了依賴倒置原則,但在業(yè)務最初的時候不會有任何問題。

隨著業(yè)務的增加,需要加上非關系型數(shù)據(jù)庫NoSQL,還對接了些政府業(yè)務,對方用Oracle。

這樣做的問題很明顯,應用代碼強耦合了實現(xiàn)類,當需要切換新的數(shù)據(jù)源實現(xiàn)的話,就不得不扒開原來的應用代碼做修改了?出了bug是不是要背鍋了?Leader可能要給你送飛機票了。

如果按照依賴倒置原則呢? 定義接口,讓不同的實現(xiàn)類去實現(xiàn)這個接口。我們發(fā)現(xiàn)通過接口,實現(xiàn)了依賴倒置。業(yè)務代碼不再依賴實現(xiàn)類,而是依賴接口,而同時,實現(xiàn)類也依賴接口。模塊之間交互從依賴實現(xiàn)到依賴抽象。

如果要切換數(shù)據(jù)庫,改一行代碼直接搞定不香嗎?

DbService dbService = new MysqlService(); //改成NoSqlService, OracleService即可

還比較迷茫的童鞋可以移步《Java為什么要面向接口編程?》

3. 開閉原則

  • 核心思想:軟件實體應該「對擴展開放,對修改關閉」。
  • 說明:對擴展開放,意味著有新的需求或變化時,可以對現(xiàn)有代碼進行擴展以適應新的情況。對修改關閉,意味著類的設計一旦完成,就可以獨立完成工作,而不要對其進行任何修改。

還是上文數(shù)據(jù)庫接口的例子,當你需要新增數(shù)據(jù)庫時,原來的MySQL實現(xiàn)類無需改動,直接新增Oracle實現(xiàn)類和NoSQL實現(xiàn)類即可。也就是「對擴展開放,對修改關閉」。

4.接口隔離原則

  • 核心思想:多個特定的接口要好于一個寬泛用途的接口
  • 通俗來講:建立單一接口,不要建立龐大臃腫的接口,盡量細化接口,接口中的方法盡量少。也就是說,我們要為各個類建立專用的接口,而不要試圖去建立一個很龐大的接口供所有依賴它的類去調用。

類A通過接口interface依賴類B,類C通過接口interface依賴類D,如果接口interface對于類A和類B來說不是最小接口,則類B和類D必須去實現(xiàn)他們不需要的方法。

我們按照ISP原則改上一版。比如A不需要用到方法4,方法5。就可以選擇不依賴他們。

總結一下接口隔離原則:

  • 優(yōu)點:將外部依賴減到最少。你只需要依賴你需要的東西。這樣可以降低模塊之間的耦合。
  • 注意:
    • 接口盡量小,但是要有限度。對接口進行細化可以提高程序設計靈活性,但是如果過小,則會造成接口數(shù)量過多,使設計復雜化。所以一定要適度。
    • 提高內聚,減少對外交互。使接口用最少的方法去完成最多的事

5. 迪米特法則(Law of Demeter)

  • 核心思想:一個實體應當盡量少地與其他實體之間發(fā)生相互作用,使得系統(tǒng)功能模塊相對獨立

法則強調了以下兩點:

  • 第一: 從被依賴者的角度來說:只暴露應該暴露的方法或者屬性
  • 第二: 從依賴者的角度來說:只依賴應該依賴的對象

針對第一點,舉個栗子。當我們對計算機進行關機的時候,會先執(zhí)行一些列的動作:比如保存當前未完成的任務,然后是關閉相關的服務,接著是關閉顯示器,最后是關閉電源,這一系列的操作以此完成后,計算機才會正式被關閉。

如下代碼違背了迪米特原則(只暴露應該暴露的方法或者屬性)。我們看到close()方法已經封裝好了所有關機流程,其他方法沒有必要是public。只有close()方法才可以被其他調用computer的類可見。

針對第二點,舉個栗子。Sheldon和學霸Wang是好基友。某天Sheldon想認識個妹子,而學霸Wang和妹子認識。Sheldon如果直接去撩妹子,妹子會認為你是個渣男直接拒絕。所以Sheldon只能通過學霸Wang,由學霸Wang去傳遞信息給妹子(只依賴應該依賴的對象)。

6. 里氏替換原則

  • 核心思想:程序中的父類型都應該可以正確地被子類替換。
  • 原理:LSP 是繼承復用的基石,只有當子類可以替換掉父類,且軟件的功能不受到任何影響時,父類才能真正被復用,而子類也能夠在父類的基礎上增加新的行為。
  • 通俗來講:只要有父類出現(xiàn)的地方,都可以使用子類來替代。而且不會出現(xiàn)任何錯誤或者異常。但是反過來卻不行。子類出現(xiàn)的地方,不能使用父類來替代。例如:我喜歡動物,那我一定喜歡狗,因為狗是動物的子類;但是我喜歡狗,不能據(jù)此斷定我喜歡動物,因為我并不喜歡老鼠,雖然它也是動物。
  • 優(yōu)點:代碼共享,減少創(chuàng)建類的工作量。提高代碼的重用性,可擴展性。
  • 缺點:繼承是侵入性的。只要繼承,就必須擁有父類的所有屬性和方法;增強了耦合性。當父類的常量、變量和方法被修改時,需要考慮子類的修改
  • 注意:如果子類不能完整地實現(xiàn)父類的方法,或者父類的某些方法在子類中已經發(fā)生“畸變”,則建議斷開父子繼承關系 采用依賴、聚合、組合等關系代替繼承。
  • 最佳實踐:我們最好將父類定義為抽象類,并定義抽象方法,讓子類重新定義這些方法,當父類是抽象類時候,父類不能實例化

7.合成復用原則? ??
1) 找出應用中可能需要變化之處,把它們獨立出來,不要和那些不需要變化的代
碼混在一起。
2) 針對接口編程,而不是針對實現(xiàn)編程。
3) 為了交互對象之間的松耦合設計而努力

總結

  • 單一職責原則:提高代碼實現(xiàn)層的內聚度,降低實現(xiàn)單元彼此之間的耦合度
  • 開閉原則:提高代碼實現(xiàn)層的可擴展性,提高面臨改變的可適應性,降低修改代碼的冗余度
  • 里氏替換原則:提高代碼抽象層的可維護性,提高實現(xiàn)層代碼與抽象層的一致性
  • 接口隔離原則:提高代碼抽象層的內聚度,降低代碼實現(xiàn)層與抽象層的耦合度,降低代碼實現(xiàn)層的冗余度
  • 依賴倒置原則:降低代碼實現(xiàn)層由依賴關系產生的耦合度,提高代碼實現(xiàn)層的可測試性
  • 迪米特法則:一個對象應該對其他對象保持最少的了解。盡量降低類與類之間的耦合。
  • 合成復用原則:盡量使用合成/聚合的方式,而不是使用繼承

23種設計模式:23 種設計模式詳解(全23種)_雨中深巷的油紙傘的博客-CSDN博客_設計模式

注意事項:上面這篇文章有錯誤

總體來說設計模式分為三大類:

創(chuàng)建型模式,共五種:工廠方法模式、抽象工廠模式、單例模式、建造者模式、原型模式。

結構型模式,共七種:適配器模式、裝飾者模式、代理模式、外觀模式、橋接模式、組合模式、享元模式。

行為型模式,共十一種:策略模式、模板方法模式、觀察者模式、迭代器模式、責任鏈模式、命令模式、備忘錄模式、狀態(tài)模式、訪問者模式、中介者模式、解釋器模式。

A、創(chuàng)建模式(5種)
工廠方法模式、抽象工廠模式、單例模式、建造者模式(生成器模式)、原型模式。

1 工廠模式
鏈接:https://www.zhihu.com/question/27125796/answer/1615074467
來源:知乎

在我們平常創(chuàng)建對象的時候,都是通過關鍵字 new 來實現(xiàn)的,例:Class A = new A() 。

在一些情況下,要創(chuàng)建的對象需要一系列復雜的初始化操作,比如查配置文件、查數(shù)據(jù)庫表、初始化成員對象等,如果把這些邏輯放在構造函數(shù)中,會極大影響代碼的可讀性。不妨定義一個類來專門負責對象的創(chuàng)建,這樣的類就是工廠類,這種做法就是工廠模式,在任何需要生成復雜對象的地方,都可以使用工廠模式。

工廠模式包括:簡單工廠(不在23種設計模式中)、工廠方法和抽象工廠。

下面我們詳細嘮嗑下這幾類的用法和區(qū)別。

解決的問題

客戶端在調用時不想判斷來實例化哪一個類或者實例化的過程過于復雜。

在工廠模式中,具體的實現(xiàn)類創(chuàng)建過程對客戶端是透明的,客戶端不決定具體實例化哪一個類,而是交由“工廠”來實例化。

簡單工廠

? 結構

定義一個創(chuàng)建對象的接口,讓其子類自己決定實例化哪一個工廠類。

  • 抽象類或接口:定義了要創(chuàng)建的產品對象的接口。
  • 具體實現(xiàn):具有統(tǒng)一父類的具體類型的產品。
  • 產品工廠:負責創(chuàng)建產品對象。工廠模式同樣體現(xiàn)了開閉原則,將“創(chuàng)建具體的產品實現(xiàn)類”這部分變化的代碼從不變化的代碼“使用產品”中分離出來,之后想要新增產品時,只需要擴展工廠的實現(xiàn)即可。

? 使用

創(chuàng)建不同品牌的鍵盤

public interface Keyboard {void print();void input(Context context); }class HPKeyboard implements Keyboard {@Overridepublic void print() {//...輸出邏輯;}@Overridepublic void input(Context context) {//...輸入邏輯;}}class DellKeyboard implements Keyboard {@Overridepublic void print() {//...輸出邏輯;}@Overridepublic void input(Context context) {//...輸入邏輯;}}class LenovoKeyboard implements Keyboard {@Overridepublic void print() {//...輸出邏輯;}@Overridepublic void input(Context context) {//...輸入邏輯;}}/*** 工廠*/ public class KeyboardFactory {public Keyboard getInstance(int brand) {if(BrandEnum.HP.getCode() == brand){return new HPKeyboard();} else if(BrandEnum.LENOVO.getCode() == brand){return new LenovoKeyboard();} else if(BrandEnum.DELL.getCode() == brand){return new DellKeyboard();}return null;}public static void main(String[] args) {KeyboardFactory keyboardFactory = new KeyboardFactory();Keyboard lenovoKeyboard = KeyboardFactory.getInstance(BrandEnum.LENOVO.getCode());//...}}

? 缺陷

上面的工廠實現(xiàn)是一個具體的類KeyboardFactory,而非接口或者抽象類,getInstance()方法利用if-else創(chuàng)建并返回具體的鍵盤實例,如果增加新的鍵盤子類,鍵盤工廠的創(chuàng)建方法中就要增加新的if-else。這種做法擴展性差,違背了開閉原則,也影響了可讀性。所以,這種方式使用在業(yè)務較簡單,工廠類不會經常更改的情況。

工廠方法

為了解決上面提到的"增加if-else"的問題,可以為每一個鍵盤子類建立一個對應的工廠子類,這些工廠子類實現(xiàn)同一個抽象工廠接口。這樣,創(chuàng)建不同品牌的鍵盤,只需要實現(xiàn)不同的工廠子類。當有新品牌加入時,新建具體工廠繼承抽象工廠,而不用修改任何一個類。

? 結構

  • 抽象工廠:聲明了工廠方法的接口。
  • 具體產品工廠:實現(xiàn)工廠方法的接口,負責創(chuàng)建產品對象。
  • 產品抽象類或接口:定義工廠方法所創(chuàng)建的產品對象的接口。
  • 具體產品實現(xiàn):具有統(tǒng)一父類的具體類型的產品。

? 使用

public interface IKeyboardFactory {Keyboard getInstance(); }public class HPKeyboardFactory implements IKeyboardFactory {@Overridepublic Keyboard getInstance(){return new HPKeyboard();} }public class LenovoFactory implements IKeyboardFactory {@Overridepublic Keyboard getInstance(){return new LenovoKeyboard();} }public class DellKeyboardFactory implements IKeyboardFactory {@Overridepublic Keyboard getInstance(){return new DellKeyboard();} }

? 缺點

每一種品牌對應一個工廠子類,在創(chuàng)建具體鍵盤對象時,實例化不同的工廠子類。但是,如果業(yè)務涉及的子類越來越多,難道每一個子類都要對應一個工廠類嗎?這樣會使得系統(tǒng)中類的個數(shù)成倍增加,增加了代碼的復雜度。

抽象工廠

為了縮減工廠實現(xiàn)子類的數(shù)量,不必給每一個產品分配一個工廠類,可以將產品進行分組,每組中的不同產品由同一個工廠類的不同方法來創(chuàng)建。


例如,鍵盤、主機這2種產品可以分到同一個分組——電腦,而不同品牌的電腦由不同的制造商工廠來創(chuàng)建。

類似這種把產品類分組,組內不同產品由同一工廠類的不同方法實現(xiàn)的設計模式,就是抽象工廠模式。


抽象工廠適用于以下情況:


1. 一個系統(tǒng)要獨立于它的產品的創(chuàng)建、組合和表示時;
2. 一個系統(tǒng)要由多個產品系列中的一個來配置時;
3. 要強調一系列相關的產品對象的設計以便進行聯(lián)合使用時;
4. 當你提供一個產品類庫,而只想顯示它們的接口而不是實現(xiàn)時;

? 結構

  • 抽象工廠:聲明了創(chuàng)建抽象產品對象的操作接口。
  • 具體產品工廠:實現(xiàn)了抽象工廠的接口,負責創(chuàng)建產品對象。
  • 產品抽象類或接口:定義一類產品對象的接口。
  • 具體產品實現(xiàn):定義一個將被相應具體工廠創(chuàng)建的產品對象。

? 使用

public interface Keyboard {void print(); } public class DellKeyboard implements Keyboard {@Overridepublic void print() {//...dell...dell;} } public class HPKeyboard implements Keyboard {@Overridepublic void print() {//...HP...HP;} } public interface Monitor {void play(); } public class DellMonitor implements Monitor {@Overridepublic void play() {//...dell...dell;} } public class HPMonitor implements Monitor {@Overridepublic void play() {//...HP...HP;} } public interface MainFrame {void run(); } public class DellMainFrame implements MainFrame {@Overridepublic void run() {//...dell...dell;} } public class HPMainFrame implements MainFrame {@Overridepublic void run() {//...HP...HP;} } //工廠類。工廠分為Dell工廠和HP工廠,各自負責品牌內產品的創(chuàng)建 public interface IFactory {MainFrame createMainFrame();Monitor createMainFrame();Keyboard createKeyboard(); } public class DellFactory implements IFactory {@Overridepublic MainFrame createMainFrame(){MainFrame mainFrame = new DellMainFrame();//...造一個Dell主機;return mainFrame;}@Overridepublic Monitor createMonitor(){Monitor monitor = new DellMonitor();//...造一個Dell顯示器;return monitor;}@Overridepublic Keyboard createKeyboard(){Keyboard keyboard = new DellKeyboard();//...造一個Dell鍵盤;return Keyboard;} } public class HPFactory implements IFactory {@Overridepublic MainFrame createMainFrame(){MainFrame mainFrame = new HPMainFrame();//...造一個HP主機;return mainFrame;}@Overridepublic Monitor createMonitor(){Monitor monitor = new HPMonitor();//...造一個HP顯示器;return monitor;}@Overridepublic Keyboard createKeyboard(){Keyboard keyboard = new HPKeyboard();//...造一個HP鍵盤;return Keyboard;} } //客戶端代碼。實例化不同的工廠子類,可以通過不同的創(chuàng)建方法創(chuàng)建不同的產品 public class Main {public static void main(String[] args) {IFactory dellFactory = new DellFactory();IFactory HPFactory = new HPFactory();//創(chuàng)建戴爾鍵盤Keyboard dellKeyboard = dellFactory.createKeyboard();//...} }

? 優(yōu)缺點

增加分組非常簡單,例如要增加Lenovo分組,只需創(chuàng)建Lenovo工廠和具體的產品實現(xiàn)類。分組中的產品擴展非常困難,要增加一個鼠標Mouse,既要創(chuàng)建抽象的Mouse接口, 又要增加具體的實現(xiàn):DellMouse、HPMouse, 還要再每個Factory中定義創(chuàng)建鼠標的方法實現(xiàn)。

? 總結

  • 簡單工廠:唯一工廠類,一個產品抽象類,工廠類的創(chuàng)建方法依據(jù)入參判斷并創(chuàng)建具體產品對象。
  • 工廠方法:多個工廠類,一個產品抽象類,利用多態(tài)創(chuàng)建不同的產品對象,避免了大量的if-else判斷。
  • 抽象工廠:多個工廠類,多個產品抽象類,產品子類分組,同一個工廠實現(xiàn)類創(chuàng)建同組中的不同產品,減少了工廠子類的數(shù)量。

在下述情況下可以考慮使用工廠模式:

  • 在編碼時不能預見需要創(chuàng)建哪種類的實例。
  • 系統(tǒng)不應依賴于產品類實例如何被創(chuàng)建、組合和表達的細節(jié)。
  • 總之,工廠模式就是為了方便創(chuàng)建同一接口定義的具有復雜參數(shù)和初始化步驟的不同對象。工廠模式一般用來創(chuàng)建復雜對象。只需用new就可以創(chuàng)建成功的簡單對象,無需使用工廠模式,否則會增加系統(tǒng)的復雜度。


    此外,如果對象的參數(shù)是不固定的,推薦使用Builder模式。

    后記

    在實際項目中,結合Spring中的InitializingBean接口,可以利用@Autowired注解優(yōu)雅的實現(xiàn)工廠。

    2 單例模式
    定義:確保一個類最多只有一個實例,并提供一個全局訪問點

    單例模式可以分為兩種:預加載和懶加載

    2.1 預加載
    顧名思義,就是預先加載。再進一步解釋就是還沒有使用該單例對象,但是,該單例對象就已經被加載到內存了。

    public class PreloadSingleton {public static PreloadSingleton instance = new PreloadSingleton();//其他的類無法實例化單例類的對象private PreloadSingleton() {};public static PreloadSingleton getInstance() {return instance;} }

    很明顯,沒有使用該單例對象,該對象就被加載到了內存,會造成內存的浪費。

    2.2 懶加載
    為了避免內存的浪費,我們可以采用懶加載,即用到該單例對象的時候再創(chuàng)建。

    public class Singleton {private static Singleton instance=null;private Singleton(){};public static Singleton getInstance(){if(instance==null){instance=new Singleton();}return instance;} }

    2.3 單例模式和線程安全
    (1)預加載只有一條語句return instance,這顯然可以保證線程安全。但是,我們知道預加載會造成內存的浪費。

    (2)懶加載不浪費內存,但是無法保證線程的安全。首先,if判斷以及其內存執(zhí)行代碼是非原子性的。其次,new Singleton()無法保證執(zhí)行的順序性。

    不滿足原子性或者順序性,線程肯定是不安全的,這是基本的常識,不再贅述。我主要講一下為什么new Singleton()無法保證順序性。我們知道創(chuàng)建一個對象分三步:

    memory=allocate();//1:初始化內存空間ctorInstance(memory);//2:初始化對象instance=memory();//3:設置instance指向剛分配的內存地址

    jvm為了提高程序執(zhí)行性能,會對沒有依賴關系的代碼進行重排序,上面2和3行代碼可能被重新排序。我們用兩個線程來說明線程是不安全的。線程A和線程B都創(chuàng)建對象。其中,A2和A3的重排序,將導致線程B在B1處判斷出instance不為空,線程B接下來將訪問instance引用的對象。此時,線程B將會訪問到一個還未初始化的對象(線程不安全)。

    2.4 保證懶加載的線程安全
    我們首先想到的就是使用synchronized關鍵字。synchronized加載getInstace()函數(shù)上確實保證了線程的安全。但是,如果要經常的調用getInstance()方法,不管有沒有初始化實例,都會喚醒和阻塞線程。為了避免線程的上下文切換消耗大量時間,如果對象已經實例化了,我們沒有必要再使用synchronized加鎖,直接返回對象。

    public class Singleton {private static Singleton instance = null;private Singleton() {};public static synchronized Singleton getInstance() {if (instance == null) {instance = new Singleton();}return instance;} }

    我們把sychronized加在if(instance==null)判斷語句里面,保證instance未實例化的時候才加鎖

    public class Singleton {private static Singleton instance = null;private Singleton() {};public static Singleton getInstance() {if (instance == null) {synchronized (Singleton.class) {if (instance == null) {instance = new Singleton();}}}return instance;} }

    我們經過2.3的討論知道new一個對象的代碼是無法保證順序性的,因此,我們需要使用另一個關鍵字volatile保證對象實例化過程的順序性

    關于violatile:Volatile如何保證有序性(禁止指令重排)_heaven殤灬的博客-CSDN博客_volatile如何保證有序性

    public class Singleton {private static volatile Singleton instance = null;//volatile可以禁止JVM指令重排private Singleton() {};public static Singleton getInstance() {if (instance == null) { //判斷為空再加鎖,不為空不需要加鎖synchronized (instance) {if (instance == null) { //可能存在兩個線程第一次都判斷為空,只有1個拿到鎖,實例完后instance已經不為空了,所以需要再一次判斷,否則可能重復實例化instance = new Singleton();}}}return instance;} }

    到此,我們就保證了懶加載的線程安全。

    3 生成器模式
    定義:封裝一個復雜對象構造過程,并允許按步驟構造。

    定義解釋: 我們可以將生成器模式理解為,假設我們有一個對象需要建立,這個對象是由多個組件(Component)組合而成,每個組件的建立都比較復雜,但運用組件來建立所需的對象非常簡單,所以我們就可以將構建復雜組件的步驟與運用組件構建對象分離,使用builder模式可以建立。

    3.1 模式的結構和代碼示例
    生成器模式結構中包括四種角色:

    (1)產品(Product):具體生產器要構造的復雜對象;

    (2)抽象生成器(Bulider):抽象生成器是一個接口,該接口除了為創(chuàng)建一個Product對象的各個組件定義了若干個方法之外,還要定義返回Product對象的方法(定義構造步驟);

    (3)具體生產器(ConcreteBuilder):實現(xiàn)Builder接口的類,具體生成器將實現(xiàn)Builder接口所定義的方法(生產各個組件);

    (4)指揮者(Director):指揮者是一個類,該類需要含有Builder接口聲明的變量。指揮者的職責是負責向用戶提供具體生成器,即指揮者將請求具體生成器類來構造用戶所需要的Product對象,如果所請求的具體生成器成功地構造出Product對象,指揮者就可以讓該具體生產器返回所構造的Product對象。(按照步驟組裝部件,并返回Product)

    舉例(我們如果構建生成一臺電腦,那么我們可能需要這么幾個步驟(1)需要一個主機(2)需要一個顯示器(3)需要一個鍵盤(4)需要一個鼠標)

    雖然我們具體在構建一臺主機的時候,每個對象的實際步驟是不一樣的,比如,有的對象構建了i7cpu的主機,有的對象構建了i5cpu的主機,有的對象構建了普通鍵盤,有的對象構建了機械鍵盤等。但不管怎樣,你總是需要經過一個步驟就是構建一臺主機,一臺鍵盤。對于這個例子,我們就可以使用生成器模式來生成一臺電腦,他需要通過多個步驟來生成。類圖如下:


    ComputerBuilder類定義構造步驟:

    public abstract class ComputerBuilder {protected Computer computer;public Computer getComputer() {return computer;}public void buildComputer() {computer = new Computer();System.out.println("生成了一臺電腦!!!");}public abstract void buildMaster();public abstract void buildScreen();public abstract void buildKeyboard();public abstract void buildMouse();public abstract void buildAudio(); }

    HPComputerBuilder定義各個組件:

    public class HPComputerBuilder extends ComputerBuilder {@Overridepublic void buildMaster() {// TODO Auto-generated method stubcomputer.setMaster("i7,16g,512SSD,1060");System.out.println("(i7,16g,512SSD,1060)的惠普主機");}@Overridepublic void buildScreen() {// TODO Auto-generated method stubcomputer.setScreen("1080p");System.out.println("(1080p)的惠普顯示屏");}@Overridepublic void buildKeyboard() {// TODO Auto-generated method stubcomputer.setKeyboard("cherry 青軸機械鍵盤");System.out.println("(cherry 青軸機械鍵盤)的鍵盤");}@Overridepublic void buildMouse() {// TODO Auto-generated method stubcomputer.setMouse("MI 鼠標");System.out.println("(MI 鼠標)的鼠標");}@Overridepublic void buildAudio() {// TODO Auto-generated method stubcomputer.setAudio("飛利浦 音響");System.out.println("(飛利浦 音響)的音響");} }

    Director類對組件進行組裝并生成產品

    public class Director {private ComputerBuilder computerBuilder;public void setComputerBuilder(ComputerBuilder computerBuilder) {this.computerBuilder = computerBuilder;}public Computer getComputer() {return computerBuilder.getComputer();}public void constructComputer() {computerBuilder.buildComputer();computerBuilder.buildMaster();computerBuilder.buildScreen();computerBuilder.buildKeyboard();computerBuilder.buildMouse();computerBuilder.buildAudio();} } public class Test{public void static main(String args[]){Director d=new Director();d.setComputerBuilder(new HPComputerBuilder());d.constructComputer();Computer computer=d.getComputer();}}

    3.2 生成器模式的優(yōu)缺點
    優(yōu)點
    將一個對象分解為各個組件

    將對象組件的構造封裝起來

    可以控制整個對象的生成過程

    缺點
    對不同類型的對象需要實現(xiàn)不同的具體構造器的類,這可能回答大大增加類的數(shù)量

    3.3 生成器模式與工廠模式的不同
    生成器模式構建對象的時候,對象通常構建的過程中需要多個步驟,就像我們例子中的先有主機,再有顯示屏,再有鼠標等等,生成器模式的作用就是將這些復雜的構建過程封裝起來。工廠模式構建對象的時候通常就只有一個步驟,調用一個工廠方法就可以生成一個對象。

    4 原型模式
    定義:通過復制現(xiàn)有實例來創(chuàng)建新的實例,無需知道相應類的信息。

    簡單地理解,其實就是當需要創(chuàng)建一個指定的對象時,我們剛好有一個這樣的對象,但是又不能直接使用,我會clone一個一毛一樣的新對象來使用;基本上這就是原型模式。關鍵字:Clone。

    4.1 深拷貝和淺拷貝
    淺復制:將一個對象復制后,基本數(shù)據(jù)類型的變量都會重新創(chuàng)建,而引用類型,指向的還是原對象所指向的。

    深復制:將一個對象復制后,不論是基本數(shù)據(jù)類型還有引用類型,都是重新創(chuàng)建的。簡單來說,就是深復制進行了完全徹底的復制,而淺復制不徹底。clone明顯是深復制,clone出來的對象是是不能去影響原型對象的

    4.2 原型模式的結構和代碼示例

    Client:使用者

    Prototype:接口(抽象類),聲明具備clone能力,例如java中得Cloneable接口

    ConcretePrototype:具體的原型類

    可以看出設計模式還是比較簡單的,重點在于Prototype接口和Prototype接口的實現(xiàn)類ConcretePrototype。原型模式的具體實現(xiàn):一個原型類,只需要實現(xiàn)Cloneable接口,覆寫clone方法,此處clone方法可以改成任意的名稱,因為Cloneable接口是個空接口,你可以任意定義實現(xiàn)類的方法名,如cloneA或者cloneB,因為此處的重點是super.clone()這句話,super.clone()調用的是Object的clone()方法。

    public class Prototype implements Cloneable { public Object clone() throws CloneNotSupportedException { Prototype proto = (Prototype) super.clone(); return proto; } }

    ?舉例(銀行發(fā)送大量郵件,使用clone和不使用clone的時間對比):我們模擬創(chuàng)建一個對象需要耗費比較長的時間,因此,在構造函數(shù)中我們讓當前線程sleep一會

    public Mail(EventTemplate et) {this.tail = et.geteventContent();this.subject = et.geteventSubject();try {Thread.sleep(1000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}

    不使用clone,發(fā)送十個郵件

    public static void main(String[] args) {int i = 0;int MAX_COUNT = 10;EventTemplate et = new EventTemplate("9月份信用卡賬單", "國慶抽獎活動...");long start = System.currentTimeMillis();while (i < MAX_COUNT) {// 以下是每封郵件不同的地方Mail mail = new Mail(et);mail.setContent(getRandString(5) + ",先生(女士):你的信用卡賬單..." + mail.getTail());mail.setReceiver(getRandString(5) + "@" + getRandString(8) + ".com");// 然后發(fā)送郵件sendMail(mail);i++;}long end = System.currentTimeMillis();System.out.println("用時:" + (end - start));}

    用時:10001

    使用clone,發(fā)送十個郵件

    public static void main(String[] args) {int i = 0;int MAX_COUNT = 10;EventTemplate et = new EventTemplate("9月份信用卡賬單", "國慶抽獎活動...");long start=System.currentTimeMillis();Mail mail = new Mail(et); while (i < MAX_COUNT) {Mail cloneMail = mail.clone();cloneMail .setContent(getRandString(5) + ",先生(女士):你的信用卡賬單..."+ mail.getTail());cloneMail .setReceiver(getRandString(5) + "@" + getRandString(8) + ".com");sendMail(cloneMail);i++;}long end=System.currentTimeMillis();System.out.println("用時:"+(end-start));}

    用時:1001

    4.3 總結
    原型模式的本質就是clone,可以解決構建復雜對象的資源消耗問題,能再某些場景中提升構建對象的效率;還有一個重要的用途就是保護性拷貝,可以通過返回一個拷貝對象的形式,實現(xiàn)只讀的限制。

    B、結構模式(7種)
    適配器模式、裝飾器模式、代理模式、外觀模式、橋接模式、組合模式、享元模式。

    5 適配器模式
    定義: 適配器模式將某個類的接口轉換成客戶端期望的另一個接口表示,目的是消除由于接口不匹配所造成的類的兼容性問題。

    主要分為三類:類的適配器模式、對象的適配器模式、接口的適配器模式。

    5.1 類適配器模式
    通過多重繼承目標接口和被適配者類方式來實現(xiàn)適配

    舉例(將USB接口轉為VGA接口),類圖如下:

    USBImpl的代碼:

    public class USBImpl implements USB{@Overridepublic void showPPT() {// TODO Auto-generated method stubSystem.out.println("PPT內容演示");} }

    ?AdatperUSB2VGA 首先繼承USBImpl獲取USB的功能,其次,實現(xiàn)VGA接口,表示該類的類型為VGA。

    public class AdapterUSB2VGA extends USBImpl implements VGA {@Overridepublic void projection() {super.showPPT();} }

    Projector將USB映射為VGA,只有VGA接口才可以連接上投影儀進行投影

    public class Projector<T> {public void projection(T t) {if (t instanceof VGA) {System.out.println("開始投影");VGA v = new VGAImpl();v = (VGA) t;v.projection();} else {System.out.println("接口不匹配,無法投影");}} }

    test代碼

    @Testpublic void test2(){//通過適配器創(chuàng)建一個VGA對象,這個適配器實際是使用的是USB的showPPT()方法VGA a=new AdapterUSB2VGA();//進行投影Projector p1=new Projector();p1.projection(a);}

    5.2 對象適配器模式
    對象適配器和類適配器使用了不同的方法實現(xiàn)適配,對象適配器使用組合,類適配器使用繼承。

    舉例(將USB接口轉為VGA接口),類圖如下:

    public class AdapterUSB2VGA implements VGA {USB u = new USBImpl();@Overridepublic void projection() {u.showPPT();} }

    實現(xiàn)VGA接口,表示適配器類是VGA類型的,適配器方法中直接使用USB對象。

    5.3 接口適配器模式
    當不需要全部實現(xiàn)接口提供的方法時,可先設計一個抽象類實現(xiàn)接口,并為該接口中每個方法提供一個默認實現(xiàn)(空方法),那么該抽象類的子類可有選擇地覆蓋父類的某些方法來實現(xiàn)需求,它適用于一個接口不想使用其所有的方法的情況。

    舉例(將USB接口轉為VGA接口,VGA中的b()和c()不會被實現(xiàn)),類圖如下:

    AdapterUSB2VGA抽象類

    public abstract class AdapterUSB2VGA implements VGA {USB u = new USBImpl();@Overridepublic void projection() {u.showPPT();}@Overridepublic void b() {};@Overridepublic void c() {}; }

    AdapterUSB2VGA實現(xiàn),不用去實現(xiàn)b()和c()方法。

    public class AdapterUSB2VGAImpl extends AdapterUSB2VGA {public void projection() {super.projection();} }

    5.4 總結
    總結一下三種適配器模式的應用場景:

    類適配器模式:當希望將一個類轉換成滿足另一個新接口的類時,可以使用類的適配器模式,創(chuàng)建一個新類,繼承原有的類,實現(xiàn)新的接口即可。

    對象適配器模式:當希望將一個對象轉換成滿足另一個新接口的對象時,可以創(chuàng)建一個Wrapper類,持有原類的一個實例,在Wrapper類的方法中,調用實例的方法就行。

    接口適配器模式:當不希望實現(xiàn)一個接口中所有的方法時,可以創(chuàng)建一個抽象類Wrapper,實現(xiàn)所有方法,我們寫別的類的時候,繼承抽象類即可。

    命名規(guī)則:

    我個人理解,三種命名方式,是根據(jù) src是以怎樣的形式給到Adapter(在Adapter里的形式)來命名的。

    類適配器,以類給到,在Adapter里,就是將src當做類,繼承,

    對象適配器,以對象給到,在Adapter里,將src作為一個對象,持有。

    接口適配器,以接口給到,在Adapter里,將src作為一個接口,實現(xiàn)。

    使用選擇:

    根據(jù)合成復用原則,組合大于繼承。因此,類的適配器模式應該少用。

    6 裝飾者模式
    定義:動態(tài)的將新功能附加到對象上。在對象功能擴展方面,它比繼承更有彈性。

    6.1 裝飾者模式結構圖與代碼示例
    1.Component(被裝飾對象的基類)

    定義一個對象接口,可以給這些對象動態(tài)地添加職責。

    2.ConcreteComponent(具體被裝飾對象)

    定義一個對象,可以給這個對象添加一些職責。

    3.Decorator(裝飾者抽象類)

    維持一個指向Component實例的引用,并定義一個與Component接口一致的接口。

    4.ConcreteDecorator(具體裝飾者)

    具體的裝飾對象,給內部持有的具體被裝飾對象,增加具體的職責。

    被裝飾對象和修飾者繼承自同一個超類

    舉例(咖啡館訂單項目:1)、咖啡種類:Espresso、ShortBlack、LongBlack、Decaf2)、調料(裝飾者):Milk、Soy、Chocolate),類圖如下:
    被裝飾的對象和裝飾者都繼承自同一個超類

    public abstract class Drink {public String description="";private float price=0f;;public void setDescription(String description){this.description=description;}public String getDescription(){return description+"-"+this.getPrice();}public float getPrice(){return price;}public void setPrice(float price){this.price=price;}public abstract float cost();}

    被裝飾的對象,不用去改造。原來怎么樣寫,現(xiàn)在還是怎么寫。

    public class Coffee extends Drink {@Overridepublic float cost() {// TODO Auto-generated method stubreturn super.getPrice();}}

    coffee類的實現(xiàn)

    public class Decaf extends Coffee {public Decaf(){super.setDescription("Decaf");super.setPrice(3.0f);} }

    裝飾者

    裝飾者不僅要考慮自身,還要考慮被它修飾的對象,它是在被修飾的對象上繼續(xù)添加修飾。例如,咖啡里面加牛奶,再加巧克力。加糖后價格為coffee+milk。再加牛奶價格為coffee+milk+chocolate。

    public class Decorator extends Drink {private Drink Obj;public Decorator(Drink Obj) {this.Obj = Obj;};@Overridepublic float cost() {// TODO Auto-generated method stubreturn super.getPrice() + Obj.cost();}@Overridepublic String getDescription() {return super.description + "-" + super.getPrice() + "&&" + Obj.getDescription();} }

    裝飾者實例化(加牛奶)。這里面要對被修飾的對象進行實例化。

    public class Milk extends Decorator {public Milk(Drink Obj) { super(Obj);// TODO Auto-generated constructor stubsuper.setDescription("Milk");super.setPrice(2.0f);} }

    coffee店:初始化一個被修飾對象,修飾者實例需要對被修改者實例化,才能對具體的被修飾者進行修飾。

    public class CoffeeBar {public static void main(String[] args) {Drink order;order = new Decaf();System.out.println("order1 price:" + order.cost());System.out.println("order1 desc:" + order.getDescription());System.out.println("****************");order = new LongBlack();order = new Milk(order);order = new Chocolate(order);order = new Chocolate(order);System.out.println("order2 price:" + order.cost());System.out.println("order2 desc:" + order.getDescription());} }

    6.2 總結

    裝飾者和被裝飾者之間必須是一樣的類型,也就是要有共同的超類。在這里應用繼承并不是實現(xiàn)方法的復制,而是實現(xiàn)類型的匹配。因為裝飾者和被裝飾者是同一個類型,因此裝飾者可以取代被裝飾者,這樣就使被裝飾者擁有了裝飾者獨有的行為。根據(jù)裝飾者模式的理念,我們可以在任何時候,實現(xiàn)新的裝飾者增加新的行為。如果是用繼承,每當需要增加新的行為時,就要修改原程序了。

    7 代理模式
    定義:代理模式給某一個對象提供一個代理對象,并由代理對象控制對原對象的引用。通俗的來講代理模式就是我們生活中常見的中介。

    舉個例子來說明:假如說我現(xiàn)在想買一輛二手車,雖然我可以自己去找車源,做質量檢測等一系列的車輛過戶流程,但是這確實太浪費我得時間和精力了。我只是想買一輛車而已為什么我還要額外做這么多事呢?于是我就通過中介公司來買車,他們來給我找車源,幫我辦理車輛過戶流程,我只是負責選擇自己喜歡的車,然后付錢就可以了。用圖表示如下:

    7.1 為什么要用代理模式?
    中介隔離作用:在某些情況下,一個客戶類不想或者不能直接引用一個委托對象,而代理類對象可以在客戶類和委托對象之間起到中介的作用,其特征是代理類和委托類實現(xiàn)相同的接口。

    開閉原則,增加功能:代理類除了是客戶類和委托類的中介之外,我們還可以通過給代理類增加額外的功能來擴展委托類的功能,這樣做我們只需要修改代理類而不需要再修改委托類,符合代碼設計的開閉原則。代理類主要負責為委托類預處理消息、過濾消息、把消息轉發(fā)給委托類,以及事后對返回結果的處理等。代理類本身并不真正實現(xiàn)服務,而是同過調用委托類的相關方法,來提供特定的服務。真正的業(yè)務功能還是由委托類來實現(xiàn),但是可以在業(yè)務功能執(zhí)行的前后加入一些公共的服務。例如我們想給項目加入緩存、日志這些功能,我們就可以使用代理類來完成,而沒必要打開已經封裝好的委托類。

    代理模式分為三類:1. 靜態(tài)代理 2. 動態(tài)代理 3. CGLIB代理

    7.2 靜態(tài)代理

    舉例(買房),類圖如下:

    第一步:創(chuàng)建服務類接口

    public interface BuyHouse {void buyHosue(); }

    第二步:實現(xiàn)服務接口

    public class BuyHouseImpl implements BuyHouse {@Overridepublic void buyHosue() {System.out.println("我要買房");} }

    第三步:創(chuàng)建代理類

    public class BuyHouseProxy implements BuyHouse {private BuyHouse buyHouse;public BuyHouseProxy(final BuyHouse buyHouse) {this.buyHouse = buyHouse;}@Overridepublic void buyHosue() {System.out.println("買房前準備");buyHouse.buyHosue();System.out.println("買房后裝修");} }

    總結:

    優(yōu)點:可以做到在符合開閉原則的情況下對目標對象進行功能擴展。

    缺點: 代理對象與目標對象要實現(xiàn)相同的接口,我們得為每一個服務都得創(chuàng)建代理類,工作量太大,不易管理。同時接口一旦發(fā)生改變,代理類也得相應修改。

    7.3 動態(tài)代理
    動態(tài)代理有以下特點:

    1.代理對象,不需要實現(xiàn)接口

    2.代理對象的生成,是利用JDK的API,動態(tài)的在內存中構建代理對象(需要我們指定創(chuàng)建代理對象/目標對象實現(xiàn)的接口的類型)

    代理類不用再實現(xiàn)接口了。但是,要求被代理對象必須有接口。

    動態(tài)代理實現(xiàn):

    Java.lang.reflect.Proxy類可以直接生成一個代理對象

    Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)生成一個代理對象

    參數(shù)1:ClassLoader loader 代理對象的類加載器 一般使用被代理對象的類加載器

    參數(shù)2:Class<?>[] interfaces 代理對象的要實現(xiàn)的接口 一般使用的被代理對象實現(xiàn)的接口

    參數(shù)3:InvocationHandler h (接口)執(zhí)行處理類

    InvocationHandler中的invoke(Object proxy, Method method, Object[] args)方法:調用代理類的任何方法,此方法都會執(zhí)行

    參數(shù)3.1:代理對象(慎用)

    參數(shù)3.2:當前執(zhí)行的方法

    參數(shù)3.3:當前執(zhí)行的方法運行時傳遞過來的參數(shù)

    第一步:編寫動態(tài)處理器

    public class DynamicProxyHandler implements InvocationHandler {private Object object;public DynamicProxyHandler(final Object object) {this.object = object;}@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println("買房前準備");Object result = method.invoke(object, args);System.out.println("買房后裝修");return result;} }

    第二步:編寫測試類

    public class DynamicProxyTest {public static void main(String[] args) {BuyHouse buyHouse = new BuyHouseImpl();BuyHouse proxyBuyHouse = (BuyHouse) Proxy.newProxyInstance(BuyHouse.class.getClassLoader(), newClass[]{BuyHouse.class}, new DynamicProxyHandler(buyHouse));proxyBuyHouse.buyHosue();} }

    動態(tài)代理總結:雖然相對于靜態(tài)代理,動態(tài)代理大大減少了我們的開發(fā)任務,同時減少了對業(yè)務接口的依賴,降低了耦合度。但是還是有一點點小小的遺憾之處,那就是它始終無法擺脫僅支持interface代理的桎梏(我們要使用被代理的對象的接口),因為它的設計注定了這個遺憾。

    7.4 CGLIB代理

    CGLIB 原理:動態(tài)生成一個要代理類的子類,子類重寫要代理的類的所有不是final的方法。在子類中采用方法攔截的技術攔截所有父類方法的調用,順勢織入橫切邏輯。它比使用java反射的JDK動態(tài)代理要快。

    CGLIB 底層:使用字節(jié)碼處理框架ASM,來轉換字節(jié)碼并生成新的類。不鼓勵直接使用ASM,因為它要求你必須對JVM內部結構包括class文件的格式和指令集都很熟悉。

    CGLIB缺點:對于final方法,無法進行代理。

    CGLIB的實現(xiàn)步驟:

    第一步:建立攔截器

    public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {System.out.println("買房前準備");Object result = methodProxy.invoke(object, args);System.out.println("買房后裝修");return result;}

    參數(shù):Object為由CGLib動態(tài)生成的代理類實例,Method為上文中實體類所調用的被代理的方法引用,Object[]為參數(shù)值列表,MethodProxy為生成的代理類對方法的代理引用。

    返回:從代理實例的方法調用返回的值。

    其中,proxy.invokeSuper(obj,arg) 調用代理類實例上的proxy方法的父類方法(即實體類TargetObject中對應的方法)

    第二步: 生成動態(tài)代理類

    public class CglibProxy implements MethodInterceptor {private Object target;public Object getInstance(final Object target) {this.target = target;Enhancer enhancer = new Enhancer();enhancer.setSuperclass(this.target.getClass());enhancer.setCallback(this);return enhancer.create();}public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {System.out.println("買房前準備");Object result = methodProxy.invoke(object, args);System.out.println("買房后裝修");return result;} }

    這里Enhancer類是CGLib中的一個字節(jié)碼增強器,它可以方便的對你想要處理的類進行擴展,以后會經常看到它。

    首先將被代理類TargetObject設置成父類,然后設置攔截器TargetInterceptor,最后執(zhí)行enhancer.create()動態(tài)生成一個代理類,并從Object強制轉型成父類型TargetObject。

    第三步:測試

    public class CglibProxyTest {public static void main(String[] args){BuyHouse buyHouse = new BuyHouseImpl();CglibProxy cglibProxy = new CglibProxy();BuyHouseImpl buyHouseCglibProxy = (BuyHouseImpl) cglibProxy.getInstance(buyHouse);buyHouseCglibProxy.buyHosue();} }

    CGLIB代理總結: CGLIB創(chuàng)建的動態(tài)代理對象比JDK創(chuàng)建的動態(tài)代理對象的性能更高,但是CGLIB創(chuàng)建代理對象時所花費的時間卻比JDK多得多。所以對于單例的對象,因為無需頻繁創(chuàng)建對象,用CGLIB合適,反之使用JDK方式要更為合適一些。同時由于CGLib由于是采用動態(tài)創(chuàng)建子類的方法,對于final修飾的方法無法進行代理。

    8 外觀模式
    定義: 隱藏了系統(tǒng)的復雜性,并向客戶端提供了一個可以訪問系統(tǒng)的接口。

    8.1 模式結構和代碼示例

    簡單來說,該模式就是把一些復雜的流程封裝成一個接口供給外部用戶更簡單的使用。這個模式中,設計到3個角色。

    1).門面角色:外觀模式的核心。它被客戶角色調用,它熟悉子系統(tǒng)的功能。內部根據(jù)客戶角色的需求預定了幾種功能的組合。(客戶調用,同時自身調用子系統(tǒng)功能)

    2).子系統(tǒng)角色:實現(xiàn)了子系統(tǒng)的功能。它對客戶角色和Facade時未知的。它內部可以有系統(tǒng)內的相互交互,也可以由供外界調用的接口。(實現(xiàn)具體功能)

    3).客戶角色:通過調用Facede來完成要實現(xiàn)的功能(調用門面角色)。

    舉例(每個Computer都有CPU、Memory、Disk。在Computer開啟和關閉的時候,相應的部件也會開啟和關閉),類圖如下:

    首先是子系統(tǒng)類:

    public class CPU {public void start() {System.out.println("cpu is start...");}public void shutDown() {System.out.println("CPU is shutDown...");} }public class Disk {public void start() {System.out.println("Disk is start...");}public void shutDown() {System.out.println("Disk is shutDown...");} }public class Memory {public void start() {System.out.println("Memory is start...");}public void shutDown() {System.out.println("Memory is shutDown...");} }

    然后是,門面類Facade

    public class Computer {private CPU cpu;private Memory memory;private Disk disk;public Computer() {cpu = new CPU();memory = new Memory();disk = new Disk();}public void start() {System.out.println("Computer start begin");cpu.start();disk.start();memory.start();System.out.println("Computer start end");}public void shutDown() {System.out.println("Computer shutDown begin");cpu.shutDown();disk.shutDown();memory.shutDown();System.out.println("Computer shutDown end...");} }

    最后為,客戶角色

    public class Client {public static void main(String[] args) {Computer computer = new Computer();computer.start();System.out.println("=================");computer.shutDown();}}

    8.2 優(yōu)點
      - 松散耦合

    使得客戶端和子系統(tǒng)之間解耦,讓子系統(tǒng)內部的模塊功能更容易擴展和維護;

    - 簡單易用

    客戶端根本不需要知道子系統(tǒng)內部的實現(xiàn),或者根本不需要知道子系統(tǒng)內部的構成,它只需要跟Facade類交互即可。

    - 更好的劃分訪問層次

    有些方法是對系統(tǒng)外的,有些方法是系統(tǒng)內部相互交互的使用的。子系統(tǒng)把那些暴露給外部的功能集中到門面中,這樣就可以實現(xiàn)客戶端的使用,很好的隱藏了子系統(tǒng)內部的細節(jié)。

    9 橋接模式
    定義: 將抽象部分與它的實現(xiàn)部分分離,使它們都可以獨立地變化。

    9.1 案例
    看下圖手機與手機軟件的類圖


    增加一款新的手機軟件,需要在所有手機品牌類下添加對應的手機軟件類,當手機軟件種類較多時,將導致類的個數(shù)急劇膨脹,難以維護

    手機和手機中的軟件是什么關系?

    手機中的軟件從本質上來說并不是一種手機,手機軟件運行在手機中,是一種包含與被包含關系,而不是一種父與子或者說一般與特殊的關系,通過繼承手機類實現(xiàn)手機軟件類的設計是違反一般規(guī)律的。

    如果Oppo手機實現(xiàn)了wifi功能,繼承它的Oppo應用商城也會繼承wifi功能,并且Oppo手機類的任何變動,都會影響其子類

    換一種解決思路

    從類圖上看起來更像是手機軟件類圖,涉及到手機本身相關的功能,比如說:wifi功能,放到哪個類中實現(xiàn)呢?放到OppoAppStore中實現(xiàn)顯然是不合適的

    引起整個結構變化的元素有兩個,一個是手機品牌,一個是手機軟件,所以我們將這兩個點抽出來,分別進行封裝

    9.2 橋接模式結構和代碼示例

    類圖:

    實現(xiàn):

    public interface Software {public void run();} public class AppStore implements Software {@Overridepublic void run() {System.out.println("run app store");} } public class Camera implements Software {@Overridepublic void run() {System.out.println("run camera");} }

    抽象:

    public abstract class Phone {protected Software software;public void setSoftware(Software software) {this.software = software;}public abstract void run();} public class Oppo extends Phone {@Overridepublic void run() {software.run();} } public class Vivo extends Phone {@Overridepublic void run() {software.run();} }

    對比最初的設計,將抽象部分(手機)與它的實現(xiàn)部分(手機軟件類)分離,將實現(xiàn)部分抽象成單獨的類,使它們都可以獨立地變化。整個類圖看起來像一座橋,所以稱為橋接模式

    繼承是一種強耦合關系,子類的實現(xiàn)與它的父類有非常緊密的依賴關系,父類的任何變化 都會導致子類發(fā)生變化,因此繼承或者說強耦合關系嚴重影響了類的靈活性,并最終限制了可復用性

    從橋接模式的設計上我們可以看出聚合是一種比繼承要弱的關聯(lián)關系,手機類和軟件類都可獨立的進行變化,不會互相影響

    9.3 適用場景
    橋接模式通常適用于以下場景。

    當一個類存在兩個獨立變化的維度,且這兩個維度都需要進行擴展時。

    當一個系統(tǒng)不希望使用繼承或因為多層次繼承導致系統(tǒng)類的個數(shù)急劇增加時。

    當一個系統(tǒng)需要在構件的抽象化角色和具體化角色之間增加更多的靈活性時。

    9.4 優(yōu)缺點
    優(yōu)點:

    (1)在很多情況下,橋接模式可以取代多層繼承方案,多層繼承方案違背了“單一職責原則”,復用性較差,且類的個數(shù)非常多,橋接模式是比多層繼承方案更好的解決方法,它極大減少了子類的個數(shù)。

    (2)橋接模式提高了系統(tǒng)的可擴展性,在兩個變化維度中任意擴展一個維度,都不需要修改原有系統(tǒng),符合“開閉原則”。

    缺點:

    橋接模式的使用會增加系統(tǒng)的理解與設計難度,由于關聯(lián)關系建立在抽象層,要求開發(fā)者一開始就針對抽象層進行設計與編程。

    10 組合模式
    定義:有時又叫作部分-整體模式,它是一種將對象組合成樹狀的層次結構的模式,用來表示“部分-整體”的關系,使用戶對單個對象和組合對象具有一致的訪問性。

    意圖:將對象組合成樹形結構以表示"部分-整體"的層次結構。組合模式使得用戶對單個對象和組合對象的使用具有一致性。

    主要解決:它在我們樹型結構的問題中,模糊了簡單元素和復雜元素的概念,客戶程序可以向處理簡單元素一樣來處理復雜元素,從而使得客戶程序與復雜元素的內部結構解耦。

    何時使用: 1、您想表示對象的部分-整體層次結構(樹形結構)。 2、您希望用戶忽略組合對象與單個對象的不同,用戶將統(tǒng)一地使用組合結構中的所有對象。

    如何解決:樹枝和葉子實現(xiàn)統(tǒng)一接口,樹枝內部組合該接口。

    關鍵代碼:樹枝內部組合該接口,并且含有內部屬性 List,里面放 Component。

    組合模式的主要優(yōu)點有:

    組合模式使得客戶端代碼可以一致地處理單個對象和組合對象,無須關心自己處理的是單個對象,還是組合對象,這簡化了客戶端代碼;

    更容易在組合體內加入新的對象,客戶端不會因為加入了新的對象而更改源代碼,滿足“開閉原則”;

    其主要缺點是:

    設計較復雜,客戶端需要花更多時間理清類之間的層次關系;

    不容易限制容器中的構件;

    不容易用繼承的方法來增加構件的新功能;
    10.1 模式結構和代碼示例

    抽象構件(Component)角色:它的主要作用是為樹葉構件和樹枝構件聲明公共接口,并實現(xiàn)它們的默認行為。在透明式的組合模式中抽象構件還聲明訪問和管理子類的接口;在安全式的組合模式中不聲明訪問和管理子類的接口,管理工作由樹枝構件完成。

    樹葉構件(Leaf)角色:是組合中的葉節(jié)點對象,它沒有子節(jié)點,用于實現(xiàn)抽象構件角色中 聲明的公共接口。

    樹枝構件(Composite)角色:是組合中的分支節(jié)點對象,它有子節(jié)點。它實現(xiàn)了抽象構件角色中聲明的接口,它的主要作用是存儲和管理子部件,通常包含 Add()、Remove()、GetChild() 等方法

    舉例(訪問一顆樹),類圖如下:


    1 組件

    public interface Component {public void add(Component c);public void remove(Component c);public Component getChild(int i);public void operation();}

    2 葉子

    public class Leaf implements Component{private String name;public Leaf(String name) {this.name = name;}@Overridepublic void add(Component c) {}@Overridepublic void remove(Component c) {}@Overridepublic Component getChild(int i) {// TODO Auto-generated method stubreturn null;}@Overridepublic void operation() {// TODO Auto-generated method stubSystem.out.println("樹葉"+name+":被訪問!"); }}

    3 樹枝

    public class Composite implements Component {private ArrayList<Component> children = new ArrayList<Component>();public void add(Component c) {children.add(c);}public void remove(Component c) {children.remove(c);}public Component getChild(int i) {return children.get(i);}public void operation() {for (Object obj : children) {((Component) obj).operation();}} }

    11 享元模式
    定義:通過共享的方式高效的支持大量細粒度的對象。

    主要解決:在有大量對象時,有可能會造成內存溢出,我們把其中共同的部分抽象出來,如果有相同的業(yè)務請求,直接返回在內存中已有的對象,避免重新創(chuàng)建。

    何時使用: 1、系統(tǒng)中有大量對象。 2、這些對象消耗大量內存。 3、這些對象的狀態(tài)大部分可以外部化。 4、這些對象可以按照內蘊狀態(tài)分為很多組,當把外蘊對象從對象中剔除出來時,每一組對象都可以用一個對象來代替。 5、系統(tǒng)不依賴于這些對象身份,這些對象是不可分辨的。

    如何解決:用唯一標識碼判斷,如果在內存中有,則返回這個唯一標識碼所標識的對象。

    關鍵代碼:用 HashMap 存儲這些對象。

    應用實例: 1、JAVA 中的 String,如果有則返回,如果沒有則創(chuàng)建一個字符串保存在字符串緩存池里面。

    優(yōu)點:大大減少對象的創(chuàng)建,降低系統(tǒng)的內存,使效率提高。

    缺點:提高了系統(tǒng)的復雜度,需要分離出外部狀態(tài)和內部狀態(tài),而且外部狀態(tài)具有固有化的性質,不應該隨著內部狀態(tài)的變化而變化,否則會造成系統(tǒng)的混亂。

    簡單來說,我們抽取出一個對象的外部狀態(tài)(不能共享)和內部狀態(tài)(可以共享)。然后根據(jù)外部狀態(tài)的決定是否創(chuàng)建內部狀態(tài)對象。內部狀態(tài)對象是通過哈希表保存的,當外部狀態(tài)相同的時候,不再重復的創(chuàng)建內部狀態(tài)對象,從而減少要創(chuàng)建對象的數(shù)量。

    11.1 享元模式的結構圖和代碼示例

    1、Flyweight (享元抽象類):一般是接口或者抽象類,定義了享元類的公共方法。這些方法可以分享內部狀態(tài)的數(shù)據(jù),也可以調用這些方法修改外部狀態(tài)。

    2、ConcreteFlyweight(具體享元類):具體享元類實現(xiàn)了抽象享元類的方法,為享元對象開辟了內存空間來保存享元對象的內部數(shù)據(jù),同時可以通過和單例模式結合只創(chuàng)建一個享元對象。

    3、FlyweightFactory(享元工廠類):享元工廠類創(chuàng)建并且管理享元類,享元工廠類針對享元類來進行編程,通過提供一個享元池來進行享元對象的管理。一般享元池設計成鍵值對,或者其他的存儲結構來存儲。當客戶端進行享元對象的請求時,如果享元池中有對應的享元對象則直接返回對應的對象,否則工廠類創(chuàng)建對應的享元對象并保存到享元池。

    舉例(JAVA 中的 String,如果有則返回,如果沒有則創(chuàng)建一個字符串保存在字符串緩存池里面)。類圖如下:

    (1)創(chuàng)建享元對象接口

    public interface IFlyweight {void print(); }

    (2)創(chuàng)建具體享元對象

    public class Flyweight implements IFlyweight {private String id;public Flyweight(String id){this.id = id;}@Overridepublic void print() {System.out.println("Flyweight.id = " + getId() + " ...");}public String getId() {return id;} }

    (3)創(chuàng)建工廠,這里要特別注意,為了避免享元對象被重復創(chuàng)建,我們使用HashMap中的key值保證其唯一。

    public class FlyweightFactory {private Map<String, IFlyweight> flyweightMap = new HashMap();public IFlyweight getFlyweight(String str){IFlyweight flyweight = flyweightMap.get(str);if(flyweight == null){flyweight = new Flyweight(str);flyweightMap.put(str, flyweight);}return flyweight;}public int getFlyweightMapSize(){return flyweightMap.size();} }

    (4)測試,我們創(chuàng)建三個字符串,但是只會產生兩個享元對象

    public class MainTest {public static void main(String[] args) {FlyweightFactory flyweightFactory = new FlyweightFactory();IFlyweight flyweight1 = flyweightFactory.getFlyweight("A");IFlyweight flyweight2 = flyweightFactory.getFlyweight("B");IFlyweight flyweight3 = flyweightFactory.getFlyweight("A");flyweight1.print();flyweight2.print();flyweight3.print();System.out.println(flyweightFactory.getFlyweightMapSize());}}

    C、關系模式(11種)
    先來張圖,看看這11中模式的關系:

    第一類:通過父類與子類的關系進行實現(xiàn)。

    第二類:兩個類之間。

    第三類:類的狀態(tài)。

    第四類:通過中間類


    12 策略模式
    定義: 策略模式定義了一系列算法,并將每個算法封裝起來,使他們可以相互替換,且算法的變化不會影響到使用算法的客戶。

    意圖:定義一系列的算法,把它們一個個封裝起來, 并且使它們可相互替換。

    主要解決:在有多種算法相似的情況下,使用 if…else 所帶來的復雜和難以維護。

    何時使用:一個系統(tǒng)有許多許多類,而區(qū)分它們的只是他們直接的行為。

    如何解決:將這些算法封裝成一個一個的類,任意地替換。

    關鍵代碼:實現(xiàn)同一個接口。

    優(yōu)點: 1、算法可以自由切換。 2、避免使用多重條件判斷。 3、擴展性良好。

    缺點: 1、策略類會增多。 2、所有策略類都需要對外暴露。

    12.1 策略模式結構和示例代碼

    抽象策略角色: 這個是一個抽象的角色,通常情況下使用接口或者抽象類去實現(xiàn)。對比來說,就是我們的Comparator接口。

    具體策略角色: 包裝了具體的算法和行為。對比來說,就是實現(xiàn)了Comparator接口的實現(xiàn)一組實現(xiàn)類。

    環(huán)境角色: 內部會持有一個抽象角色的引用,給客戶端調用。

    舉例如下( 實現(xiàn)一個加減的功能),類圖如下:

    1、定義抽象策略角色

    public interface Strategy {public int calc(int num1,int num2); }

    2、定義具體策略角色

    public class AddStrategy implements Strategy {@Overridepublic int calc(int num1, int num2) {// TODO Auto-generated method stubreturn num1 + num2;}} public class SubstractStrategy implements Strategy {@Overridepublic int calc(int num1, int num2) {// TODO Auto-generated method stubreturn num1 - num2;}}

    3、環(huán)境角色

    public class Environment {private Strategy strategy;public Environment(Strategy strategy) {this.strategy = strategy;}public int calculate(int a, int b) {return strategy.calc(a, b);}}

    4、測試

    public class MainTest {public static void main(String[] args) {Environment environment=new Environment(new AddStrategy());int result=environment.calculate(20, 5);System.out.println(result);Environment environment1=new Environment(new SubstractStrategy());int result1=environment1.calculate(20, 5);System.out.println(result1);}}

    13 模板模式
    定義:定義一個操作中算法的骨架,而將一些步驟延遲到子類中,模板方法使得子類可以不改變算法的結構即可重定義該算法的某些特定步驟。

    通俗點的理解就是 :完成一件事情,有固定的數(shù)個步驟,但是每個步驟根據(jù)對象的不同,而實現(xiàn)細節(jié)不同;就可以在父類中定義一個完成該事情的總方法,按照完成事件需要的步驟去調用其每個步驟的實現(xiàn)方法。每個步驟的具體實現(xiàn),由子類完成。

    13.1 模式結構和代碼示例

    抽象父類(AbstractClass):實現(xiàn)了模板方法,定義了算法的骨架。

    具體類(ConcreteClass):實現(xiàn)抽象類中的抽象方法,即不同的對象的具體實現(xiàn)細節(jié)。

    舉例( 我們做菜可以分為三個步驟 (1)備料 (2)具體做菜 (3)盛菜端給客人享用,這三部就是算法的骨架 ;然而做不同菜需要的料,做的方法,以及如何盛裝給客人享用都是不同的這個就是不同的實現(xiàn)細節(jié)。)。類圖如下:

    a. 先來寫一個抽象的做菜父類:

    public abstract class Dish { /*** 具體的整個過程*/protected void dodish(){this.preparation();this.doing();this.carriedDishes();}/*** 備料*/public abstract void preparation();/*** 做菜*/public abstract void doing();/*** 上菜*/public abstract void carriedDishes (); }

    b. 下來做兩個番茄炒蛋(EggsWithTomato)和紅燒肉(Bouilli)實現(xiàn)父類中的抽象方法

    public class EggsWithTomato extends Dish {@Overridepublic void preparation() {System.out.println("洗并切西紅柿,打雞蛋。");}@Overridepublic void doing() {System.out.println("雞蛋倒入鍋里,然后倒入西紅柿一起炒。");}@Overridepublic void carriedDishes() {System.out.println("將炒好的西紅寺雞蛋裝入碟子里,端給客人吃。");}} public class Bouilli extends Dish{@Overridepublic void preparation() {System.out.println("切豬肉和土豆。");}@Overridepublic void doing() {System.out.println("將切好的豬肉倒入鍋中炒一會然后倒入土豆連炒帶燉。");}@Overridepublic void carriedDishes() {System.out.println("將做好的紅燒肉盛進碗里端給客人吃。");}}

    c. 在測試類中我們來做菜:

    public class MainTest {public static void main(String[] args) {Dish eggsWithTomato = new EggsWithTomato();eggsWithTomato.dodish();System.out.println("-----------------------------");Dish bouilli = new Bouilli();bouilli.dodish();}}

    13.2 模板模式的優(yōu)點和缺點
    優(yōu)點:

    (1)具體細節(jié)步驟實現(xiàn)定義在子類中,子類定義詳細處理算法是不會改變算法整體結構。

    (2)代碼復用的基本技術,在數(shù)據(jù)庫設計中尤為重要。

    (3)存在一種反向的控制結構,通過一個父類調用其子類的操作,通過子類對父類進行擴展增加新的行為,符合“開閉原則”。

    缺點:
    每個不同的實現(xiàn)都需要定義一個子類,會導致類的個數(shù)增加,系統(tǒng)更加龐大。

    14 觀察者模式
    定義: 定義對象間的一種一對多的依賴關系,當一個對象的狀態(tài)發(fā)生改變時,所有依賴于它的對象都得到通知并被自動更新。

    主要解決:一個對象狀態(tài)改變給其他對象通知的問題,而且要考慮到易用和低耦合,保證高度的協(xié)作。

    何時使用:一個對象(目標對象)的狀態(tài)發(fā)生改變,所有的依賴對象(觀察者對象)都將得到通知,進行廣播通知。

    如何解決:使用面向對象技術,可以將這種依賴關系弱化。

    關鍵代碼:在抽象類里有一個 ArrayList 存放觀察者們。

    優(yōu)點: 1、觀察者和被觀察者是抽象耦合的。 2、建立一套觸發(fā)機制。

    缺點: 1、如果一個被觀察者對象有很多的直接和間接的觀察者的話,將所有的觀察者都通知到會花費很多時間。 2、如果在觀察者和觀察目標之間有循環(huán)依賴的話,觀察目標會觸發(fā)它們之間進行循環(huán)調用,可能導致系統(tǒng)崩潰。 3、觀察者模式沒有相應的機制讓觀察者知道所觀察的目標對象是怎么發(fā)生變化的,而僅僅只是知道觀察目標發(fā)生了變化。

    14.1 模式結構圖和代碼示例

    抽象被觀察者角色:也就是一個抽象主題,它把所有對觀察者對象的引用保存在一個集合中,每個主題都可以有任意數(shù)量的觀察者。抽象主題提供一個接口,可以增加和刪除觀察者角色。一般用一個抽象類和接口來實現(xiàn)。

    抽象觀察者角色:為所有的具體觀察者定義一個接口,在得到主題通知時更新自己。

    具體被觀察者角色:也就是一個具體的主題,在集體主題的內部狀態(tài)改變時,所有登記過的觀察者發(fā)出通知。

    具體觀察者角色:實現(xiàn)抽象觀察者角色所需要的更新接口,一邊使本身的狀態(tài)與制圖的狀態(tài)相協(xié)調。

    舉例(有一個微信公眾號服務,不定時發(fā)布一些消息,關注公眾號就可以收到推送消息,取消關注就收不到推送消息。)類圖如下:

    1、定義一個抽象被觀察者接口

    public interface Subject {public void registerObserver(Observer o);public void removeObserver(Observer o);public void notifyObserver();}

    2、定義一個抽象觀察者接口

    public interface Observer {public void update(String message);}

    3、定義被觀察者,實現(xiàn)了Observerable接口,對Observerable接口的三個方法進行了具體實現(xiàn),同時有一個List集合,用以保存注冊的觀察者,等需要通知觀察者時,遍歷該集合即可。

    public class WechatServer implements Subject {private List<Observer> list;private String message;public WechatServer() {list = new ArrayList<Observer>();}@Overridepublic void registerObserver(Observer o) {// TODO Auto-generated method stublist.add(o);}@Overridepublic void removeObserver(Observer o) {// TODO Auto-generated method stubif (!list.isEmpty()) {list.remove(o);}}@Overridepublic void notifyObserver() {// TODO Auto-generated method stubfor (Observer o : list) {o.update(message);}}public void setInfomation(String s) {this.message = s;System.out.println("微信服務更新消息: " + s);// 消息更新,通知所有觀察者notifyObserver();}}

    4、定義具體觀察者,微信公眾號的具體觀察者為用戶User

    public class User implements Observer {private String name;private String message;public User(String name) {this.name = name;}@Overridepublic void update(String message) {this.message = message;read();}public void read() {System.out.println(name + " 收到推送消息: " + message);}}

    5、編寫一個測試類

    public class MainTest {public static void main(String[] args) {WechatServer server = new WechatServer();Observer userZhang = new User("ZhangSan");Observer userLi = new User("LiSi");Observer userWang = new User("WangWu");server.registerObserver(userZhang);server.registerObserver(userLi);server.registerObserver(userWang);server.setInfomation("PHP是世界上最好用的語言!");System.out.println("----------------------------------------------");server.removeObserver(userZhang);server.setInfomation("JAVA是世界上最好用的語言!");}}

    15 迭代器模式
    定義:提供一種方法順序訪問一個聚合對象中各個元素, 而又無須暴露該對象的內部表示。

    簡單來說,不同種類的對象可能需要不同的遍歷方式,我們對每一種類型的對象配一個迭代器,最后多個迭代器合成一個。

    主要解決:不同的方式來遍歷整個整合對象。

    何時使用:遍歷一個聚合對象。

    如何解決:把在元素之間游走的責任交給迭代器,而不是聚合對象。

    關鍵代碼:定義接口:hasNext, next。

    應用實例:JAVA 中的 iterator。

    優(yōu)點: 1、它支持以不同的方式遍歷一個聚合對象。 2、迭代器簡化了聚合類。 3、在同一個聚合上可以有多個遍歷。 4、在迭代器模式中,增加新的聚合類和迭代器類都很方便,無須修改原有代碼。

    缺點:由于迭代器模式將存儲數(shù)據(jù)和遍歷數(shù)據(jù)的職責分離,增加新的聚合類需要對應增加新的迭代器類,類的個數(shù)成對增加,這在一定程度上增加了系統(tǒng)的復雜性。

    15.1 模式結構和代碼示例

    (1)迭代器角色(Iterator):定義遍歷元素所需要的方法,一般來說會有這么三個方法:取得下一個元素的方法next(),判斷是否遍歷結束的方法hasNext()),移出當前對象的方法remove(),

    (2)具體迭代器角色(Concrete Iterator):實現(xiàn)迭代器接口中定義的方法,完成集合的迭代。

    (3)容器角色(Aggregate): 一般是一個接口,提供一個iterator()方法,例如java中的Collection接口,List接口,Set接口等

    (4)具體容器角色(ConcreteAggregate):就是抽象容器的具體實現(xiàn)類,比如List接口的有序列表實現(xiàn)ArrayList,List接口的鏈表實現(xiàn)LinkList,Set接口的哈希列表的實現(xiàn)HashSet等。

    舉例(咖啡廳和中餐廳合并,他們兩個餐廳的菜單一個是數(shù)組保存的,一個是ArrayList保存的。遍歷方式不一樣,使用迭代器聚合訪問,只需要一種方式)


    1 迭代器接口?

    public interface Iterator {public boolean hasNext();public Object next();}

    2 咖啡店菜單和咖啡店菜單遍歷器

    public class CakeHouseMenu {private ArrayList<MenuItem> menuItems;public CakeHouseMenu() {menuItems = new ArrayList<MenuItem>();addItem("KFC Cake Breakfast","boiled eggs&toast&cabbage",true,3.99f);addItem("MDL Cake Breakfast","fried eggs&toast",false,3.59f);addItem("Stawberry Cake","fresh stawberry",true,3.29f);addItem("Regular Cake Breakfast","toast&sausage",true,2.59f);}private void addItem(String name, String description, boolean vegetable,float price) {MenuItem menuItem = new MenuItem(name, description, vegetable, price);menuItems.add(menuItem);}public Iterator getIterator(){return new CakeHouseIterator() ;}class CakeHouseIterator implements Iterator{ private int position=0;public CakeHouseIterator(){position=0;}@Overridepublic boolean hasNext() {// TODO Auto-generated method stubif(position<menuItems.size()){return true;}return false;}@Overridepublic Object next() {// TODO Auto-generated method stubMenuItem menuItem =menuItems.get(position);position++;return menuItem;}};//鍏朵粬鍔熻兘浠g爜}

    3 中餐廳菜單和中餐廳菜單遍歷器

    public class DinerMenu {private final static int Max_Items = 5;private int numberOfItems = 0;private MenuItem[] menuItems;public DinerMenu() {menuItems = new MenuItem[Max_Items];addItem("vegetable Blt", "bacon&lettuce&tomato&cabbage", true, 3.58f);addItem("Blt", "bacon&lettuce&tomato", false, 3.00f);addItem("bean soup", "bean&potato salad", true, 3.28f);addItem("hotdog", "onions&cheese&bread", false, 3.05f);}private void addItem(String name, String description, boolean vegetable,float price) {MenuItem menuItem = new MenuItem(name, description, vegetable, price);if (numberOfItems >= Max_Items) {System.err.println("sorry,menu is full!can not add another item");} else {menuItems[numberOfItems] = menuItem;numberOfItems++;}}public Iterator getIterator() {return new DinerIterator();}class DinerIterator implements Iterator {private int position;public DinerIterator() {position = 0;}@Overridepublic boolean hasNext() {// TODO Auto-generated method stubif (position < numberOfItems) {return true;}return false;}@Overridepublic Object next() {// TODO Auto-generated method stubMenuItem menuItem = menuItems[position];position++;return menuItem;}}; }

    4 女服務員

    public class Waitress {private ArrayList<Iterator> iterators = new ArrayList<Iterator>();public Waitress() {}public void addIterator(Iterator iterator) {iterators.add(iterator);}public void printMenu() {Iterator iterator;MenuItem menuItem;for (int i = 0, len = iterators.size(); i < len; i++) {iterator = iterators.get(i);while (iterator.hasNext()) {menuItem = (MenuItem) iterator.next();System.out.println(menuItem.getName() + "***" + menuItem.getPrice() + "***" + menuItem.getDescription());}}}public void printBreakfastMenu() {}public void printLunchMenu() {}public void printVegetableMenu() {} }

    16 責任鏈模式
    定義:如果有多個對象有機會處理請求,責任鏈可使請求的發(fā)送者和接受者解耦,請求沿著責任鏈傳遞,直到有一個對象處理了它為止。

    主要解決:職責鏈上的處理者負責處理請求,客戶只需要將請求發(fā)送到職責鏈上即可,無須關心請求的處理細節(jié)和請求的傳遞,所以職責鏈將請求的發(fā)送者和請求的處理者解耦了。

    何時使用:在處理消息的時候以過濾很多道。

    如何解決:攔截的類都實現(xiàn)統(tǒng)一接口。

    關鍵代碼:Handler 里面聚合它自己,在 HandlerRequest 里判斷是否合適,如果沒達到條件則向下傳遞,向誰傳遞之前 set 進去。

    16.1 模式的結構和代碼示例

    抽象處理者(Handler)角色:定義一個處理請求的接口,包含抽象處理方法和一個后繼連接。

    具體處理者(Concrete Handler)角色:實現(xiàn)抽象處理者的處理方法,判斷能否處理本次請求,如果可以處理請求則處理,否則將該請求轉給它的后繼者。

    客戶類(Client)角色:創(chuàng)建處理鏈,并向鏈頭的具體處理者對象提交請求,它不關心處理細節(jié)和請求的傳遞過程。

    舉例(購買請求決策,價格不同要由不同的級別決定:組長、部長、副部、總裁)。類圖如下:

    1 決策者抽象類,包含對請求處理的函數(shù),同時還包含指定下一個決策者的函數(shù)

    public abstract class Approver {Approver successor;String Name;public Approver(String Name){this.Name=Name;}public abstract void ProcessRequest( PurchaseRequest request);public void SetSuccessor(Approver successor) {// TODO Auto-generated method stubthis.successor=successor;} }

    2 客戶端以及請求

    public class PurchaseRequest {private int Type = 0;private int Number = 0;private float Price = 0;private int ID = 0;public PurchaseRequest(int Type, int Number, float Price) {this.Type = Type;this.Number = Number;this.Price = Price;}public int GetType() {return Type;}public float GetSum() {return Number * Price;}public int GetID() {return (int) (Math.random() * 1000);} } public class Client {public Client() {}public PurchaseRequest sendRequst(int Type, int Number, float Price) {return new PurchaseRequest(Type, Number, Price);}}

    3 組長、部長。。。繼承決策者抽象類

    public class GroupApprover extends Approver {public GroupApprover(String Name) {super(Name + " GroupLeader");// TODO Auto-generated constructor stub}@Overridepublic void ProcessRequest(PurchaseRequest request) {// TODO Auto-generated method stubif (request.GetSum() < 5000) {System.out.println("**This request " + request.GetID() + " will be handled by " + this.Name + " **");} else {successor.ProcessRequest(request);}}} public class DepartmentApprover extends Approver {public DepartmentApprover(String Name) {super(Name + " DepartmentLeader");}@Overridepublic void ProcessRequest(PurchaseRequest request) {// TODO Auto-generated method stubif ((5000 <= request.GetSum()) && (request.GetSum() < 10000)) {System.out.println("**This request " + request.GetID()+ " will be handled by " + this.Name + " **");} else {successor.ProcessRequest(request);}}}

    4測試

    public class MainTest {public static void main(String[] args) {Client mClient = new Client();Approver GroupLeader = new GroupApprover("Tom");Approver DepartmentLeader = new DepartmentApprover("Jerry");Approver VicePresident = new VicePresidentApprover("Kate");Approver President = new PresidentApprover("Bush");GroupLeader.SetSuccessor(VicePresident);DepartmentLeader.SetSuccessor(President);VicePresident.SetSuccessor(DepartmentLeader);President.SetSuccessor(GroupLeader);GroupLeader.ProcessRequest(mClient.sendRequst(1, 10000, 40));}}

    17 命令模式
    定義:將一個請求封裝為一個對象,使發(fā)出請求的責任和執(zhí)行請求的責任分割開。這樣兩者之間通過命令對象進行溝通,這樣方便將命令對象進行儲存、傳遞、調用、增加與管理。

    意圖:將一個請求封裝成一個對象,從而使您可以用不同的請求對客戶進行參數(shù)化。

    主要解決:在軟件系統(tǒng)中,行為請求者與行為實現(xiàn)者通常是一種緊耦合的關系,但某些場合,比如需要對行為進行記錄、撤銷或重做、事務等處理時,這種無法抵御變化的緊耦合的設計就不太合適。

    何時使用:在某些場合,比如要對行為進行"記錄、撤銷/重做、事務"等處理,這種無法抵御變化的緊耦合是不合適的。在這種情況下,如何將"行為請求者"與"行為實現(xiàn)者"解耦?將一組行為抽象為對象,可以實現(xiàn)二者之間的松耦合。

    如何解決:通過調用者調用接受者執(zhí)行命令,順序:調用者→接受者→命令。

    17.1模式結構和代碼示例

    1抽象命令類(Command)角色:聲明執(zhí)行命令的接口,擁有執(zhí)行命令的抽象方法 execute()。
    2具體命令角色(Concrete Command)角色:是抽象命令類的具體實現(xiàn)類,它擁有接收者對象,并通過調用接收者的功能來完成命令要執(zhí)行的操作。
    3實現(xiàn)者/接收者(Receiver)角色:執(zhí)行命令功能的相關操作,是具體命令對象業(yè)務的真正實現(xiàn)者。
    4調用者/請求者(Invoker)角色:是請求的發(fā)送者,它通常擁有很多的命令對象,并通過訪問命令對象來執(zhí)行相關請求,它不直接訪問接收者。
    代碼舉例(開燈和關燈),類圖如下:

    1 命令抽象類

    public interface Command {public void excute();public void undo();}

    2 具體命令對象

    public class TurnOffLight implements Command {private Light light;public TurnOffLight(Light light) {this.light = light;}@Overridepublic void excute() {// TODO Auto-generated method stublight.Off();}@Overridepublic void undo() {// TODO Auto-generated method stublight.On();}}

    3 實現(xiàn)者

    public class Light {String loc = "";public Light(String loc) {this.loc = loc;}public void On() {System.out.println(loc + " On");}public void Off() {System.out.println(loc + " Off");}}

    4 請求者

    public class Contral{public void CommandExcute(Command command) {// TODO Auto-generated method stubcommand.excute();}public void CommandUndo(Command command) {// TODO Auto-generated method stubcommand.undo();}}

    18 狀態(tài)模式

    概述

    狀態(tài)模式在日常開發(fā)中是一個非常實用的模式,可以將你的代碼逼格迅速提升一個檔次,所以讓我們開始今天的卓越之旅吧

    定義

    當一個對象內在狀態(tài)改變時允許改變其行為,這個對象看起來像是改變了其類。

    定義對于初學者沒啥用,因為字都認識卻無法理解其中的含義。必須等學完了,回過頭來看才能更加深刻的理解其含義

    使用場景

    你發(fā)現(xiàn)你的代碼里面存在一個很長的if else列表,而這些分支都是因為不同狀態(tài)下執(zhí)行的操作不一樣時考慮使用此模式

    UML類圖

    照例先上一張俺手撕的UML類圖

    從上圖可見,狀態(tài)模式共有3個角色

    • State

    是一個接口,封裝了狀態(tài)及其行為

    • ConcreteState X

    State的實現(xiàn)類,表示具體的狀態(tài)

    • Context

    保持并切換各個狀態(tài),其持有一個State的引用。它將依賴狀態(tài)的各種操作委托給不同的狀態(tài)對象執(zhí)行。其負責與客戶端交互

    實例

    最近王二狗又要過生日了,近兩年他內心中是非常抗拒過生日的,因為每過一個生日就意味著自己又老一歲,離被辭退的35歲魔咒又近了一步。可惜時間是不以人的意志為轉移的,任何人都阻止不了時間的流逝,所以該過還的過。令二狗比較欣慰的時,這次過生日老婆送了他一個自己一直想要的機械鍵盤作為生日禮物... 翠花于是在二狗生日前3天在京東上下了一個單...

    自從下單以來,二狗天天看物流狀態(tài)信息,心心念念著自己的機械鍵盤快點到...

    這個物流系統(tǒng)就很適合使用狀態(tài)模式來開發(fā),因為此過程存在很多不同的狀態(tài),例如接單,出庫,運輸,送貨,收貨,評價等等。而訂單在每個不同的狀態(tài)下的操作可能都不一樣,例如在接單狀態(tài)下,商家就需要通知倉庫揀貨,通知用戶等等操作,其他狀態(tài)類似

    下面是實例的UML類圖

    第一,定義一個狀態(tài)接口

    此接口定義各個狀態(tài)的統(tǒng)一操作接口

    public interface LogisticsState {void doAction(JdLogistics context); }

    第二,定義一個物流Context類

    此類持有一個LogisticsState?的引用,負責在流程中保持并切換狀態(tài)

    public class JdLogistics {private LogisticsState logisticsState;public void setLogisticsState(LogisticsState logisticsState) {this.logisticsState = logisticsState;}public LogisticsState getLogisticsState() {return logisticsState;}public void doAction(){Objects.requireNonNull(logisticsState);logisticsState.doAction(this);} }

    第三,實現(xiàn)各種狀態(tài)類

    • 接單狀態(tài)類,其需要實現(xiàn)LogisticsState接口
    public class OrderState implements LogisticsState {@Overridepublic void doAction(JdLogistics context) {System.out.println("商家已經接單,正在處理中...");} }
    • 出庫狀態(tài)類
    public class ProductOutState implements LogisticsState {@Overridepublic void doAction(JdLogistics context) {System.out.println("商品已經出庫...");} }

    依次類推,可以建立任意多個狀態(tài)類

    第四, 客戶端使用

    public class StateClient {public void buyKeyboard() {//狀態(tài)的保持與切換者JdLogistics jdLogistics = new JdLogistics();//接單狀態(tài)OrderState orderState = new OrderState();jdLogistics.setLogisticsState(orderState);jdLogistics.doAction();//出庫狀態(tài)ProductOutState productOutState = new ProductOutState();jdLogistics.setLogisticsState(productOutState);jdLogistics.doAction();//運輸狀態(tài)TransportState transportState = new TransportState();jdLogistics.setLogisticsState(transportState);jdLogistics.doAction();} }

    輸出結果:

    商家已經接單,正在處理中... 商品已經出庫... 商品正在運往天津分發(fā)中心

    可見,我們將每個狀態(tài)下要做的具體動作封裝到了每個狀態(tài)類中,我們只需要切換不同的狀態(tài)即可。如果不使用狀態(tài)模式,我們的代碼中可能會出現(xiàn)很長的if else列表,這樣就不便于擴展和修改了。

    技術要點總結

    • 必須要有一個Context類,這個類持有State接口,負責保持并切換當前的狀態(tài)。
    • 狀態(tài)模式沒有定義在哪里進行狀態(tài)轉換,本例是在Context類進行的,也有人在具體的State類中轉換

    當使用Context類切換狀態(tài)時,狀態(tài)類之間互相不認識,他們直接的依賴關系應該由客戶端負責。 例如,只有在接單狀態(tài)的操作完成后才應該切換到出庫狀態(tài),那么出庫狀態(tài)就對接單狀態(tài)有了依賴,這個依賴順序應該由客戶端負責,而不是在狀態(tài)內判斷。

    當使用具體的State類切換時,狀態(tài)直接就可能互相認識,一個狀態(tài)執(zhí)行完就自動切換到了另一個狀態(tài)去了

    優(yōu)缺點

    優(yōu)點

    • 增強了程序的可擴展性,因為我們很容易添加一個State
    • 增強了程序的封裝性,每個狀態(tài)的操作都被封裝到了一個狀態(tài)類中

    缺點

    類變多了

    狀態(tài)模式與策略模式

    狀態(tài)模式與策略模式的UML類圖都是一樣的,從表面上看他們非常相似。特別是將狀態(tài)切換任務放在Context中做的時候就更像了,但是其背后的思想卻非常不同。

    • 策略模式定義了一組可互相代替的算法,這一組算法對象完成的是同一個任務,只是使用的方式不同,例如同樣是億萬富翁,馬云通過賣東西實現(xiàn),而王思聰通過繼承實現(xiàn)。
    • 狀態(tài)模式不同的狀態(tài)完成的任務完全不一樣。

    19 備忘錄模式
    定義: 在不破壞封裝性的前提下,捕獲一個對象的內部狀態(tài),并在該對象之外保存這個狀態(tài),以便以后當需要時能將該對象恢復到原先保存的狀態(tài)。該模式又叫快照模式。

    備忘錄模式是一種對象行為型模式,其主要優(yōu)點如下。

    提供了一種可以恢復狀態(tài)的機制。當用戶需要時能夠比較方便地將數(shù)據(jù)恢復到某個歷史的狀態(tài)。

    實現(xiàn)了內部狀態(tài)的封裝。除了創(chuàng)建它的發(fā)起人之外,其他對象都不能夠訪問這些狀態(tài)信息。

    簡化了發(fā)起人類。發(fā)起人不需要管理和保存其內部狀態(tài)的各個備份,所有狀態(tài)信息都保存在備忘錄中,并由管理者進行管理,這符合單一職責原則。

    其主要缺點是:資源消耗大。如果要保存的內部狀態(tài)信息過多或者特別頻繁,將會占用比較大的內存資源。

    19.1 模式結構圖和代碼示例

    1發(fā)起人(Originator)角色:記錄當前時刻的內部狀態(tài)信息,提供創(chuàng)建備忘錄和恢復備忘錄數(shù)據(jù)的功能,實現(xiàn)其他業(yè)務功能,它可以訪問備忘錄里的所有信息。

    2備忘錄(Memento)角色:負責存儲發(fā)起人的內部狀態(tài),在需要的時候提供這些內部狀態(tài)給發(fā)起人。

    3管理者(Caretaker)角色:對備忘錄進行管理,提供保存與獲取備忘錄的功能,但其不能對備忘錄的內容進行訪問與修改。
    舉例(發(fā)起者通過備忘錄存儲信息和獲取信息),類圖如下:

    1 備忘錄接口

    public interface MementoIF {}

    2 備忘錄

    public class Memento implements MementoIF{private String state;public Memento(String state) {this.state = state;}public String getState(){return state;}}

    ?3 發(fā)起者

    public class Originator {private String state;public String getState() {return state;}public void setState(String state) {this.state = state;}public Memento saveToMemento() {return new Memento(state);}public String getStateFromMemento(MementoIF memento) {return ((Memento) memento).getState();}}

    ?4.管理者

    public class CareTaker {private List<MementoIF> mementoList = new ArrayList<MementoIF>();public void add(MementoIF memento) {mementoList.add(memento);}public MementoIF get(int index) {return mementoList.get(index);}}

    20 訪問者模式
    定義:將作用于某種數(shù)據(jù)結構中的各元素的操作分離出來封裝成獨立的類,使其在不改變數(shù)據(jù)結構的前提下可以添加作用于這些元素的新的操作,為數(shù)據(jù)結構中的每個元素提供多種訪問方式。它將對數(shù)據(jù)的操作與數(shù)據(jù)結構進行分離。

    訪問者(Visitor)模式是一種對象行為型模式,其主要優(yōu)點如下。

    擴展性好。能夠在不修改對象結構中的元素的情況下,為對象結構中的元素添加新的功能。

    復用性好。可以通過訪問者來定義整個對象結構通用的功能,從而提高系統(tǒng)的復用程度。

    靈活性好。訪問者模式將數(shù)據(jù)結構與作用于結構上的操作解耦,使得操作集合可相對自由地演化而不影響系統(tǒng)的數(shù)據(jù)結構。

    符合單一職責原則。訪問者模式把相關的行為封裝在一起,構成一個訪問者,使每一個訪問者的功能都比較單一。

    訪問者(Visitor)模式的主要缺點如下。

    增加新的元素類很困難。在訪問者模式中,每增加一個新的元素類,都要在每一個具體訪問者類中增加相應的具體操作,這違背了“開閉原則”。

    破壞封裝。訪問者模式中具體元素對訪問者公布細節(jié),這破壞了對象的封裝性。

    違反了依賴倒置原則。訪問者模式依賴了具體類,而沒有依賴抽象類。

    20.1 模式結構和代碼示例

    訪問者模式包含以下主要角色。

    1抽象訪問者(Visitor)角色:定義一個訪問具體元素的接口,為每個具體元素類對應一個訪問操作 visit() ,該操作中的參數(shù)類型標識了被訪問的具體元素。

    2具體訪問者(ConcreteVisitor)角色:實現(xiàn)抽象訪問者角色中聲明的各個訪問操作,確定訪問者訪問一個元素時該做什么。

    3抽象元素(Element)角色:聲明一個包含接受操作 accept() 的接口,被接受的訪問者對象作為 accept() 方法的參數(shù)。

    4具體元素(ConcreteElement)角色:實現(xiàn)抽象元素角色提供的 accept() 操作,其方法體通常都是 visitor.visit(this) ,另外具體元素中可能還包含本身業(yè)務邏輯的相關操作。

    5對象結構(Object Structure)角色:是一個包含元素角色的容器,提供讓訪問者對象遍歷容器中的所有元素的方法,通常由 List、Set、Map 等聚合類實現(xiàn)。

    1 抽象訪問者

    public interface Visitor {abstract public void Visit(Element element); }

    2 具體訪問者

    public class CompensationVisitor implements Visitor {@Overridepublic void Visit(Element element) {// TODO Auto-generated method stubEmployee employee = ((Employee) element);System.out.println(employee.getName() + "'s Compensation is " + (employee.getDegree() * employee.getVacationDays() * 10));}}

    3 抽象元素

    public interface Element {abstract public void Accept(Visitor visitor);}

    4 具體元素

    public class CompensationVisitor implements Visitor {@Overridepublic void Visit(Element element) {// TODO Auto-generated method stubEmployee employee = ((Employee) element);System.out.println(employee.getName() + "'s Compensation is " + (employee.getDegree() * employee.getVacationDays() * 10));}}

    5 對象結構

    public class ObjectStructure {private HashMap<String, Employee> employees;public ObjectStructure() {employees = new HashMap();}public void Attach(Employee employee) {employees.put(employee.getName(), employee);}public void Detach(Employee employee) {employees.remove(employee);}public Employee getEmployee(String name) {return employees.get(name);}public void Accept(Visitor visitor) {for (Employee e : employees.values()) {e.Accept(visitor);}}}

    21 中介者模式
    定義:定義一個中介對象來封裝一系列對象之間的交互,使原有對象之間的耦合松散,且可以獨立地改變它們之間的交互。中介者模式又叫調停模式,它是迪米特法則的典型應用。

    中介者模式是一種對象行為型模式,其主要優(yōu)點如下。

    降低了對象之間的耦合性,使得對象易于獨立地被復用。

    將對象間的一對多關聯(lián)轉變?yōu)橐粚σ坏年P聯(lián),提高系統(tǒng)的靈活性,使得系統(tǒng)易于維護和擴展。

    其主要缺點是:當同事類太多時,中介者的職責將很大,它會變得復雜而龐大,以至于系統(tǒng)難以維護。

    21.1 模式結構和代碼示例


    抽象中介者(Mediator)角色:它是中介者的接口,提供了同事對象注冊與轉發(fā)同事對象信息的抽象方法。

    具體中介者(ConcreteMediator)角色:實現(xiàn)中介者接口,定義一個 List 來管理同事對象,協(xié)調各個同事角色之間的交互關系,因此它依賴于同事角色。

    抽象同事類(Colleague)角色:定義同事類的接口,保存中介者對象,提供同事對象交互的抽象方法,實現(xiàn)所有相互影響的同事類的公共功能。

    具體同事類(Concrete Colleague)角色:是抽象同事類的實現(xiàn)者,當需要與其他同事對象交互時,由中介者對象負責后續(xù)的交互。

    舉例(通過中介賣方),類圖如下:


    1 抽象中介者

    public interface Mediator {void register(Colleague colleague); // 客戶注冊void relay(String from, String to,String ad); // 轉發(fā)}

    2 具體中介者

    public class ConcreteMediator implements Mediator {private List<Colleague> colleagues = new ArrayList<Colleague>();@Overridepublic void register(Colleague colleague) {// TODO Auto-generated method stubif (!colleagues.contains(colleague)) {colleagues.add(colleague);colleague.setMedium(this);}}@Overridepublic void relay(String from, String to, String ad) {// TODO Auto-generated method stubfor (Colleague cl : colleagues) {String name = cl.getName();if (name.equals(to)) {cl.receive(from, ad);}}}}

    3 抽象同事類

    public abstract class Colleague {protected Mediator mediator;protected String name;public Colleague(String name) {this.name = name;}public void setMedium(Mediator mediator) {this.mediator = mediator;}public String getName() {return name;}public abstract void Send(String to, String ad);public abstract void receive(String from, String ad);}

    4 具體同事類

    public class Buyer extends Colleague {public Buyer(String name) {super(name);}@Overridepublic void Send(String to, String ad) {// TODO Auto-generated method stubmediator.relay(name, to, ad);}@Overridepublic void receive(String from, String ad) {// TODO Auto-generated method stubSystem.out.println(name + "接收到來自" + from + "的消息:" + ad);}}

    22.解釋器模式
    定義
    給定一個語言,定義它的文法的一種表示,并定義一個解釋器,這個解釋器使用該表示來解釋語言中的句子。
    解釋器模式(Interpreter Pattern)提供了評估語言的語法或表達式的方式,它屬于行為型模式。這種模式實現(xiàn)了一個表達式接口,該接口解釋一個特定的上下文。這種模式被用在 SQL 解析、符號處理引擎等。

    解決
    對于一些固定文法構建一個解釋句子的解釋器。
    解釋器模式(Interpreter)是一種針對特定問題設計的一種解決方案。例如,匹配字符串的時候,由于匹配條件非常靈活,使得通過代碼來實現(xiàn)非常不靈活。

    優(yōu)點
    能夠很容易地改變和擴展文法,因為該模式使用類來表示文法規(guī)則,你可使用繼承來改變或擴展該文法。
    比較容易實現(xiàn)文法,因為定義抽象語法樹中各個節(jié)點地類的實現(xiàn)大體類似,這些類都易于直接編寫。
    缺點
    解釋器模式為文法中的每一條規(guī)則至少定義了一個類,因此包含許多規(guī)則的文法可能難以管理和維護。
    易引起類膨脹。
    可利用的場景較少。
    解釋器模式采用遞歸調用方法。
    結構
    解釋器模式包含如下角色:

    AbstrExpression: 抽象表達式
    TerminalExpression: 終結符表達式
    NonterminalExpression: 非終結符表達式
    Context: 環(huán)境類:包含解釋器之外的一些全局信息

    實現(xiàn)

    package interpreterpattern; /*** 聲明一個抽象的解釋操作,這個接口為抽象語法樹中所有的節(jié)點所共享*/ public abstract class AbstractExpression {public abstract void interpret(Context context); } package interpreterpattern;/*** 實現(xiàn)與文法中的終結符相關聯(lián)的解釋操作,文法中每一個終結符都有一個具體終結表達式與之相對應*/ public class TerminalExpression extends AbstractExpression{@Overridepublic void interpret(Context context) {System.out.println("終端解釋器");} } package interpreterpattern; /*** 非終結符表達式,為文法中的非終結符實現(xiàn)解釋操作。對文法中每一條規(guī)則R1、R2...Rn都需要一個具體的非終結符表達式類。*/ public class NonTerminalExpression extends AbstractExpression{@Overridepublic void interpret(Context context) {System.out.println("非終端解釋器");} } package interpreterpattern; /*** 包含解釋器之外的一些全局信息*/ public class Context {private String input;private String output;public String getInput() {return input;}public void setInput(String input) {this.input = input;}public String getOutput() {return output;}public void setOutput(String output) {this.output = output;} } package interpreterpattern; import java.util.ArrayList; import java.util.List; /*** 構建表示該文法定義的語言中一個特定的句子的抽象語法樹,調用解釋操作*/ public class InterpreterClient {public static void main(String[] args) {Context context = new Context();List<AbstractExpression> list = new ArrayList<AbstractExpression>();list.add(new TerminalExpression());list.add(new NonTerminalExpression());list.add(new TerminalExpression());list.add(new TerminalExpression());for (AbstractExpression expression : list) {expression.interpret(context);}} }

    實例

    做了一個正則化的小例子 該標準是 [單個數(shù)字-單個小寫-單個大寫]

    package interpreterpattern.demo;public abstract class AbstractExpression {public abstract boolean interpret(String info); } package interpreterpattern.demo; import java.util.HashSet; import java.util.Set;public class TerminalExpression extends AbstractExpression{private Set<String> set =new HashSet<String>();public TerminalExpression(String[] data){for(int i=0; i<data.length;i++)set.add(data[i]);}@Overridepublic boolean interpret(String info) {if(set.contains(info)){return true;}return false;} } package interpreterpattern.demo;public class NonTerminalExpression extends AbstractExpression{private AbstractExpression address=null;private AbstractExpression name=null;private AbstractExpression id=null;public NonTerminalExpression(AbstractExpression address, AbstractExpression name, AbstractExpression id) {this.address = address;this.name = name;this.id = id;}@Overridepublic boolean interpret(String info) {String s[]=info.split("-");return address.interpret(s[0])&&name.interpret(s[1])&&id.interpret(s[2]);} } package interpreterpattern.demo; public class Context {private String[] shuzis={"1","2","3","4","5","6","7","8","9","0"};private String[] xiaoxiezimus={"a","b","c","d","e","f","g","h","i","j","k","l"};private String[] daxiezimus={"A","B","C","D","E","F","G"};private AbstractExpression infomation;public Context(){AbstractExpression shuzi=new TerminalExpression(shuzis);AbstractExpression xiaoxiezimu=new TerminalExpression(xiaoxiezimus);AbstractExpression daxiezimu=new TerminalExpression(daxiezimus);infomation=new NonTerminalExpression(shuzi,xiaoxiezimu,daxiezimu);}public void jieshi(String info){boolean ok=infomation.interpret(info);if(ok) System.out.println("正確! ["+info+"] 滿足 [單個數(shù)字-單個小寫-單個大寫] 的條件");else System.out.println("錯誤! ["+info+"] 不滿足 [單個數(shù)字-單個小寫-單個大寫] 的條件");} } package interpreterpattern.demo; public class InterpreterClient {public static void main(String[] args) {Context people=new Context();people.jieshi("2-a-A");people.jieshi("11-A-5");people.jieshi("你-好-吖");people.jieshi("2aA");} }

    ?

    總結

    以上是生活随笔為你收集整理的设计模式相关的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    国产精品亚洲а∨无码播放麻豆 | 正在播放老肥熟妇露脸 | 久久99精品久久久久婷婷 | 人妻有码中文字幕在线 | 无码人中文字幕 | 日本精品少妇一区二区三区 | 好男人社区资源 | 蜜臀av在线播放 久久综合激激的五月天 | 国产成人一区二区三区在线观看 | 亚洲国产欧美在线成人 | 国产人成高清在线视频99最全资源 | 亚洲欧美日韩成人高清在线一区 | 亚洲成a人片在线观看无码 | 东京热无码av男人的天堂 | 强开小婷嫩苞又嫩又紧视频 | 国产精品第一区揄拍无码 | 人人澡人摸人人添 | 国产精品久久久久久久影院 | 一本久道久久综合婷婷五月 | a在线观看免费网站大全 | 免费网站看v片在线18禁无码 | 丝袜 中出 制服 人妻 美腿 | 麻花豆传媒剧国产免费mv在线 | 国产欧美熟妇另类久久久 | 乱码av麻豆丝袜熟女系列 | 亚洲人成人无码网www国产 | 色婷婷av一区二区三区之红樱桃 | 四虎国产精品一区二区 | 蜜桃av蜜臀av色欲av麻 999久久久国产精品消防器材 | 伊人久久婷婷五月综合97色 | 自拍偷自拍亚洲精品被多人伦好爽 | 丝袜美腿亚洲一区二区 | 人人妻人人澡人人爽欧美精品 | 久热国产vs视频在线观看 | 国产尤物精品视频 | 亚拍精品一区二区三区探花 | 男人的天堂av网站 | 婷婷丁香六月激情综合啪 | 久久亚洲中文字幕无码 | 午夜精品久久久久久久 | 无码人妻精品一区二区三区下载 | 成 人 免费观看网站 | 性做久久久久久久久 | 日日橹狠狠爱欧美视频 | 亚洲精品久久久久中文第一幕 | 永久免费观看美女裸体的网站 | 久久国产精品精品国产色婷婷 | 麻豆国产人妻欲求不满谁演的 | 欧美精品国产综合久久 | 欧美国产日产一区二区 | 高清无码午夜福利视频 | 色妞www精品免费视频 | 国产午夜手机精彩视频 | 欧美性生交xxxxx久久久 | 精品 日韩 国产 欧美 视频 | 国产av久久久久精东av | 精品人妻人人做人人爽夜夜爽 | 亚洲熟妇色xxxxx欧美老妇y | 国产九九九九九九九a片 | 99久久久国产精品无码免费 | 欧美乱妇无乱码大黄a片 | 国产精品亚洲а∨无码播放麻豆 | 欧美黑人巨大xxxxx | 亚洲国产欧美国产综合一区 | 国产成人精品视频ⅴa片软件竹菊 | 国产熟女一区二区三区四区五区 | 亚洲熟妇色xxxxx欧美老妇 | 中文字幕日产无线码一区 | 啦啦啦www在线观看免费视频 | 国语自产偷拍精品视频偷 | 天堂无码人妻精品一区二区三区 | 国产精品自产拍在线观看 | 亚洲国产精品毛片av不卡在线 | 在线 国产 欧美 亚洲 天堂 | 无码人妻久久一区二区三区不卡 | 亚洲精品一区二区三区在线 | 国产成人精品无码播放 | 熟妇人妻无码xxx视频 | 成人无码视频免费播放 | 中国大陆精品视频xxxx | 国内老熟妇对白xxxxhd | 老头边吃奶边弄进去呻吟 | 最近免费中文字幕中文高清百度 | 久久aⅴ免费观看 | 人人澡人人妻人人爽人人蜜桃 | 午夜精品久久久久久久 | 人人爽人人澡人人高潮 | 图片区 小说区 区 亚洲五月 | 亚洲 激情 小说 另类 欧美 | 亚洲 另类 在线 欧美 制服 | 粗大的内捧猛烈进出视频 | 香蕉久久久久久av成人 | 国产 浪潮av性色四虎 | 成熟妇人a片免费看网站 | 300部国产真实乱 | 国产黑色丝袜在线播放 | 内射白嫩少妇超碰 | 精品无人国产偷自产在线 | 亚洲精品欧美二区三区中文字幕 | 亚洲欧洲日本无在线码 | 国产性生交xxxxx无码 | 国产在线aaa片一区二区99 | 人人爽人人澡人人高潮 | 在线观看国产午夜福利片 | 国产色xx群视频射精 | 国产明星裸体无码xxxx视频 | 男女猛烈xx00免费视频试看 | 精品国产一区二区三区av 性色 | 久久亚洲精品中文字幕无男同 | av小次郎收藏 | 国产97在线 | 亚洲 | 国产明星裸体无码xxxx视频 | 亚洲 日韩 欧美 成人 在线观看 | 成人精品视频一区二区 | 成人无码视频在线观看网站 | 日韩亚洲欧美精品综合 | 久久无码专区国产精品s | 免费人成网站视频在线观看 | 一本久久伊人热热精品中文字幕 | 欧美xxxxx精品 | 日本护士毛茸茸高潮 | 波多野结衣 黑人 | 国内精品久久久久久中文字幕 | 强伦人妻一区二区三区视频18 | 中文字幕日产无线码一区 | 青青青爽视频在线观看 | 熟妇女人妻丰满少妇中文字幕 | 日韩精品无码一本二本三本色 | 国产亚av手机在线观看 | 亚洲精品www久久久 | 亚洲国产精品无码久久久久高潮 | ass日本丰满熟妇pics | 人人妻人人澡人人爽精品欧美 | 欧美精品国产综合久久 | 亚洲欧美日韩成人高清在线一区 | 色欲综合久久中文字幕网 | www国产亚洲精品久久久日本 | 全黄性性激高免费视频 | 夜精品a片一区二区三区无码白浆 | 少妇厨房愉情理9仑片视频 | 国产成人精品优优av | 久久国内精品自在自线 | 亚洲日韩乱码中文无码蜜桃臀网站 | 丰满妇女强制高潮18xxxx | 色欲综合久久中文字幕网 | 色情久久久av熟女人妻网站 | 国产情侣作爱视频免费观看 | 国产精品久久国产三级国 | 国产日产欧产精品精品app | 在线精品亚洲一区二区 | 黑森林福利视频导航 | 亚洲熟妇色xxxxx亚洲 | 99久久精品国产一区二区蜜芽 | 国产性生大片免费观看性 | 女人被爽到呻吟gif动态图视看 | 玩弄人妻少妇500系列视频 | 国产精品人妻一区二区三区四 | 国产情侣作爱视频免费观看 | 国内揄拍国内精品少妇国语 | 亚洲欧美精品aaaaaa片 | 国产无av码在线观看 | 精品国产aⅴ无码一区二区 | 无码毛片视频一区二区本码 | 老熟妇乱子伦牲交视频 | 无码人妻精品一区二区三区不卡 | 又黄又爽又色的视频 | 欧美人与禽猛交狂配 | 亚洲 另类 在线 欧美 制服 | 色妞www精品免费视频 | 亚洲小说春色综合另类 | 两性色午夜视频免费播放 | 狠狠躁日日躁夜夜躁2020 | 无码人妻丰满熟妇区五十路百度 | 少妇高潮喷潮久久久影院 | 亚洲精品综合一区二区三区在线 | 影音先锋中文字幕无码 | 性做久久久久久久免费看 | 亚洲欧美色中文字幕在线 | 中文字幕乱妇无码av在线 | 亚洲a无码综合a国产av中文 | 亚洲精品国产精品乱码视色 | 国产精华av午夜在线观看 | 国产精品欧美成人 | 欧美精品无码一区二区三区 | 亚洲啪av永久无码精品放毛片 | 97资源共享在线视频 | 国产黑色丝袜在线播放 | 国产精品人人妻人人爽 | 国产成人午夜福利在线播放 | 久久视频在线观看精品 | 乱人伦中文视频在线观看 | 欧美日韩综合一区二区三区 | 国产精品内射视频免费 | 日韩欧美中文字幕公布 | 国产精品-区区久久久狼 | 图片区 小说区 区 亚洲五月 | 亚洲娇小与黑人巨大交 | 欧美兽交xxxx×视频 | 狠狠色噜噜狠狠狠狠7777米奇 | 成人片黄网站色大片免费观看 | 国产精品人人爽人人做我的可爱 | 亚洲国产精品久久人人爱 | 亚洲s码欧洲m码国产av | 无码午夜成人1000部免费视频 | 波多野42部无码喷潮在线 | 对白脏话肉麻粗话av | 人妻少妇精品久久 | 99视频精品全部免费免费观看 | 精品国产一区二区三区四区 | www国产亚洲精品久久久日本 | 无码人妻丰满熟妇区毛片18 | 乱中年女人伦av三区 | a片免费视频在线观看 | 国产xxx69麻豆国语对白 | 亚洲成a人片在线观看无码3d | 久久久久久九九精品久 | 蜜臀av无码人妻精品 | 亚洲国产精品成人久久蜜臀 | 无码毛片视频一区二区本码 | 麻豆果冻传媒2021精品传媒一区下载 | 少妇无码吹潮 | 国产两女互慰高潮视频在线观看 | 精品国产av色一区二区深夜久久 | 夜夜夜高潮夜夜爽夜夜爰爰 | 大乳丰满人妻中文字幕日本 | 成人亚洲精品久久久久 | 久久综合久久自在自线精品自 | 国产一精品一av一免费 | 中文字幕人成乱码熟女app | 久久精品中文闷骚内射 | 国产激情无码一区二区app | 国产精品va在线观看无码 | 免费无码av一区二区 | 国产成人综合美国十次 | 一二三四在线观看免费视频 | 成在人线av无码免观看麻豆 | 无遮挡国产高潮视频免费观看 | 97夜夜澡人人爽人人喊中国片 | 少妇厨房愉情理9仑片视频 | 性欧美牲交在线视频 | 精品偷拍一区二区三区在线看 | 日欧一片内射va在线影院 | 成人无码影片精品久久久 | 天天躁日日躁狠狠躁免费麻豆 | 国产人妻精品一区二区三区不卡 | 一本一道久久综合久久 | 久久无码人妻影院 | 麻豆成人精品国产免费 | 亚洲欧美综合区丁香五月小说 | 内射后入在线观看一区 | 亚洲狠狠色丁香婷婷综合 | 国产在线精品一区二区三区直播 | 国产一区二区三区精品视频 | 国精产品一区二区三区 | 亚洲国产精品毛片av不卡在线 | 老太婆性杂交欧美肥老太 | 曰本女人与公拘交酡免费视频 | 国内精品人妻无码久久久影院 | 4hu四虎永久在线观看 | 亚洲精品国偷拍自产在线观看蜜桃 | 亚洲乱码日产精品bd | 成人欧美一区二区三区黑人免费 | 免费看少妇作爱视频 | 免费观看黄网站 | 国产精品香蕉在线观看 | 亚洲综合在线一区二区三区 | 日韩精品a片一区二区三区妖精 | 亚洲日韩av片在线观看 | 日本一区二区三区免费高清 | 成年美女黄网站色大免费视频 | 国产精品18久久久久久麻辣 | 老司机亚洲精品影院 | 日韩无码专区 | 国产激情艳情在线看视频 | 国产偷自视频区视频 | 国产三级久久久精品麻豆三级 | 国产人妻大战黑人第1集 | 国产无遮挡又黄又爽免费视频 | 最新国产乱人伦偷精品免费网站 | 丰满少妇弄高潮了www | 极品尤物被啪到呻吟喷水 | 亚洲一区二区三区播放 | 人人妻人人藻人人爽欧美一区 | 色综合视频一区二区三区 | 纯爱无遮挡h肉动漫在线播放 | 日韩精品无码一本二本三本色 | 99精品国产综合久久久久五月天 | 精品亚洲成av人在线观看 | yw尤物av无码国产在线观看 | 久久精品中文闷骚内射 | 久久久久se色偷偷亚洲精品av | 成年美女黄网站色大免费视频 | 日韩成人一区二区三区在线观看 | 亚洲小说春色综合另类 | 色婷婷综合中文久久一本 | 丰满妇女强制高潮18xxxx | 国内少妇偷人精品视频免费 | 色婷婷综合中文久久一本 | 中文无码成人免费视频在线观看 | 国产精品爱久久久久久久 | 亚洲一区二区三区无码久久 | 精品国产成人一区二区三区 | 欧美午夜特黄aaaaaa片 | 亚洲第一无码av无码专区 | 日本欧美一区二区三区乱码 | 中文字幕人成乱码熟女app | 波多野结衣高清一区二区三区 | 无码一区二区三区在线观看 | 亚洲s码欧洲m码国产av | 男人的天堂av网站 | 国产人妖乱国产精品人妖 | 国产suv精品一区二区五 | 纯爱无遮挡h肉动漫在线播放 | 精品国产av色一区二区深夜久久 | 樱花草在线社区www | 亚洲精品成人av在线 | 国产偷抇久久精品a片69 | 国产亚洲美女精品久久久2020 | 国产特级毛片aaaaaaa高清 | 四虎国产精品一区二区 | 国产片av国语在线观看 | 国产成人无码午夜视频在线观看 | 玩弄人妻少妇500系列视频 | 亚洲 a v无 码免 费 成 人 a v | 免费无码av一区二区 | 激情爆乳一区二区三区 | 日韩 欧美 动漫 国产 制服 | 亚洲国产精品美女久久久久 | 免费人成在线视频无码 | 国产精品久久久久久亚洲毛片 | 久久久成人毛片无码 | 久久综合香蕉国产蜜臀av | 国产sm调教视频在线观看 | 双乳奶水饱满少妇呻吟 | 亚洲男人av香蕉爽爽爽爽 | 人妻少妇被猛烈进入中文字幕 | 呦交小u女精品视频 | 国产精品成人av在线观看 | 熟女俱乐部五十路六十路av | 亚洲午夜久久久影院 | 久久久中文久久久无码 | 真人与拘做受免费视频 | 国产偷抇久久精品a片69 | 亚洲国产精品美女久久久久 | 亚洲爆乳大丰满无码专区 | 内射老妇bbwx0c0ck | 曰本女人与公拘交酡免费视频 | 欧美怡红院免费全部视频 | 一本久久伊人热热精品中文字幕 | 窝窝午夜理论片影院 | 日日麻批免费40分钟无码 | 欧美性猛交xxxx富婆 | 午夜福利试看120秒体验区 | 欧美丰满熟妇xxxx性ppx人交 | a在线观看免费网站大全 | 人人妻在人人 | 欧洲极品少妇 | 久久久久亚洲精品中文字幕 | a在线观看免费网站大全 | 免费网站看v片在线18禁无码 | 欧美亚洲国产一区二区三区 | 欧美日韩亚洲国产精品 | 东京无码熟妇人妻av在线网址 | 国产熟女一区二区三区四区五区 | 天堂а√在线地址中文在线 | 一区二区传媒有限公司 | 精品无码av一区二区三区 | 国产精品高潮呻吟av久久 | 亚洲人成网站在线播放942 | 亚洲日韩一区二区 | 中文字幕 亚洲精品 第1页 | 无码任你躁久久久久久久 | 精品少妇爆乳无码av无码专区 | 国产特级毛片aaaaaaa高清 | 久久久国产精品无码免费专区 | 色婷婷综合中文久久一本 | 粉嫩少妇内射浓精videos | 天天躁夜夜躁狠狠是什么心态 | 伊人久久大香线焦av综合影院 | 中文字幕无码av波多野吉衣 | 成人女人看片免费视频放人 | 精品欧美一区二区三区久久久 | 国产亚洲欧美在线专区 | 国产一区二区不卡老阿姨 | 欧美性猛交内射兽交老熟妇 | 成人毛片一区二区 | 一本精品99久久精品77 | 日本爽爽爽爽爽爽在线观看免 | 黄网在线观看免费网站 | 色综合久久中文娱乐网 | 狠狠色噜噜狠狠狠狠7777米奇 | 久久久久亚洲精品男人的天堂 | 一二三四社区在线中文视频 | 精品午夜福利在线观看 | 日本精品人妻无码77777 天堂一区人妻无码 | 88国产精品欧美一区二区三区 | 在线播放无码字幕亚洲 | 无码成人精品区在线观看 | 国产又爽又猛又粗的视频a片 | 中文字幕乱码中文乱码51精品 | 亚洲成a人一区二区三区 | 国产av一区二区精品久久凹凸 | 51国偷自产一区二区三区 | 色婷婷综合激情综在线播放 | 丰满人妻精品国产99aⅴ | 午夜福利一区二区三区在线观看 | 国产无遮挡又黄又爽又色 | 亚洲欧美国产精品久久 | 精品无人国产偷自产在线 | 国产农村妇女aaaaa视频 撕开奶罩揉吮奶头视频 | 97夜夜澡人人爽人人喊中国片 | 国精产品一品二品国精品69xx | 国产亚洲精品久久久久久国模美 | 少妇无码av无码专区在线观看 | 性色欲网站人妻丰满中文久久不卡 | 亚洲精品一区二区三区大桥未久 | 麻豆蜜桃av蜜臀av色欲av | 色情久久久av熟女人妻网站 | 亚洲aⅴ无码成人网站国产app | 1000部啪啪未满十八勿入下载 | 无码人妻出轨黑人中文字幕 | 国产精品久久久久久久9999 | 国内精品一区二区三区不卡 | 呦交小u女精品视频 | 亚洲aⅴ无码成人网站国产app | 久久99久久99精品中文字幕 | 日韩 欧美 动漫 国产 制服 | 在线播放亚洲第一字幕 | 搡女人真爽免费视频大全 | 国产香蕉尹人综合在线观看 | 亚洲欧美国产精品专区久久 | 亚洲人成影院在线无码按摩店 | 天堂а√在线地址中文在线 | 免费观看又污又黄的网站 | 少妇性l交大片欧洲热妇乱xxx | 国产农村妇女aaaaa视频 撕开奶罩揉吮奶头视频 | 日日鲁鲁鲁夜夜爽爽狠狠 | 久久精品99久久香蕉国产色戒 | 中文无码伦av中文字幕 | 色一情一乱一伦一区二区三欧美 | 俺去俺来也在线www色官网 | 少妇被粗大的猛进出69影院 | 在线看片无码永久免费视频 | 亚洲 欧美 激情 小说 另类 | 亚洲熟妇色xxxxx欧美老妇y | 欧美日本精品一区二区三区 | 国产热a欧美热a在线视频 | 欧美精品在线观看 | 鲁鲁鲁爽爽爽在线视频观看 | 天堂无码人妻精品一区二区三区 | 成人av无码一区二区三区 | 97资源共享在线视频 | 久激情内射婷内射蜜桃人妖 | 天堂亚洲免费视频 | 日韩亚洲欧美中文高清在线 | 99久久久国产精品无码免费 | 国产精品va在线播放 | 免费无码肉片在线观看 | 377p欧洲日本亚洲大胆 | 精品欧美一区二区三区久久久 | 欧美性猛交xxxx富婆 | 精品亚洲韩国一区二区三区 | 亚洲一区二区三区含羞草 | 性生交片免费无码看人 | 又粗又大又硬又长又爽 | www国产精品内射老师 | 欧美日韩亚洲国产精品 | 精品人妻中文字幕有码在线 | 日本一卡2卡3卡四卡精品网站 | 狠狠躁日日躁夜夜躁2020 | 性欧美熟妇videofreesex | 大胆欧美熟妇xx | 中文字幕人妻丝袜二区 | 午夜免费福利小电影 | 欧美成人家庭影院 | 国产精品第一区揄拍无码 | 国产性生大片免费观看性 | 麻豆md0077饥渴少妇 | 99精品无人区乱码1区2区3区 | 国产suv精品一区二区五 | 日韩av无码一区二区三区不卡 | 内射老妇bbwx0c0ck | 伊人久久婷婷五月综合97色 | 小泽玛莉亚一区二区视频在线 | 久久人人97超碰a片精品 | 青青久在线视频免费观看 | 一区二区三区乱码在线 | 欧洲 | 欧美日韩综合一区二区三区 | 18禁止看的免费污网站 | 欧美怡红院免费全部视频 | 成在人线av无码免观看麻豆 | 国产高清不卡无码视频 | 在线成人www免费观看视频 | 亚洲第一网站男人都懂 | 少女韩国电视剧在线观看完整 | 天堂在线观看www | 精品国产成人一区二区三区 | 亚洲国产成人av在线观看 | 人人妻人人藻人人爽欧美一区 | 日日躁夜夜躁狠狠躁 | 麻豆国产丝袜白领秘书在线观看 | 精品成人av一区二区三区 | 国产精品毛片一区二区 | 一个人免费观看的www视频 | 激情综合激情五月俺也去 | 精品欧洲av无码一区二区三区 | 中文字幕久久久久人妻 | 男人扒开女人内裤强吻桶进去 | 成 人 网 站国产免费观看 | 99精品无人区乱码1区2区3区 | √天堂中文官网8在线 | 美女张开腿让人桶 | 色爱情人网站 | 夜精品a片一区二区三区无码白浆 | 无码精品国产va在线观看dvd | 性生交片免费无码看人 | 国产成人无码av在线影院 | 精品日本一区二区三区在线观看 | 日本丰满熟妇videos | 久久综合给久久狠狠97色 | 精品午夜福利在线观看 | 欧美猛少妇色xxxxx | 国产黄在线观看免费观看不卡 | 日日噜噜噜噜夜夜爽亚洲精品 | 国内精品人妻无码久久久影院蜜桃 | 波多野结衣高清一区二区三区 | 国产精品丝袜黑色高跟鞋 | 亚洲日本va中文字幕 | 中文字幕无码av激情不卡 | 久久婷婷五月综合色国产香蕉 | 日本欧美一区二区三区乱码 | 东京热一精品无码av | 国产九九九九九九九a片 | 激情爆乳一区二区三区 | 久久久久人妻一区精品色欧美 | 日韩 欧美 动漫 国产 制服 | 国产精品久久久午夜夜伦鲁鲁 | 午夜无码人妻av大片色欲 | 噜噜噜亚洲色成人网站 | 日本一本二本三区免费 | 国产精品毛多多水多 | 欧美高清在线精品一区 | 国产精品久久精品三级 | 色噜噜亚洲男人的天堂 | 麻豆国产97在线 | 欧洲 | 午夜精品久久久久久久久 | 欧美老熟妇乱xxxxx | 西西人体www44rt大胆高清 | 亚洲成a人一区二区三区 | 亚洲国产精品毛片av不卡在线 | 亚洲精品国产第一综合99久久 | 亚洲码国产精品高潮在线 | 图片小说视频一区二区 | 国产无套粉嫩白浆在线 | 亚洲区小说区激情区图片区 | 国产精品va在线观看无码 | 熟妇激情内射com | 欧美日韩一区二区免费视频 | 国产九九九九九九九a片 | 欧美自拍另类欧美综合图片区 | 久久久久久国产精品无码下载 | 天天拍夜夜添久久精品大 | 日本成熟视频免费视频 | 亚洲乱亚洲乱妇50p | 国产成人一区二区三区在线观看 | 狠狠综合久久久久综合网 | 国产在线精品一区二区三区直播 | 中文字幕av无码一区二区三区电影 | 国产热a欧美热a在线视频 | 日本高清一区免费中文视频 | 好男人www社区 | 亚洲欧洲中文日韩av乱码 | 中文字幕无码av波多野吉衣 | 伊人色综合久久天天小片 | 国产三级久久久精品麻豆三级 | 久久亚洲中文字幕无码 | 综合人妻久久一区二区精品 | 国产在热线精品视频 | 精品国产青草久久久久福利 | 日韩亚洲欧美精品综合 | 蜜臀av在线观看 在线欧美精品一区二区三区 | 男人扒开女人内裤强吻桶进去 | 国产国语老龄妇女a片 | 狠狠色色综合网站 | 一本精品99久久精品77 | 国产va免费精品观看 | 国产97色在线 | 免 | 亚洲精品综合一区二区三区在线 | 亚洲精品久久久久中文第一幕 | 亚洲中文字幕在线观看 | 99精品国产综合久久久久五月天 | 欧洲极品少妇 | 亚洲爆乳精品无码一区二区三区 | 国产绳艺sm调教室论坛 | 无码国产色欲xxxxx视频 | 久久国产精品二国产精品 | 丰满少妇弄高潮了www | 亚洲精品一区二区三区在线观看 | 国产九九九九九九九a片 | 蜜桃臀无码内射一区二区三区 | 亚洲中文字幕久久无码 | 亚洲成a人一区二区三区 | 久久国产精品萌白酱免费 | 国产av人人夜夜澡人人爽麻豆 | 俺去俺来也在线www色官网 | 免费国产成人高清在线观看网站 | 精品人妻中文字幕有码在线 | 樱花草在线播放免费中文 | 成人动漫在线观看 | 精品无码av一区二区三区 | 99久久精品日本一区二区免费 | 成人免费视频一区二区 | 亚洲国产精品一区二区第一页 | 国产无遮挡又黄又爽又色 | yw尤物av无码国产在线观看 | 亚洲综合久久一区二区 | 国内精品九九久久久精品 | 国产三级精品三级男人的天堂 | 欧美精品一区二区精品久久 | 亚洲精品鲁一鲁一区二区三区 | 巨爆乳无码视频在线观看 | 国产精品亚洲一区二区三区喷水 | 一本无码人妻在中文字幕免费 | 在线观看国产午夜福利片 | 亚拍精品一区二区三区探花 | 色综合视频一区二区三区 | 鲁一鲁av2019在线 | 少妇被黑人到高潮喷出白浆 | 无码播放一区二区三区 | 国产乱人伦偷精品视频 | 99久久精品日本一区二区免费 | 捆绑白丝粉色jk震动捧喷白浆 | 日本欧美一区二区三区乱码 | 亚洲日韩精品欧美一区二区 | 中文无码伦av中文字幕 | 久久99精品国产.久久久久 | 久久综合九色综合欧美狠狠 | 网友自拍区视频精品 | 无码帝国www无码专区色综合 | 狠狠噜狠狠狠狠丁香五月 | 国产亚洲精品久久久闺蜜 | 亚洲爆乳精品无码一区二区三区 | 国产黑色丝袜在线播放 | 亚洲国产精品久久久久久 | 久久久久久九九精品久 | 亚洲人成网站免费播放 | 国产激情无码一区二区 | 丰满人妻翻云覆雨呻吟视频 | 国产亚洲视频中文字幕97精品 | 国产性猛交╳xxx乱大交 国产精品久久久久久无码 欧洲欧美人成视频在线 | 色综合久久久久综合一本到桃花网 | 国产免费观看黄av片 | 亚洲人亚洲人成电影网站色 | 亚洲欧美国产精品专区久久 | 日本一区二区更新不卡 | 日日夜夜撸啊撸 | 最近免费中文字幕中文高清百度 | 亚洲色大成网站www国产 | 国产亲子乱弄免费视频 | 又粗又大又硬又长又爽 | 欧美老人巨大xxxx做受 | 曰本女人与公拘交酡免费视频 | 国产精品第一区揄拍无码 | 国产成人无码区免费内射一片色欲 | 亚洲午夜无码久久 | 久激情内射婷内射蜜桃人妖 | 国产 浪潮av性色四虎 | 在线播放免费人成毛片乱码 | 色妞www精品免费视频 | 国产精品怡红院永久免费 | 亚洲爆乳精品无码一区二区三区 | 高清不卡一区二区三区 | 欧美亚洲日韩国产人成在线播放 | 亚洲七七久久桃花影院 | 任你躁国产自任一区二区三区 | а√天堂www在线天堂小说 | 无码人妻精品一区二区三区不卡 | 日产精品高潮呻吟av久久 | 高清不卡一区二区三区 | 女高中生第一次破苞av | 国产乱子伦视频在线播放 | 综合人妻久久一区二区精品 | 青青久在线视频免费观看 | 风流少妇按摩来高潮 | 日本丰满护士爆乳xxxx | 亚洲成av人片在线观看无码不卡 | 樱花草在线社区www | 男人的天堂2018无码 | 亚洲精品国产精品乱码不卡 | 丁香啪啪综合成人亚洲 | 老太婆性杂交欧美肥老太 | a在线观看免费网站大全 | 强开小婷嫩苞又嫩又紧视频 | 丁香花在线影院观看在线播放 | 亚洲精品国偷拍自产在线观看蜜桃 | 国产精品对白交换视频 | 荫蒂被男人添的好舒服爽免费视频 | 国产真实乱对白精彩久久 | 红桃av一区二区三区在线无码av | 丝袜 中出 制服 人妻 美腿 | 久久久久免费看成人影片 | 国产精品久久久久久亚洲影视内衣 | 亚洲春色在线视频 | 欧美xxxxx精品 | 人人妻人人澡人人爽精品欧美 | 亚洲国产av精品一区二区蜜芽 | 久久天天躁狠狠躁夜夜免费观看 | 99麻豆久久久国产精品免费 | 噜噜噜亚洲色成人网站 | 国产高清av在线播放 | 亚洲欧洲无卡二区视頻 | 久久精品国产99久久6动漫 | 国产一区二区三区精品视频 | 国模大胆一区二区三区 | 国产免费无码一区二区视频 | 亚洲日韩精品欧美一区二区 | 国产麻豆精品一区二区三区v视界 | 午夜肉伦伦影院 | 亚洲成熟女人毛毛耸耸多 | 一二三四在线观看免费视频 | 国产手机在线αⅴ片无码观看 | 麻豆精品国产精华精华液好用吗 | 亚洲精品www久久久 | 成人精品视频一区二区三区尤物 | 国产亚洲精品久久久久久久久动漫 | 曰本女人与公拘交酡免费视频 | 乌克兰少妇性做爰 | 无码国模国产在线观看 | 国产午夜无码视频在线观看 | 帮老师解开蕾丝奶罩吸乳网站 | 最近的中文字幕在线看视频 | 久久久中文字幕日本无吗 | 亚洲熟悉妇女xxx妇女av | 天堂亚洲免费视频 | 成人综合网亚洲伊人 | 男人的天堂2018无码 | 九月婷婷人人澡人人添人人爽 | 四虎国产精品免费久久 | 亚洲日本va午夜在线电影 | 精品久久久中文字幕人妻 | 亚洲综合伊人久久大杳蕉 | 国产亚洲视频中文字幕97精品 | 国产在热线精品视频 | 欧美 日韩 人妻 高清 中文 | 亚洲成熟女人毛毛耸耸多 | 国产97人人超碰caoprom | 亚洲国产高清在线观看视频 | 红桃av一区二区三区在线无码av | 久久www免费人成人片 | 精品人妻人人做人人爽 | 暴力强奷在线播放无码 | 久久精品国产99久久6动漫 | 亚洲成熟女人毛毛耸耸多 | 久激情内射婷内射蜜桃人妖 | 日日天干夜夜狠狠爱 | 人妻aⅴ无码一区二区三区 | 国产精品久久久久久久影院 | 捆绑白丝粉色jk震动捧喷白浆 | 黑人大群体交免费视频 | 亚洲春色在线视频 | 天堂一区人妻无码 | 国产精品沙发午睡系列 | 麻花豆传媒剧国产免费mv在线 | 国产成人精品久久亚洲高清不卡 | 女人高潮内射99精品 | 在线亚洲高清揄拍自拍一品区 | 2019午夜福利不卡片在线 | 香蕉久久久久久av成人 | 麻豆蜜桃av蜜臀av色欲av | 午夜福利一区二区三区在线观看 | 欧美野外疯狂做受xxxx高潮 | 国产亲子乱弄免费视频 | 中文字幕乱码人妻二区三区 | 久久久久久av无码免费看大片 | 久久精品成人欧美大片 | 国产另类ts人妖一区二区 | 中文无码精品a∨在线观看不卡 | 无码国产乱人伦偷精品视频 | 亚洲第一网站男人都懂 | 午夜精品久久久久久久久 | 国产精品人人爽人人做我的可爱 | 国产精品久久久av久久久 | 大肉大捧一进一出好爽视频 | 东京热男人av天堂 | 小泽玛莉亚一区二区视频在线 | 人妻与老人中文字幕 | 男人的天堂av网站 | 午夜免费福利小电影 | 丁香啪啪综合成人亚洲 | 国产香蕉尹人综合在线观看 | 亚洲春色在线视频 | 国产精品二区一区二区aⅴ污介绍 | 欧美日韩色另类综合 | 国产精品va在线播放 | 丰腴饱满的极品熟妇 | 1000部啪啪未满十八勿入下载 | 国产九九九九九九九a片 | 日本精品久久久久中文字幕 | 人妻无码久久精品人妻 | 色老头在线一区二区三区 | 午夜性刺激在线视频免费 | 免费观看的无遮挡av | 亚洲精品一区二区三区在线观看 | 欧美成人高清在线播放 | 鲁大师影院在线观看 | 国产乱人无码伦av在线a | 精品无码国产一区二区三区av | 日欧一片内射va在线影院 | 久久99精品国产麻豆 | 欧美自拍另类欧美综合图片区 | 强伦人妻一区二区三区视频18 | 亚洲爆乳精品无码一区二区三区 | 日本精品久久久久中文字幕 | 娇妻被黑人粗大高潮白浆 | 久久久精品成人免费观看 | 欧美日本精品一区二区三区 | 亚洲精品成a人在线观看 | 欧美肥老太牲交大战 | 性欧美大战久久久久久久 | 中文字幕无码日韩欧毛 | 久久亚洲精品中文字幕无男同 | 狠狠色色综合网站 | 国产精品久久久久7777 | 色欲av亚洲一区无码少妇 | 国产激情艳情在线看视频 | 4hu四虎永久在线观看 | 日日天干夜夜狠狠爱 | 精品一区二区三区波多野结衣 | 55夜色66夜色国产精品视频 | 日韩少妇白浆无码系列 | 久久久www成人免费毛片 | 亚洲精品综合五月久久小说 | 色欲av亚洲一区无码少妇 | 99久久人妻精品免费一区 | 又粗又大又硬毛片免费看 | 国产97色在线 | 免 | 激情综合激情五月俺也去 | 国产精品久久久久无码av色戒 | 免费无码一区二区三区蜜桃大 | 久久这里只有精品视频9 | 欧美人与禽猛交狂配 | 扒开双腿疯狂进出爽爽爽视频 | 久久久精品成人免费观看 | 亚洲中文字幕无码中文字在线 | 精品国偷自产在线视频 | 国产午夜福利亚洲第一 | 亚洲综合在线一区二区三区 | 天天做天天爱天天爽综合网 | 自拍偷自拍亚洲精品被多人伦好爽 | 亚洲男人av香蕉爽爽爽爽 | 午夜理论片yy44880影院 | 免费无码午夜福利片69 | 女人被男人躁得好爽免费视频 | 国产精品美女久久久网av | 国产又爽又猛又粗的视频a片 | 欧美日韩在线亚洲综合国产人 | 一本大道久久东京热无码av | 国内少妇偷人精品视频 | 亚洲国产精品无码一区二区三区 | 草草网站影院白丝内射 | 激情综合激情五月俺也去 | 麻豆国产人妻欲求不满谁演的 | 人妻少妇被猛烈进入中文字幕 | 激情国产av做激情国产爱 | 亚洲国产精品美女久久久久 | 亚洲熟熟妇xxxx | 熟女少妇在线视频播放 | 任你躁国产自任一区二区三区 | 欧美日韩一区二区免费视频 | 又色又爽又黄的美女裸体网站 | 97久久国产亚洲精品超碰热 | 国产精品久久久av久久久 | 亚洲色偷偷男人的天堂 | 亚洲精品国产第一综合99久久 | 久久人人爽人人爽人人片av高清 | 国产高潮视频在线观看 | 欧美xxxx黑人又粗又长 | 扒开双腿吃奶呻吟做受视频 | 麻豆av传媒蜜桃天美传媒 | 久久人人爽人人爽人人片av高清 | 自拍偷自拍亚洲精品被多人伦好爽 | 亚洲伊人久久精品影院 | 黄网在线观看免费网站 | 国产成人一区二区三区别 | 狠狠亚洲超碰狼人久久 | 国产成人精品必看 | 午夜无码区在线观看 | 天堂а√在线地址中文在线 | 日产精品高潮呻吟av久久 | 麻豆md0077饥渴少妇 | 蜜桃av抽搐高潮一区二区 | 国产精品久久久久9999小说 | 国产色精品久久人妻 | 日日摸天天摸爽爽狠狠97 | 国产区女主播在线观看 | 亚洲中文字幕久久无码 | 色噜噜亚洲男人的天堂 | 久久久久久亚洲精品a片成人 | 少妇的肉体aa片免费 | 中文精品久久久久人妻不卡 | 人人妻人人澡人人爽欧美一区九九 | 久久亚洲日韩精品一区二区三区 | 久久国产精品二国产精品 | 99精品视频在线观看免费 | 一本色道久久综合狠狠躁 | 亚洲精品国产品国语在线观看 | 日本护士毛茸茸高潮 | 色 综合 欧美 亚洲 国产 | 色一情一乱一伦一区二区三欧美 | 欧美日韩一区二区免费视频 | 无遮挡国产高潮视频免费观看 | 澳门永久av免费网站 | 国产精品久久久久无码av色戒 | 少妇厨房愉情理9仑片视频 | 国产成人久久精品流白浆 | 亚洲国产av美女网站 | 国产sm调教视频在线观看 | 亚洲日本va中文字幕 | 亚洲中文无码av永久不收费 | 久久午夜夜伦鲁鲁片无码免费 | 久久久久免费精品国产 | 日韩视频 中文字幕 视频一区 | 亚洲大尺度无码无码专区 | 一本久久伊人热热精品中文字幕 | 久久精品成人欧美大片 | 清纯唯美经典一区二区 | 无码午夜成人1000部免费视频 | 日韩精品无码免费一区二区三区 | 日韩人妻无码中文字幕视频 | 日本一区二区更新不卡 | 日日天干夜夜狠狠爱 | 久久久无码中文字幕久... | 日本精品久久久久中文字幕 | 天堂久久天堂av色综合 | 亚洲欧洲无卡二区视頻 | 欧美大屁股xxxxhd黑色 | 久久久婷婷五月亚洲97号色 | 99精品无人区乱码1区2区3区 | 国产精品18久久久久久麻辣 | 国产精品久久久久无码av色戒 | 亚洲一区二区三区含羞草 | 久久99精品久久久久久 | 午夜嘿嘿嘿影院 | 国产精品igao视频网 | 亚洲色欲色欲天天天www | 性啪啪chinese东北女人 | 在线a亚洲视频播放在线观看 | 亚洲啪av永久无码精品放毛片 | 免费无码午夜福利片69 | 国产精品免费大片 | 久久视频在线观看精品 | 久久精品女人的天堂av | 日韩 欧美 动漫 国产 制服 | 欧洲vodafone精品性 | 国内丰满熟女出轨videos | 日欧一片内射va在线影院 | 亚洲日本va中文字幕 | 亚洲中文字幕无码中文字在线 | 日本一区二区更新不卡 | 中文字幕乱妇无码av在线 | 好爽又高潮了毛片免费下载 | 成熟女人特级毛片www免费 | 波多野结衣高清一区二区三区 | a片免费视频在线观看 | 亚洲色欲久久久综合网东京热 | 亚洲中文无码av永久不收费 | 清纯唯美经典一区二区 | 日本一区二区更新不卡 | 中文字幕av无码一区二区三区电影 | 欧美 日韩 人妻 高清 中文 | 人妻与老人中文字幕 | 成人一区二区免费视频 | 国产无套粉嫩白浆在线 | 一区二区三区乱码在线 | 欧洲 | 好男人社区资源 | 亚洲一区二区三区香蕉 | 人妻与老人中文字幕 | 久久亚洲国产成人精品性色 | 国产精品-区区久久久狼 | 欧美野外疯狂做受xxxx高潮 | 久久精品国产99久久6动漫 | 亚无码乱人伦一区二区 | 日韩无码专区 | 宝宝好涨水快流出来免费视频 | 在线精品亚洲一区二区 | 夫妻免费无码v看片 | 丰满妇女强制高潮18xxxx | 少妇人妻大乳在线视频 | 久青草影院在线观看国产 | 亚洲人成人无码网www国产 | 日本一区二区三区免费播放 | 久久久久久久久888 | 少妇被黑人到高潮喷出白浆 | 强伦人妻一区二区三区视频18 | 少妇性荡欲午夜性开放视频剧场 | 欧美日韩综合一区二区三区 | 最近中文2019字幕第二页 | 美女毛片一区二区三区四区 | 高潮毛片无遮挡高清免费 | 无码吃奶揉捏奶头高潮视频 | 久久综合给合久久狠狠狠97色 | a片在线免费观看 | 99精品久久毛片a片 | 久久久久久a亚洲欧洲av冫 | 国产av久久久久精东av | 久久 国产 尿 小便 嘘嘘 | 久久人人爽人人爽人人片av高清 | 久久熟妇人妻午夜寂寞影院 | 欧美 日韩 亚洲 在线 | 婷婷丁香六月激情综合啪 | 精品日本一区二区三区在线观看 | 又粗又大又硬又长又爽 | 99久久久无码国产精品免费 | 丝袜人妻一区二区三区 | 欧美自拍另类欧美综合图片区 | 青青青手机频在线观看 | 久久亚洲日韩精品一区二区三区 | 国产乡下妇女做爰 | 东京无码熟妇人妻av在线网址 | 漂亮人妻洗澡被公强 日日躁 | 亚洲精品国产第一综合99久久 | 日韩人妻无码中文字幕视频 | 欧美黑人性暴力猛交喷水 | 性做久久久久久久久 | 图片区 小说区 区 亚洲五月 | 精品国产一区二区三区av 性色 | 丰腴饱满的极品熟妇 | 色综合久久久无码中文字幕 | 精品国产aⅴ无码一区二区 | 国产精品99爱免费视频 | 最新版天堂资源中文官网 | 成人亚洲精品久久久久软件 | 桃花色综合影院 | 强开小婷嫩苞又嫩又紧视频 | 欧美日本免费一区二区三区 | 东京无码熟妇人妻av在线网址 | 日本免费一区二区三区最新 | 97资源共享在线视频 | 77777熟女视频在线观看 а天堂中文在线官网 | 国产极品美女高潮无套在线观看 | 亚洲中文字幕无码中文字在线 | 国产农村妇女高潮大叫 | 亚洲欧美日韩成人高清在线一区 | 亚洲 日韩 欧美 成人 在线观看 | 夜夜影院未满十八勿进 | 乱人伦中文视频在线观看 | 国内精品久久久久久中文字幕 | 亚洲热妇无码av在线播放 | 亚洲一区二区三区偷拍女厕 | 国产午夜精品一区二区三区嫩草 | 夜夜影院未满十八勿进 | 国产亚洲精品久久久闺蜜 | 给我免费的视频在线观看 | 蜜桃av蜜臀av色欲av麻 999久久久国产精品消防器材 | 曰韩无码二三区中文字幕 | 国产手机在线αⅴ片无码观看 | 麻豆国产丝袜白领秘书在线观看 | 成人无码视频免费播放 | 一个人看的www免费视频在线观看 | 欧洲美熟女乱又伦 | 爱做久久久久久 | 性啪啪chinese东北女人 | 青青久在线视频免费观看 | 欧美人与善在线com | 成人动漫在线观看 | 欧美大屁股xxxxhd黑色 | 强辱丰满人妻hd中文字幕 | 久热国产vs视频在线观看 | 99国产欧美久久久精品 | 欧美xxxx黑人又粗又长 | 夜夜夜高潮夜夜爽夜夜爰爰 | 国产精品亚洲综合色区韩国 | 久久久无码中文字幕久... | 国产精品久久久久久久影院 | 东京一本一道一二三区 | av无码不卡在线观看免费 | 国产三级精品三级男人的天堂 | 久在线观看福利视频 | 国产艳妇av在线观看果冻传媒 | 精品无人区无码乱码毛片国产 | 久久国语露脸国产精品电影 | 无遮挡国产高潮视频免费观看 | 伊人色综合久久天天小片 | 在线视频网站www色 | 国产精品亚洲五月天高清 | 国产成人无码av一区二区 | 中文字幕无码乱人伦 | 亚洲乱码日产精品bd | 欧美日韩亚洲国产精品 | 国产精品美女久久久 | 色欲久久久天天天综合网精品 | 中文字幕无码乱人伦 | 国产97人人超碰caoprom | 亚洲国产欧美在线成人 | 自拍偷自拍亚洲精品10p | 久久人人爽人人爽人人片av高清 | 给我免费的视频在线观看 | 麻豆国产丝袜白领秘书在线观看 | 呦交小u女精品视频 | 国产人妻精品一区二区三区 | 国产疯狂伦交大片 | 国产精品无码久久av | av在线亚洲欧洲日产一区二区 | av香港经典三级级 在线 | 人妻少妇精品无码专区动漫 | 无套内谢老熟女 | 精品一区二区三区波多野结衣 | 日本熟妇乱子伦xxxx | 亚洲精品午夜国产va久久成人 | 亚洲高清偷拍一区二区三区 | 国产特级毛片aaaaaa高潮流水 | 丰腴饱满的极品熟妇 | 日日摸夜夜摸狠狠摸婷婷 | 性生交大片免费看女人按摩摩 | 欧美人妻一区二区三区 | 国产精品久久久久久久影院 | 成人亚洲精品久久久久软件 | 国产熟妇高潮叫床视频播放 | 久激情内射婷内射蜜桃人妖 | 中文字幕无码免费久久9一区9 | 蜜桃av蜜臀av色欲av麻 999久久久国产精品消防器材 | 国产av人人夜夜澡人人爽麻豆 | 亚洲色大成网站www | 日产国产精品亚洲系列 | www一区二区www免费 | 中文字幕av无码一区二区三区电影 | 18黄暴禁片在线观看 | 成人无码精品一区二区三区 | 国产精品无码永久免费888 | 真人与拘做受免费视频一 | 亚洲精品一区二区三区四区五区 | 久久综合激激的五月天 | 一本无码人妻在中文字幕免费 | а√天堂www在线天堂小说 | 国产sm调教视频在线观看 | 日本护士毛茸茸高潮 | 88国产精品欧美一区二区三区 | 国产精品人人爽人人做我的可爱 | 好男人www社区 | 天堂无码人妻精品一区二区三区 | 一本久道久久综合狠狠爱 | 久久亚洲a片com人成 | 亚洲色www成人永久网址 | 国产无遮挡又黄又爽又色 | 国产精品亚洲а∨无码播放麻豆 | 精品无码一区二区三区爱欲 | 久久国产精品_国产精品 | 国产免费观看黄av片 | 无套内谢的新婚少妇国语播放 | 日本又色又爽又黄的a片18禁 | 久久 国产 尿 小便 嘘嘘 | 无码人妻丰满熟妇区毛片18 | 欧美第一黄网免费网站 | 在线а√天堂中文官网 | 欧美大屁股xxxxhd黑色 | 999久久久国产精品消防器材 | 精品人人妻人人澡人人爽人人 | 狠狠躁日日躁夜夜躁2020 | 成 人 网 站国产免费观看 | 欧洲熟妇色 欧美 | 99久久精品无码一区二区毛片 | 99久久人妻精品免费二区 | аⅴ资源天堂资源库在线 | 亚洲精品中文字幕乱码 | 国产偷国产偷精品高清尤物 | 亚洲一区二区观看播放 | 无码精品国产va在线观看dvd | 综合人妻久久一区二区精品 | 最近中文2019字幕第二页 | 中文字幕色婷婷在线视频 | 久久久中文字幕日本无吗 | 国产人妻精品一区二区三区不卡 | 亚洲男女内射在线播放 | 麻豆成人精品国产免费 | 女人高潮内射99精品 | 国产舌乚八伦偷品w中 | 日韩精品无码一区二区中文字幕 | √8天堂资源地址中文在线 | 中文字幕乱码人妻二区三区 | 成熟女人特级毛片www免费 | 国产亚洲人成a在线v网站 | 国产人妖乱国产精品人妖 | 任你躁在线精品免费 | 免费人成在线视频无码 | 小泽玛莉亚一区二区视频在线 | 日韩欧美成人免费观看 | 国产精品-区区久久久狼 | 国语自产偷拍精品视频偷 | 男人的天堂2018无码 | 日韩欧美中文字幕公布 | 大胆欧美熟妇xx | 无码午夜成人1000部免费视频 | 国产舌乚八伦偷品w中 | 婷婷六月久久综合丁香 | 色婷婷综合激情综在线播放 | 对白脏话肉麻粗话av | 欧美亚洲日韩国产人成在线播放 | 欧美日本精品一区二区三区 | 午夜理论片yy44880影院 | 国产女主播喷水视频在线观看 | 亚洲欧美精品伊人久久 | 亲嘴扒胸摸屁股激烈网站 | 在线观看免费人成视频 | 成人欧美一区二区三区黑人 | 国产日产欧产精品精品app | 人人妻人人澡人人爽欧美一区 | 免费无码肉片在线观看 | 国产无遮挡又黄又爽免费视频 | 999久久久国产精品消防器材 | 国产精品无码mv在线观看 | 狂野欧美激情性xxxx | 97资源共享在线视频 | 国产又爽又猛又粗的视频a片 | 免费看少妇作爱视频 | 国产人妻精品一区二区三区 | 国产sm调教视频在线观看 | 久久综合九色综合欧美狠狠 | 国内精品九九久久久精品 | 男女超爽视频免费播放 | 131美女爱做视频 | 国产午夜无码视频在线观看 | 综合激情五月综合激情五月激情1 | 国产尤物精品视频 | 国产 浪潮av性色四虎 | 55夜色66夜色国产精品视频 | 久久综合给合久久狠狠狠97色 | 东京热一精品无码av | 亚洲 欧美 激情 小说 另类 | 国产精品亚洲一区二区三区喷水 | 日本欧美一区二区三区乱码 | 极品嫩模高潮叫床 | 午夜性刺激在线视频免费 | 日韩欧美群交p片內射中文 | 国内精品一区二区三区不卡 | 亚洲区小说区激情区图片区 | 精品久久久中文字幕人妻 | 国产国产精品人在线视 | 国产精品18久久久久久麻辣 | 成年美女黄网站色大免费视频 | 人妻少妇精品无码专区二区 | 国产又爽又黄又刺激的视频 | 一个人看的视频www在线 | 成人免费视频视频在线观看 免费 | 国产乱人无码伦av在线a | 无码吃奶揉捏奶头高潮视频 | 成 人影片 免费观看 | 欧美人与禽zoz0性伦交 | 97se亚洲精品一区 | 人妻尝试又大又粗久久 | 亚洲大尺度无码无码专区 | 亚洲综合色区中文字幕 | 亚洲精品综合五月久久小说 | 欧美精品无码一区二区三区 | 国产成人无码区免费内射一片色欲 | 亚洲国产高清在线观看视频 | 国产片av国语在线观看 | 欧洲熟妇精品视频 | 久久久久99精品国产片 | 无码午夜成人1000部免费视频 | 欧美国产日产一区二区 | 欧美精品在线观看 | 久久天天躁狠狠躁夜夜免费观看 | 性欧美牲交在线视频 | 大地资源网第二页免费观看 | 久久国产精品精品国产色婷婷 | 88国产精品欧美一区二区三区 | 亚洲娇小与黑人巨大交 | 日本精品高清一区二区 | 亚洲自偷自偷在线制服 | 天天av天天av天天透 | 嫩b人妻精品一区二区三区 | 国产精品国产三级国产专播 | 内射欧美老妇wbb | 国产成人精品必看 | 99精品无人区乱码1区2区3区 | 无遮挡啪啪摇乳动态图 | 成人亚洲精品久久久久软件 | 欧美老人巨大xxxx做受 | 久久精品国产一区二区三区 | 99久久久国产精品无码免费 | 天天躁夜夜躁狠狠是什么心态 | 高中生自慰www网站 | 四虎国产精品免费久久 | 久久久久亚洲精品中文字幕 | 欧美老妇交乱视频在线观看 | 久久精品无码一区二区三区 | 久久精品国产99精品亚洲 | 丰满人妻一区二区三区免费视频 | 日本大香伊一区二区三区 | 欧美色就是色 | 日韩精品无码一区二区中文字幕 | 精品久久久久久人妻无码中文字幕 | 午夜精品久久久久久久久 | 欧美三级不卡在线观看 | 国产精品久久国产三级国 | 国产人妻精品一区二区三区不卡 | 纯爱无遮挡h肉动漫在线播放 | 一个人看的www免费视频在线观看 | 熟妇人妻激情偷爽文 | 99久久精品国产一区二区蜜芽 | 黑人玩弄人妻中文在线 | 精品国产一区av天美传媒 | 久久精品国产一区二区三区肥胖 | 亚洲国产精品美女久久久久 | 亚洲性无码av中文字幕 | 99久久精品午夜一区二区 | av无码久久久久不卡免费网站 | 东京无码熟妇人妻av在线网址 | 九九热爱视频精品 | 麻豆蜜桃av蜜臀av色欲av | 欧美黑人巨大xxxxx | 性欧美牲交xxxxx视频 | 午夜精品一区二区三区在线观看 | 国产女主播喷水视频在线观看 | 夜夜高潮次次欢爽av女 | 日本乱偷人妻中文字幕 | 理论片87福利理论电影 | 特黄特色大片免费播放器图片 | 成人一在线视频日韩国产 | 波多野结衣av一区二区全免费观看 | 曰韩少妇内射免费播放 | 欧美熟妇另类久久久久久多毛 | 国产免费观看黄av片 | aa片在线观看视频在线播放 | 国产真实乱对白精彩久久 | av无码不卡在线观看免费 | 强辱丰满人妻hd中文字幕 | 九月婷婷人人澡人人添人人爽 | 成熟女人特级毛片www免费 | 成人精品天堂一区二区三区 | 国产综合色产在线精品 | 国产肉丝袜在线观看 | 九九在线中文字幕无码 | 国产日产欧产精品精品app | 亚洲精品国产精品乱码不卡 | av无码久久久久不卡免费网站 | 激情五月综合色婷婷一区二区 | 亚洲爆乳精品无码一区二区三区 | 国产精品对白交换视频 | 丰满人妻一区二区三区免费视频 | av小次郎收藏 | 婷婷六月久久综合丁香 | 日韩人妻少妇一区二区三区 | 国产精品久久久久久无码 | 中文无码伦av中文字幕 | 无码av免费一区二区三区试看 | 人妻少妇精品无码专区二区 | 亚洲成a人片在线观看日本 | 狠狠噜狠狠狠狠丁香五月 | 国产精品.xx视频.xxtv | 中文字幕av无码一区二区三区电影 | 国产美女精品一区二区三区 | 在线精品亚洲一区二区 | 日本xxxx色视频在线观看免费 | 成人无码影片精品久久久 | 亚洲熟悉妇女xxx妇女av | аⅴ资源天堂资源库在线 | 无套内谢的新婚少妇国语播放 | 300部国产真实乱 | 欧美老熟妇乱xxxxx | av无码不卡在线观看免费 | 亚洲中文字幕乱码av波多ji | 夜先锋av资源网站 | 欧美怡红院免费全部视频 | 日韩av激情在线观看 | 亚洲日韩av一区二区三区四区 | 无套内射视频囯产 | 波多野结衣高清一区二区三区 | 99精品国产综合久久久久五月天 | 性啪啪chinese东北女人 | 99麻豆久久久国产精品免费 | 又大又硬又爽免费视频 | 无码一区二区三区在线观看 | 日韩精品无码一区二区中文字幕 | 日本一区二区更新不卡 | 国产香蕉尹人综合在线观看 | 久久熟妇人妻午夜寂寞影院 | 麻豆精品国产精华精华液好用吗 | 东京热无码av男人的天堂 | 亚洲国产欧美日韩精品一区二区三区 | 日日碰狠狠丁香久燥 | 国产综合久久久久鬼色 | 全球成人中文在线 | 亚洲色偷偷偷综合网 | 国产精华av午夜在线观看 | 中文字幕无码热在线视频 | 内射白嫩少妇超碰 | 色妞www精品免费视频 | 人妻aⅴ无码一区二区三区 | 国产一区二区三区四区五区加勒比 | 国产sm调教视频在线观看 | 国产97人人超碰caoprom | 亚洲欧美综合区丁香五月小说 | 蜜臀av无码人妻精品 | 国产成人精品无码播放 | 国产在热线精品视频 | 国内少妇偷人精品视频 | 天堂а√在线地址中文在线 | 少妇无码吹潮 | 天干天干啦夜天干天2017 | 久久午夜夜伦鲁鲁片无码免费 | 人妻少妇精品无码专区二区 | 国内揄拍国内精品少妇国语 | 免费乱码人妻系列无码专区 | 51国偷自产一区二区三区 | 婷婷六月久久综合丁香 | 国产真实乱对白精彩久久 | 国产精品a成v人在线播放 | 最近免费中文字幕中文高清百度 | 久久精品国产精品国产精品污 | 国产激情艳情在线看视频 | 青草青草久热国产精品 | 在线播放亚洲第一字幕 | 国产激情一区二区三区 | 亚洲另类伦春色综合小说 | 特黄特色大片免费播放器图片 | 国产精品久久福利网站 | 国产人妻精品一区二区三区 | 亚洲精品美女久久久久久久 | ass日本丰满熟妇pics | 精品成人av一区二区三区 | 99久久精品国产一区二区蜜芽 | 国产精品.xx视频.xxtv | 美女黄网站人色视频免费国产 | 少女韩国电视剧在线观看完整 | 国产激情一区二区三区 | 欧美freesex黑人又粗又大 | 久久无码专区国产精品s | 日本免费一区二区三区最新 | 亚洲精品国产精品乱码不卡 | 国产亚洲精品久久久ai换 | 丰满少妇人妻久久久久久 | 久久亚洲中文字幕无码 | 青青青爽视频在线观看 | 成人试看120秒体验区 | 国产精品久久久久影院嫩草 | 成人无码精品一区二区三区 | 国产黄在线观看免费观看不卡 | 秋霞特色aa大片 | 欧美三级a做爰在线观看 | 蜜臀av在线播放 久久综合激激的五月天 | 午夜成人1000部免费视频 | 国产午夜无码精品免费看 | 亚洲乱码中文字幕在线 | 成熟女人特级毛片www免费 | 精品国偷自产在线视频 | 久在线观看福利视频 | 一区二区三区乱码在线 | 欧洲 | 欧美大屁股xxxxhd黑色 | 国产亚洲精品久久久久久国模美 | 国产舌乚八伦偷品w中 | 成人亚洲精品久久久久 | 小泽玛莉亚一区二区视频在线 | 又粗又大又硬又长又爽 | 麻豆精品国产精华精华液好用吗 | 激情亚洲一区国产精品 | 国产农村乱对白刺激视频 | 国产精品-区区久久久狼 | 正在播放老肥熟妇露脸 | 精品国产国产综合精品 | 少妇性荡欲午夜性开放视频剧场 | 久久午夜夜伦鲁鲁片无码免费 | 国产另类ts人妖一区二区 | 窝窝午夜理论片影院 | 亚洲欧美国产精品专区久久 | 久久无码人妻影院 | 丝袜足控一区二区三区 | 国产免费久久精品国产传媒 | 影音先锋中文字幕无码 | 国产口爆吞精在线视频 | 久久久久久亚洲精品a片成人 | 亚洲国产一区二区三区在线观看 | 国产精品久久久一区二区三区 | 少妇愉情理伦片bd | 人妻插b视频一区二区三区 | 欧美真人作爱免费视频 | 少妇无码吹潮 | av在线亚洲欧洲日产一区二区 | 欧美日韩人成综合在线播放 | 国产做国产爱免费视频 | 大乳丰满人妻中文字幕日本 | 国产一区二区三区四区五区加勒比 | 国产美女极度色诱视频www | 无码免费一区二区三区 | 成人性做爰aaa片免费看不忠 | 九九热爱视频精品 | 动漫av一区二区在线观看 | 中文字幕无码日韩专区 | 日韩精品无码一区二区中文字幕 | 国产无套内射久久久国产 | 午夜男女很黄的视频 | 人人澡人摸人人添 | 中文字幕无线码免费人妻 | 免费无码一区二区三区蜜桃大 | 亚洲人成网站在线播放942 | 久久综合给久久狠狠97色 | 色综合久久88色综合天天 | 精品无码国产一区二区三区av | 中文精品无码中文字幕无码专区 | 国语自产偷拍精品视频偷 | 中国女人内谢69xxxxxa片 | 老熟妇乱子伦牲交视频 | 精品无人国产偷自产在线 | 久久久久成人精品免费播放动漫 | 中文字幕乱码人妻二区三区 | 日韩av无码中文无码电影 | 精品国产一区二区三区四区在线看 | 亚洲精品成人福利网站 | 久久精品成人欧美大片 | 十八禁真人啪啪免费网站 | 亚洲一区二区三区在线观看网站 | 亚洲日本在线电影 | 牲欲强的熟妇农村老妇女 | 国产精品久久国产三级国 | 中文字幕乱码人妻二区三区 | 国产综合在线观看 | 久久国语露脸国产精品电影 | 久久久无码中文字幕久... | 四虎4hu永久免费 | 精品无码av一区二区三区 | 国产网红无码精品视频 | 中文亚洲成a人片在线观看 | 丝袜美腿亚洲一区二区 | 精品久久久久香蕉网 | 日韩成人一区二区三区在线观看 | 国产精品18久久久久久麻辣 | 国产精品igao视频网 | 中文字幕无码免费久久9一区9 | 国产区女主播在线观看 | 无遮挡国产高潮视频免费观看 | 欧美人与动性行为视频 | 玩弄少妇高潮ⅹxxxyw | 亚洲人成人无码网www国产 | 久久www免费人成人片 | 亚洲 激情 小说 另类 欧美 | 日韩精品无码一区二区中文字幕 | 男人的天堂av网站 | 波多野结衣高清一区二区三区 | 久久精品国产亚洲精品 | 久久综合九色综合欧美狠狠 | 欧美一区二区三区 | 双乳奶水饱满少妇呻吟 | 国内精品人妻无码久久久影院 | 国产特级毛片aaaaaa高潮流水 | 无码任你躁久久久久久久 | 日本精品高清一区二区 | 丰满少妇高潮惨叫视频 | 欧美 日韩 人妻 高清 中文 | 亚洲s码欧洲m码国产av | 中国女人内谢69xxxx | 亚洲阿v天堂在线 | 中文字幕av无码一区二区三区电影 | 99久久亚洲精品无码毛片 | 久久国产精品_国产精品 | 亚洲毛片av日韩av无码 | 精品偷拍一区二区三区在线看 | 国产av人人夜夜澡人人爽麻豆 | 在线 国产 欧美 亚洲 天堂 | 精品夜夜澡人妻无码av蜜桃 | 亚洲春色在线视频 | 无码人妻精品一区二区三区不卡 | 国产在线aaa片一区二区99 | 性欧美牲交xxxxx视频 | 国产人妻人伦精品 | 丰满少妇高潮惨叫视频 | 久久久久亚洲精品中文字幕 | 亚洲熟妇色xxxxx亚洲 | 精品亚洲成av人在线观看 | 久青草影院在线观看国产 | 国产后入清纯学生妹 | 免费无码av一区二区 | 国产精品va在线观看无码 | 粉嫩少妇内射浓精videos | 国产无遮挡又黄又爽免费视频 | 中文字幕乱妇无码av在线 | 免费人成网站视频在线观看 | 亚洲啪av永久无码精品放毛片 | 亚洲精品一区二区三区在线 | 国产亚洲精品久久久久久久久动漫 | 亚洲人成影院在线无码按摩店 | 美女扒开屁股让男人桶 | 99久久精品日本一区二区免费 | 久久久久久久人妻无码中文字幕爆 | 亚洲男女内射在线播放 | 国产精品无码永久免费888 | 国产美女极度色诱视频www | 国产亚洲精品久久久久久久久动漫 | 无套内射视频囯产 | 成年女人永久免费看片 | 女人高潮内射99精品 | 亚洲码国产精品高潮在线 | 国产免费观看黄av片 | 国产suv精品一区二区五 | 东北女人啪啪对白 | 最近中文2019字幕第二页 | 亚洲精品一区二区三区在线观看 | 精品无码一区二区三区的天堂 | 日韩少妇白浆无码系列 | 亚洲另类伦春色综合小说 | 国产成人人人97超碰超爽8 | 成人动漫在线观看 | 无码av中文字幕免费放 | 国产精品18久久久久久麻辣 | 小泽玛莉亚一区二区视频在线 | 国产97人人超碰caoprom | 日本一区二区三区免费播放 | 精品国精品国产自在久国产87 | 在线a亚洲视频播放在线观看 | 精品无码一区二区三区爱欲 | 奇米影视888欧美在线观看 | 亚洲精品一区二区三区在线观看 | 性做久久久久久久久 | 18禁止看的免费污网站 | 亚洲娇小与黑人巨大交 | 人人爽人人爽人人片av亚洲 | 老熟妇仑乱视频一区二区 | 88国产精品欧美一区二区三区 | 在线观看免费人成视频 | 久久精品国产一区二区三区肥胖 | 综合激情五月综合激情五月激情1 | 激情内射日本一区二区三区 | 国产黄在线观看免费观看不卡 | 国产精品国产自线拍免费软件 | 红桃av一区二区三区在线无码av | 国产精品igao视频网 | 在线 国产 欧美 亚洲 天堂 | 国产精品对白交换视频 | 无遮挡啪啪摇乳动态图 | 国产va免费精品观看 | 亚洲国产精品无码一区二区三区 | 国产精品久久久久影院嫩草 | 蜜臀av无码人妻精品 | 狠狠色丁香久久婷婷综合五月 | 国产疯狂伦交大片 | 亚洲精品一区二区三区在线观看 | 高清国产亚洲精品自在久久 | 国产人妻精品一区二区三区 | 精品少妇爆乳无码av无码专区 | 波多野结衣一区二区三区av免费 | 玩弄少妇高潮ⅹxxxyw | 亚洲人成网站免费播放 | 久久久www成人免费毛片 | 人妻夜夜爽天天爽三区 | 成人无码精品1区2区3区免费看 | 亚洲男女内射在线播放 | 亚洲男女内射在线播放 | 99久久久无码国产aaa精品 | 免费无码av一区二区 | 亚洲精品一区二区三区在线观看 | 牛和人交xxxx欧美 | 亚洲男人av天堂午夜在 | 人人爽人人澡人人高潮 | 好男人社区资源 | 亚欧洲精品在线视频免费观看 | 久久精品国产精品国产精品污 | www国产亚洲精品久久久日本 | 精品欧洲av无码一区二区三区 | 欧美黑人性暴力猛交喷水 | 中文字幕无线码 | 亚洲国产精品毛片av不卡在线 | 国产精品久久精品三级 | 中文精品无码中文字幕无码专区 | 俄罗斯老熟妇色xxxx | 国产超碰人人爽人人做人人添 | 亚洲熟熟妇xxxx | 亚洲第一网站男人都懂 | 国产精品a成v人在线播放 | 久久久久成人精品免费播放动漫 | 亚洲精品久久久久中文第一幕 | 国产激情无码一区二区app | 中文无码伦av中文字幕 | 成人性做爰aaa片免费看 | 亚洲最大成人网站 | 四虎影视成人永久免费观看视频 | 欧美真人作爱免费视频 | 中文字幕+乱码+中文字幕一区 |