溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

go中設計模式之結構型模式

發(fā)布時間:2020-06-15 00:42:06 來源:網絡 閱讀:1339 作者:wx5cf612fe3a728 欄目:編程語言

外觀模式

1. 定義: 外部與一個子系統(tǒng)通信必須通過一個統(tǒng)一的對象進行,為子系統(tǒng)中的一組接口提供一致界面。

2. 代碼示例:

// 定義對外API
type API interface {
    Test()
}

func NewAPI() API {
    return apiImpl{newMod()}
}

type apiImpl struct {
    m mod
}

func (a apiImpl) Test() {
    a.m.mod()
}

// 需要交互的內部模塊
type mod interface {
    mod()
}

func newMod() mod {
    return modImpl{}
}

type modImpl struct {
}

func (m modImpl) mod() {

}

3. 實現步驟

  • 定義內部模塊
  • 定義對外交互接口及實現

4. 使用場景

  • 當要為一個復雜子系統(tǒng)提供一個簡單接口時可以使用外觀模式。該接口可以滿足大多數用戶的需求,而且用戶也可以越過外觀類直接訪問子系統(tǒng)。
  • 客戶程序與多個子系統(tǒng)之間存在很大的依賴性。引入外觀類將子系統(tǒng)與客戶以及其他子系統(tǒng)解耦,可以提高子系統(tǒng)的獨立性和可移植性。
  • 在層次化結構中,可以使用外觀模式定義系統(tǒng)中每一層的入口,層與層之間不直接產生聯系,而通過外觀類建立聯系,降低層之間的耦合度。

5. 優(yōu)點

對客戶屏蔽子系統(tǒng)組件

適配器模式

1. 定義: 將一個接口轉換成客戶希望的另一個接口。

2. 代碼示例:

// 定義被適配的接口
type Adapter interface {
    Request() string
}

type adaptee struct {
}

func (adaptee) Request() string {
}

func NewAdapter() Adapter {
    return &adaptee{}
}

// 定義目標接口
type Target interface {
    TargetRequest() string
}

func New(adapter Adapter) Target {
    return &target{adapter}
}

type target struct {
    Adapter
}

func (t *target) TargetRequest() {
    t.Request()
}

3. 實現步驟

  • 定義被適配的接口和實現
  • 定義目標接口和實現,并且實現接口由被適配接口創(chuàng)建

4. 使用場景

系統(tǒng)需要使用現有的類,而這些類的接口不符合系統(tǒng)的需要。

5. 優(yōu)點

將目標類和適配者類解耦,通過引入一個適配器類來重用現有的適配者類,而無須修改原有代碼。

裝飾模式

1. 定義: 動態(tài)地給一個對象增加一些額外的職責。

2. 代碼示例:

// 定義組件
type Component interface {
    Calc() int
}

type ConcreteComponent struct{}

func (*ConcreteComponent) Calc() int {
    return 0
}

// 定義裝飾對象
type MulDecorator struct {
    Component
    num int
}

func WarpMulDecorator(c Component, num int) Component {
    return &MulDecorator{
        Component: c,
        num:       num,
    }
}

func (d *MulDecorator) Calc() int {
    return d.Component.Calc() * d.num
}

type AddDecorator struct {
    Component
    num int
}

func WarpAddDecorator(c Component, num int) Component {
    return &AddDecorator{
        Component: c,
        num:       num,
    }
}

func (d *AddDecorator) Calc() int {
    return d.Component.Calc() + d.num
}

3. 實現步驟

  • 定義組件
  • 定義裝飾對象
  • 使用裝飾對象生成組件

4. 使用場景

在不影響其他對象的情況下,以動態(tài)、透明的方式給單個對象添加職責。

5. 優(yōu)點

可以通過一種動態(tài)的方式來擴展一個對象的功能,通過配置文件可以在運行時選擇不同的裝飾器,從而實現不同的行為。

享元模式

1. 定義: 享元模式通過共享技術實現相同或相似對象的重用。

2. 代碼示例:

// 定義享元對象
type ImageFlyweight struct {
    data string
}

func NewImageFlyweight(filename string) *ImageFlyweight {
    // Load image file
    data := fmt.Sprintf("image data %s", filename)
    return &ImageFlyweight{
        data: data,
    }
}

