一個菜鳥的設計模式之旅,使用 Golang 實現。本節實現代理模式。小明很喜歡同班的雪怡,但是過於靦腆的他不敢當面說。打算通過手機(代理)跟雪怡表白! ...
一個菜鳥的設計模式之旅,文章可能會有不對的地方,懇請大佬指出錯誤。
編程旅途是漫長遙遠的,在不同時刻有不同的感悟,本文會一直更新下去。
程式介紹
本程式實現代理模式。小明很喜歡同班的雪怡,但是過於靦腆的他不敢當面說。打算通過手機(代理)跟雪怡表白!
小明給雪怡發了個表情包
小明祝雪怡生日快樂
小明對雪怡說做我女朋友吧
雪怡對小明說我願意!
程式代碼
proxy.go
package main
import "fmt"
type sender interface {
sendMeme(r people)
sendWish(r people)
sendConfession(r people)
sendYes(r people)
}
type people string
func (p people) sendMeme(r people) {
fmt.Printf("%s給%s發了個表情包\n", p, r)
}
func (p people) sendWish(r people) {
fmt.Printf("%s祝%s生日快樂\n", p, r)
}
func (p people) sendConfession(r people) {
fmt.Printf("%s對%s說做我女朋友吧\n", p, r)
}
func (p people) sendYes(r people) {
fmt.Printf("%s對%s說我願意!\n", p, r)
}
type proxy struct {
people
}
func (p proxy) sendMeme(r people) {
p.people.sendMeme(r)
}
func (p proxy) sendWish(r people) {
p.people.sendWish(r)
}
func (p proxy) sendConfession(r people) {
p.people.sendConfession(r)
}
func (p proxy) sendYes(r people) {
p.people.sendYes(r)
}
main.go
package main
func main() {
var girl, boy people = "雪怡", "小明"
proxy := proxy{boy}
proxy.sendMeme(girl)
proxy.sendWish(girl)
proxy.sendConfession(girl)
proxy.people = girl
proxy.sendYes(boy)
}
Console
小明給雪怡發了個表情包
小明祝雪怡生日快樂
小明對雪怡說做我女朋友吧
雪怡對小明說我願意!
思考總結
什麼是代理模式
在代理模式(Proxy Pattern)中,一個類代表另一個類的功能。這種類型的設計模式屬於結構型模式。在代理模式中,我們創建具有現有對象的對象,以便向外界提供功能介面。
代理模式:為其他對象提供一種代理以控制對這個對象的訪問。
主要解決:在直接訪問對象時帶來的問題,比如說:要訪問的對象在遠程的機器上。在面向對象系統中,有些對象由於某些原因(比如對象創建開銷很大,或者某些操作需要安全控制,或者需要進程外的訪問),直接訪問會給使用者或者系統結構帶來很多麻煩,我們可以在訪問此對象時加上一個對此對象的訪問層。
何時使用:想在訪問一個類時做一些控制。
如何解決:增加中間層。
關鍵代碼:實現與被代理類組合。
應用實例: 1、Windows 裡面的快捷方式。 2、豬八戒去找高翠蘭結果是孫悟空變的,可以這樣理解:把高翠蘭的外貌抽象出來,高翠蘭本人和孫悟空都實現了這個介面,豬八戒訪問高翠蘭的時候看不出來這個是孫悟空,所以說孫悟空是高翠蘭代理類。 3、買火車票不一定在火車站買,也可以去代售點。 4、一張支票或銀行存單是賬戶中資金的代理。支票在市場交易中用來代替現金,並提供對簽發人賬號上資金的控制。
優點: 1、職責清晰。 2、高擴展性。 3、智能化。
缺點: 1、由於在客戶端和真實主題之間增加了代理對象,因此有些類型的代理模式可能會造成請求的處理速度變慢。 2、實現代理模式需要額外的工作,有些代理模式的實現非常複雜。
使用場景:按職責來劃分,通常有以下使用場景: 1、遠程代理。 (對象在不同的地址空間)2、虛擬代理。 (根據需要創建開銷很大的對象,然後存放實例化長時間的對象,如網頁頁面)3、Copy-on-Write 代理。 4、保護(Protect or Access)代理。 (控制真實對象訪問時的許可權)5、Cache代理。 6、防火牆(Firewall)代理。 7、同步化(Synchronization)代理。 8、智能引用(Smart Reference)代理。(當調用真實對象時,代理處理另外一些事)
代理模式與外觀模式主要區別:
- 代理模式是一個類代表另一個類的功能,代表一個單一對象,而外觀對象代表一個子系統。
- 代理的客戶對象無法直接訪問目標對象,小明無法直接跟雪怡面對面,他們兩隻能通過手機間接訪問。代理可以提供對目標對象的訪問控制。
- 外觀的客戶對象可以直接訪問子系統的各個對象,但通常由外觀對象提供子系統各個元件功能的簡化的共同層次的調用介面。
代理模式與適配器模式主要區別:
- 代理是一種原來對象的代表,是具有現有對象的對象,其他需要與這個對象打交道的操作都是與這個代表交涉。而適配器不需要虛構出一個代表者,只需要為應付特定使用目的,將原來的類進行一些組合。
- 適配器模式主要改變所考慮對象的介面,而代理模式不能改變所代理類的介面。
代理模式與裝飾器模式主要區別:
- 裝飾器模式為了增強功能,而代理模式是為了加以控制。
參考資料
- 《Go語言核心編程》李文塔
- 《Go語言高級編程》柴樹彬、曹春輝
- 《大話設計模式》程傑
- 單例模式 | 菜鳥教程