1. 程式人生 > >[設計模式](十三):中介模式|訪問者模式|直譯器模式(三種中間類行為模式)

[設計模式](十三):中介模式|訪問者模式|直譯器模式(三種中間類行為模式)

    >上一篇<中介紹了兩種類狀態行為模式,這次介紹行為模式的最後三種——中間類行為模式:中介模式|訪問者模式|直譯器模式

>什麼是中間模式 ?

    中介模式中,存在一箇中介物件,封裝了一系列物件的互動,使得各個物件間的互動由緊密網路變成鬆散的中心耦合狀態。簡單來說,就是將下圖中系統中的UML圖變為右邊的那樣:


     中介模式的UML圖如下:


     其主要包含兩個要素:

  • Mediator中介類:封裝了同事類間的互動方法;
  • Colleague同事類:同事類間將可能因為自身狀態改變或其他原因發生互動。
     下面舉一個小例子:普通的客戶機與超算中心進行工作協調。
//中介
abstract class Mediator(){
    abstract fun contact(s:String,sender:Computer)
}
class MediatorCenter(c:Computer,center:Computer):Mediator(){
    //封裝物件
    private val client = c
    private val computerCenter = center
    //封裝物件間的互動
    override fun contact(s: String,sender:Computer) {
        when(sender){
            is FamilyComputer -> computerCenter.showMessage(s)
            is Supercomputer -> client.showMessage(s)
        }
    }
}
//同事類
abstract class Computer{
    lateinit var myMediator:Mediator
    abstract fun contact(s:String)
    fun setMediator(m:Mediator){
        myMediator = m
    }
    fun showMessage(s:String){
        println("${this.javaClass} 收到: $s")
    }
}
class FamilyComputer:Computer(){
    override fun contact(s:String) {
        //資料改變時不自己去處理相關的關聯,而是交給中介的互動方法處理
        myMediator.contact(s,this)
    }
}
class Supercomputer:Computer(){
    override fun contact(s:String) {
        myMediator.contact(s,this)
    }
}
//測試
fun main(a:Array<String>){
    val client = FamilyComputer()
    val computerCenter = Supercomputer()
    val mediatorCenter = MediatorCenter(client,computerCenter)
    client.setMediator(mediatorCenter)
    computerCenter.setMediator(mediatorCenter)
    client.contact("我的資料發生了改變,請告訴超算中心") //輸出:class Supercomputer 收到: 我的資料發生了改變,請告訴超算中心
    computerCenter.contact("我的資料發生了改變,請告訴使用者機") //輸出:class FamilyComputer 收到: 我的資料發生了改變,請告訴使用者機
}
     中介模式的優缺點:簡化了物件間的關係,並對其進行鬆耦合,集中同事類間分散的互動設計,同事類間通過同一的介面進行聯絡,因而同事類可以獨立變化;但增加了系統的複雜度,對OCP的支援程度不高。

>什麼是訪問者模式?

     訪問者模式:針對一個相對穩定的資料結構,訪問者模式提供了一個基於該資料結構之上的的操作方法,使得訪問該資料的模式可以基於OCP進行變化。或者說,是針對不同的資料,提供可擴充套件的訪問方案。

     其UML圖如下:


    舉個例子來說明這個模式:老闆和會計對一系列賬目的關注點是不同,也就是老闆和會計是訪問者,而不同的賬目(資料結構)是UML圖中的Element。

abstract class Account{//賬單類
    abstract var myContent:String
    abstract fun accept(visitor:Visitor)
}
class AccountA:Account(){
    override var myContent: String = "賬單A"
    override fun accept(visitor:Visitor){
        visitor.visit(this)
    }
}
class AccountB:Account(){
    override var myContent: String = "賬單B"
    override fun accept(visitor:Visitor){
        visitor.visit(this)
    }
}
abstract class Visitor{//訪問者類
    abstract fun visit(account:AccountA)//利用引數不同進行過載visit函式
    abstract fun visit(account:AccountB)
}
class Boss:Visitor(){
    override fun visit(account: AccountA) {
        println("Boss 瀏覽 賬單A,感嘆道又虧了一個億.")//可以針對性地提供訪問該資料的方案,這裡從簡
    }
    override fun visit(account: AccountB) {
        println("Boss 瀏覽 賬單B,感嘆道又虧了一個億.")
    }
}
class Accountant:Visitor(){
    override fun visit(account: AccountA) {
        println("會計 瀏覽 賬單A,並計算了總盈虧.")
    }
    override fun visit(account: AccountB) {
        println("會計 瀏覽 賬單B,並計算了總盈虧.")
    }
}
//測試
fun main(a:Array<String>){
    val a = AccountA()
    val b = AccountB()
    val boss = Boss()
    val accountant = Accountant()
    a.accept(boss) //Boss 瀏覽 賬單A,感嘆道又虧了一個億.
    b.accept(boss) //Boss 瀏覽 賬單B,感嘆道又虧了一個億.
    a.accept(accountant) //會計 瀏覽 賬單A,並計算了總盈虧.
    b.accept(accountant) //會計 瀏覽 賬單B,並計算了總盈虧.
}
     注意:訪問者模式的使用條件是系統中要有一個穩定的資料結構,這樣才能夠保證OCP的執行。