func (i *ImageFlyweight) Data() string {
    return i.data
}

// 定義享元對象工廠
type ImageFlyweightFactory struct {
    maps map[string]*ImageFlyweight
}

var imageFactory *ImageFlyweightFactory

func GetImageFlyweightFactory() *ImageFlyweightFactory {
    if imageFactory == nil {
        imageFactory = &ImageFlyweightFactory{
            maps: make(map[string]*ImageFlyweight),
        }
    }
    return imageFactory
}

func (f *ImageFlyweightFactory) Get(filename string) *ImageFlyweight {
    image := f.maps[filename]
    if image == nil {
        image = NewImageFlyweight(filename)
        f.maps[filename] = image
    }

    return image
}

type ImageViewer struct {
    *ImageFlyweight
}

func NewImageViewer(filename string) *ImageViewer {
    image := GetImageFlyweightFactory().Get(filename)
    return &ImageViewer{
        ImageFlyweight: image,
    }
}

func (i *ImageViewer) Display() {
    fmt.Printf("Display: %s\n", i.Data())
}

3. 實現步驟

  • 定義享元對象
  • 定義享元工廠
  • 使用享元工廠創(chuàng)建

4. 使用場景

  • 一個系統(tǒng)有大量相同或者相似的對象,由于這類對象的大量使用,造成內存的大量耗費。
    對象的大部分狀態(tài)都可以外部化,可以將這些外部狀態(tài)傳入對象中。
  • 使用享元模式需要維護一個存儲享元對象的享元池,而這需要耗費資源,因此,應當在多次重復使用享元對象時才值得使用享元模式。

5. 優(yōu)點

享元模式從對象中剝離出不發(fā)生改變且多個實例需要的重復數據,獨立出一個享元,使多個對象共享,從而節(jié)省內存以及減少對象數量。

代理模式

1. 定義: 給某一個對象提供一個代理,并由代理對象控制對原對象的引用。

2. 代碼示例:

package proxy

type Subject interface {
    Do() string
}

type RealSubject struct{}

func (RealSubject) Do() string {
    return "real"
}

type Proxy struct {
    real RealSubject
}

func (p Proxy) Do() string {
    var res string

    // 在調用真實對象之前的工作,檢查緩存,判斷權限,實例化真實對象等。。
    res += "pre:"

    // 調用真實對象
    res += p.real.Do()

    // 調用之后的操作,如緩存結果,對結果進行處理等。。
    res += ":after"

    return res
}

3. 實現步驟

  • 定義接口
  • 定義實現對象
  • 定義代理實現對象

4. 使用場景

  • 并由代理對象控制對原對象的引用,增加請求注入劫持

5. 優(yōu)點

代理模式能夠協(xié)調調用者和被調用者,在一定程度上降低了系統(tǒng)的耦合度。

橋接模式

1. 定義: 給某一個對象提供一個代 理,并由代理對象控制對原對象的引用。

2. 代碼示例:

package bridge

import "fmt"

type AbstractMessage interface {
    SendMessage(text, to string)
}

type MessageImplementer interface {
    Send(text, to string)
}

type MessageSMS struct{}

func ViaSMS() MessageImplementer {
    return &MessageSMS{}
}

func (*MessageSMS) Send(text, to string) {
    fmt.Printf("send %s to %s via SMS", text, to)
}

type MessageEmail struct{}

func ViaEmail() MessageImplementer {
    return &MessageEmail{}
}

func (*MessageEmail) Send(text, to string) {
    fmt.Printf("send %s to %s via Email", text, to)
}

type CommonMessage struct {
    method MessageImplementer
}

func NewCommonMessage(method MessageImplementer) *CommonMessage {
    return &CommonMessage{
        method: method,
    }
}

func (m *CommonMessage) SendMessage(text, to string) {
    m.method.Send(text, to)
}

type UrgencyMessage struct {
    method MessageImplementer
}

func NewUrgencyMessage(method MessageImplementer) *UrgencyMessage {
    return &UrgencyMessage{
        method: method,
    }
}

func (m *UrgencyMessage) SendMessage(text, to string) {
    m.method.Send(fmt.Sprintf("[Urgency] %s", text), to)
}

3. 實現步驟

4. 使用場景

5. 優(yōu)點

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI