go 常用设计模式-结构型模式

本次分享结构型模式,主要包括:

  • 代理模式
  • 装饰器模式
  • 适配器模式
  • 享元模式

1.代理模式

package proxy

import "fmt"

/*
结构型模式

代理,代表打理,以他人的名义代表委托人打理其本职工作之外或不所能及的事务,达成合作关系并更高效地促成事务完成的目的。
强调的是对被代理对象的控制。
*/

// 以光猫代理访问为例,限制小孩访问,设置相应的访问黑名单
type Modem struct {}

func (t Modem) Access(url string)  {
	fmt.Println("正常访问:" + url)
}

type Proxy struct {
	BlackList []string
	M Modem
}

// filter access
func (t Proxy) FilterAccess(url string)  {
	for _, v := range t.BlackList {
		if v == url {
			fmt.Println("禁止访问:" + url)
			return
		}
	}
	t.M.Access(url)
}

2.装饰器模式

package decorator

import "fmt"

/*
结构型模式

指在不改变现有对象结构的情况下,动态地给该对象增加一些额外功能的模式

例如:日期格式化函数,系统只提供了通用的方法。当遇到其他格式的日期的时候,
需要额外增加一些变化,使特殊日期符合一般的格式化要求。这就是对系统函数的装饰。

再例如:买的毛坯房,房子的主体结构我们是不允许修改的,
但是我们可以请师傅装饰内饰,使原本平平无奇的房子,变的富丽堂皇的精装修。

从上面举例可以看出,原始的对象(女生、毛坯房、系统函数)是不允许修改的,只能额外增加一些装饰
*/

// 以女生化妆为例,先定义一般接口
type Showable interface {
	Show()
}

// implement normal girl
type Girl struct {}

func (t *Girl) Show()  {
	fmt.Printf("未化妆 girl")
}

// Showable接口在调用的时候,传入为Showable的实现对象即可
type MakeUPDecorator struct {
	Showable
}

func (t *MakeUPDecorator) Show()  {
	fmt.Print("打粉底(")
	t.Showable.Show()
	fmt.Print(")")
}

type LipDecorator struct {
	Showable
}

func (t *LipDecorator) Show() {
	fmt.Print("涂口红(")
	t.Showable.Show()
	fmt.Print(")\n")
}

3.适配器模式

package adapter

import "fmt"

/*
结构型模式

将一个类的接口转换成客户希望的另外一个接口,使得原本由于接口不兼容而不能一起工作的那些类能一起工作。

类似不同的移动设备 USB -> type C | Lighting | android
*/

type USB interface {
	Work()
}

// 对外接口
func Charge(usb USB)  {
	usb.Work()
}

// TypeC 未实现usb接口的Work方法,不可以充电
type TypeC struct {}

func (t TypeC) IPhone()  {
	fmt.Println("Charge IPhone")
}

// 通过适配器实现usb接口充电,套一层或者继承
type AdapterTypeC struct {
	TypeC
}

func (t AdapterTypeC) Work()  {
	t.IPhone()
}

type Micro struct {}

func (t Micro) Work()  {
	fmt.Println("Charge Android")
}

4.享元模式

package flyWeight

import (
	"fmt"
	"sync"
)

/*
结构型模式

对象复用

运用共享技术来有效地支持大量细粒度对象的复用。
它通过共享已经存在的对象来大幅度减少要创建的对象数量、避免大量相似类的开销,从而提高系统资源的利用率。

享元就是共享的概念,比如线程池、对象池、连接池等等

共用对象、节省内存、减少对象数量
*/

// define share obj
type Flyweight interface {
	Operation()
}

// implement interface
type ConcreteFlyweight struct {
	Key string
}

func (t ConcreteFlyweight) Operation()  {
	fmt.Println(t.Key)
}

// define obj pool, use map
type FlyweightFactory struct {
	mu sync.Mutex
	Flys map[string]Flyweight
}

func (t FlyweightFactory) Get(key string) Flyweight {
	t.mu.Lock()
	defer t.mu.Unlock()

	if f, ok := t.Flys[key]; !ok {
		f = ConcreteFlyweight{Key: key}
		t.Flys[key] = f
		return f
	} else {
		return f
	}
}

func (t FlyweightFactory) Len() int {
	return len(t.Flys)
}

func (t FlyweightFactory) Put()  {

}

5.测试

...
        fmt.Println(strings.Repeat("-", 10) + "结构型模式" + strings.Repeat("-", 10))
	// 10.proxy mode
	fmt.Println("proxy mode testing...")
	p := proxy.Proxy{
		BlackList: []string{"www.bilibili.com", "www.youku.com"},
		M: proxy.Modem{},
	}
	p.FilterAccess("www.baidu.com")
	p.FilterAccess("www.bilibili.com")
	fmt.Printf("+%s+\n", strings.Repeat("-", 50))

	// 11.decorator mode
	fmt.Println("decorator mode testing...")
	girl := decorator.Girl{}
	girl.Show()
	fmt.Println(" 化妆后:")
	l := decorator.LipDecorator{Showable: &decorator.MakeUPDecorator{&girl}}
	l.Show()
	fmt.Printf("+%s+\n", strings.Repeat("-", 50))

	// 12.adapter mode
	fmt.Println("decorator mode testing...")
	adapter.Charge(adapter.Micro{})
	adapter.Charge(adapter.AdapterTypeC{})
	fmt.Printf("+%s+\n", strings.Repeat("-", 50))

	// 13.flyweight mode
	fmt.Println("flyweight mode testing...")
	fly := flyWeight.FlyweightFactory{Flys: make(map[string]flyWeight.Flyweight)}
	fly.Get("A").Operation()
	fly.Get("A").Operation()
	fly.Get("B").Operation()
	fly.Get("C").Operation()
	fmt.Println("flyweight len:", fly.Len())
	fmt.Printf("+%s+\n", strings.Repeat("-", 50))
...

参考文档:

posted on 2023-03-21 18:09  进击的davis  阅读(14)  评论(0编辑  收藏  举报

导航