>什麼是直譯器模式?

    直譯器模式:給定一個上下文,直譯器模式提供了該Context的解釋方案。講白了跟編譯原理裡的語法樹的解析沒啥兩樣。其UML圖如下:


     但我覺得,直譯器模式最重要的核心思想,就是提供了一個interpretor,對特殊的Context進行解析並輸出系統可直接使用的結果。類似黑盒輸入。因此只要是基於此類思想,雖然不符合直譯器模式的標準定義,但其作為直譯器在使用上完全是沒問題的,這裡有一個brainfuck語言的直譯器作為參考:http://blog.csdn.net/shenpibaipao/article/details/73692164

    總的來說,直譯器模式用的地方比較少,對程式設計師的編寫能力要求也較高。

相關推薦

[設計模式](十三)中介模式|訪問者模式|直譯器模式中間行為模式

    >上一篇<中介紹了兩種類狀態行為模式,這次介紹行為模式的最後三種——中間類行為模式:中介模式|訪問者模式|直譯器模式。 >什麼是中間模式 ?     中介模式中,存在一箇中介物件,封裝了一系列物件的互動,使得各個物件間的互動由緊密網路變成鬆散的中

Selenium練習四百度搜索自動化指令碼定位方式

1. 實現百度搜索的自動化測試指令碼,需滿足要求如下: 1)瀏覽器至少選擇兩種(火狐+chrome/ie),關鍵詞為“福哥雜記 CSDN”; 2)指令碼檔案命名為“{組名}_{姓名}_百度搜索_{瀏覽器}_{指令碼序號}.py” 3)搜尋框和“百度一下”元素的定位方式,至少

路一步步走>> 設計模式十三Chain of Responsibility-責任鏈

package com.test.DPs.XingWei.ChainOfResponsibility; /** * 行為型:Chain of Responsibility-責任鏈 外觀:作用面為 物件 */ interface Handler{ void operator(); } ab

Java設計模式(十三)代理設計模式

代理模式可以分為以下四類 遠端代理(Remote Proxy):控制對遠端物件(不同地址空間)的訪問,它負責將請求及其引數進行編碼,並向不同地址空間中的物件傳送已經編碼的請求。 虛擬代理(Virtual Proxy):根據需要建立開銷很大的物件,它可以快取實體的附加資訊,以

設計模式系列中介模式

引入 1.案例: 假設計算機1,2,3,4之間要相互通訊。 2.面向實現程式設計方案: 類Computer1中要儲存類Computer2、類Computer3和類Computer4例項,才能呼叫Computer2、Computer3、Comput

JAVA實現單例模式方法使用靜態內部類實現單例設計模式

靜態程式碼塊和靜態內部類的載入順序:當呼叫外部類的建構函式是,外部類的靜態程式碼塊同時被載入,但是其內部類不會同時被載入;當且僅當內部類的靜態域或其構造方法或其靜態方法被呼叫時,內部內才被載入。 因此,通過內部內實現單例,就能實現延遲載入。 這個解決方案被稱為Lazy i

設計模式(四)從“兵工廠”中探索簡單工廠、工廠方法和抽象工廠模式

前面陸陸續續的更新了三篇關於設計模式的部落格,是關於“策略模式”、“觀察者模式”、“裝飾者模式”的,今天這篇部落格就從“兵工廠”中來探索一下“工廠模式”(Factory Pattern)。“工廠模式”又可以分為“簡單工廠模式”(Simple Factory Pattern)、“工廠方法模式”(Factory

設計模式與應用代理模式詳解

簡介 Proxy代理模式,是構造型的設計模式之一 代理模式為其他物件提供代理以控制這個物件的訪問。 所謂代理,是指具有與代理元(被代理物件)具有相同介面的類。client需要通過代理與被代理的目標類互動,代理類就是在互動的過程中(前後

CentOS6.5下搭建ftp服務器認證模式匿名用戶、本地用戶、虛擬用戶

所有者 start 生效 用戶權限 密碼 新建 over 使用 則無 CentOS 6.5下搭建ftp服務器 vsftpd(very secure ftp daemon,非常安全的FTP守護進程)是一款運行在Linux操作系統上的FTP服務程序,不僅完全開源而且免費,此外,

設計模式 十九 模板方法模式Template method行為

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

Java 設計模式—工廠模式方式

  來看下它的組成:        1)抽象工廠角色: 這是工廠方法模式的核心,它與應用程式無關。是具體工廠角色必須實現的介面或者必須繼承的父類。在java中它由抽象類或者介面來實現。        2)具體工廠角色:它含有和具體業務邏輯有關的程式碼。由應用程式呼叫以建立對應的具體產品的物件。      

Java設計的單例模式寫法

最近在一些部落格上面看到的單例模式,無一例外都是餓漢和懶漢,這兩個確實是單例模式,但是各有自己的弊端 先上程式碼吧 //餓漢式 class ClassA{ private static final ClassA instance = new ClassA(); pub

設計模式11——模板方法模式Template Method Pattern,行為

1.概述 使用設計模式可以提高程式碼的可複用性、可擴充性和可維護性。 模板方法模式(Template Method Pattern)屬行為型,在一個方法中定義一個演算法骨架,而將一些步驟延遲到子類中,使子類可以不改變演算法結構即可重定義演算法的某些特定步驟。

LVS負載均衡模式

lvs負載均衡集群1、主流開源軟件:LVS、keepalived、haproxy、nginx等;▏LVS特點:抗負載能力強、是工作在網絡4層之上僅作分發之用,沒有流量的產生,這個特點也決定了它在負載均衡軟件裏的性能最強的;配置性比較低,這是一個缺點也是一個優點,因為沒有可太多配置的東西,所以並不需要太多接觸,

Silverlight & Blend動畫設計系列十三三角函數Trigonometry動畫之飄落的雪花Falling Snow

4.2 函數 produced end amp war handler 代碼 alex 平時我們所看到的雪花(Falling Snow)飄飄的效果實際上也是一個動畫,是由許多的動畫對象共同完成的一個界面效果。對於不同大小的雪片可以通過縮放變換(ScaleTransform)

搭建叢集的模式

搭建叢集的模式有三種: 1、偽分散式 node01在一臺伺服器上,啟動多個程序,分別表示各個角色 2、完全分散式 在多臺伺服器上,每臺伺服器啟動不同角色的程序,使用多臺伺服器組成HDFS叢集 node01 : namenode node02 : seco

【Android架構】基於MVP模式的Retrofit2+RXjava封裝之檔案上傳

最近手頭事比較多,抽個空把之前系列也補充一下。 先回顧下之前的 【Android架構】基於MVP模式的Retrofit2+RXjava封裝(一) 【Android架構】基於MVP模式的Retrofit2+RXjava封裝之檔案下載(二) 今天要說的是檔案上傳 1.單圖上

一個例子穿插不同的工廠模式形態

1、簡單工廠模式 工廠類根據提供給它的引數,返回的是幾個產品中的一個類的例項。通常情況下,它返回的是一個公共的父類,在這個工廠類裡面,父類的引用指向子類的物件 廠長生產杯子時先不讓生產線知道我要產的

FTP資料傳輸模式

導讀:對於FTP我們需要掌握的東西很多。其中就是包括它的傳輸模式。這裡我們就來對其進行一下系統的總結。那麼我們就來看看都有哪些FTP資料傳輸模式吧。在眾多網路應用中,FTP(檔案傳輸協議)有著非常重要的地位。Internet中一個十分重要的資源就是軟體資源,而各種各樣的軟體資

java多執行緒同步以及執行緒間通訊詳解&amp;消費者生產者模式&amp;死鎖&amp;Thread.join()多執行緒程式設計之二

從執行結果,我們就可以看出我們4個售票視窗同時賣出了1號票,這顯然是不合邏輯的,其實這個問題就是我們前面所說的執行緒同步問題。不同的執行緒都對同一個資料進了操作這就容易導致資料錯亂的問題,也就是執行緒不同步。那麼這個問題該怎麼解決呢?在給出解決思路之前我們先來分析一下這個問題是怎麼產生的?我們宣告一個執行緒類