一、工厂模式
// Shape接口
type Shape interface {
draw()
}
type Circle struct {}
func (s *Circle) draw() {
fmt.Println("Circle")
}
type Square struct {}
func (s *Square) draw() {
fmt.Println("Square")
}
// Color接口
type Color interface {
fill()
}
type Red struct {}
func (s *Red) fill() {
fmt.Println("Red")
}
type Blue struct {}
func (s *Blue) fill() {
fmt.Println("Blue")
}
type Green struct {}
func (s *Green) fill() {
fmt.Println("Green")
}
1、普通工厂
// Shape工厂
func ShapeFactory(shape string) Shape {
switch shape {
case "circle":
return &Circle{}
case "square":
return &Square{}
default:
return nil
}
}
// Color工厂
func ColorFactory(color string) Color {
switch color {
case "red":
return &Red{}
case "blue":
return &Blue{}
case "green":
return &Green{}
default:
return nil
}
}
func main() {
// shape工厂实例化
shape := ShapeFactory("circle")
shape.draw() // 输出 => "Circle"
// color工厂实例化
color := ColorFactory("red")
color.fill() // 输出 => "Red"
}
2、抽象工厂
工厂封装在抽象工厂中统一获取对应的工厂
通过抽象工厂封装了Shape和Color的工厂类,从抽象工厂中获取工厂,在获取工厂对应的生产实例。
简单抽象工厂
// 抽象工厂
type AbstractFactory interface {
getShape(string) Shape
getColor(string) Color
}
type FactoryProducer struct {}
func NewFactoryProducer() AbstractFactory {
return &FactoryProducer{}
}
// 抽象工厂:Shape工厂
func (f *FactoryProducer) getShape(shape string) Shape {
switch shape {
case "circle":
return &Circle{}
case "square":
return &Square{}
default:
return nil
}
}
// 抽象工厂:Color工厂
func (f *FactoryProducer) getColor(color string) Color {
switch color {
case "red":
return &Red{}
case "blue":
return &Blue{}
case "green":
return &Green{}
default:
return nil
}
}
func main() {
// 抽象工厂
abstractFactory := NewFactoryProducer()
// 抽象工厂:Shape工厂
shape := abstractFactory.getShape("circle")
shape.draw() // 输出 => "Circle"
// 抽象工厂:Color工厂
color := abstractFactory.getColor("blue")
color.fill() // 输出 => "Blue"
}
完全体抽象工厂
// ==== 颜色 ====
type Color interface {
color()
}
type Red struct {}
func (this *Red) color() {
fmt.Println("红色")
}
type Yellow struct {}
func (this *Yellow) color() {
fmt.Println("黄色")
}
type Blue struct {}
func (this *Blue) color() {
fmt.Println("蓝色")
}
// ==== 形状 ====
type Shape interface {
shape()
}
type Circular struct {}
func (this *Circular) shape() {
fmt.Println("圆形")
}
type Square struct {}
func (this *Square) shape() {
fmt.Println("正方形")
}
// ===== 抽象工厂 =====
type AbstractFactory interface {
ColorFactory(color string) Color // 颜色工厂
ShapeFactory(shape string) Shape // 形状工厂
}
// 形状工厂
type ShapeFactory struct {}
func (factory *ShapeFactory) ColorFactory(color string) Color {
return nil
}
func (factory *ShapeFactory) ShapeFactory(shape string) Shape {
switch shape {
case "cir":
return &Circular{}
case "square":
return &Square{}
default:
return nil
}
}
// 颜色工厂
type ColorFactory struct {}
func (factory *ColorFactory) ColorFactory(color string) Color {
switch color {
case "red":
return &Red{}
case "yellow":
return &Yellow{}
case "blue":
return &Blue{}
default:
return nil
}
}
func (factory *ColorFactory) ShapeFactory(shape string) Shape {
return nil
}
// 总工厂 选择 子工厂
func NewFactory(choice string) AbstractFactory {
switch choice {
case "shape":
return &ShapeFactory{}
case "color":
return &ColorFactory{}
default:
return nil
}
}
func Try() {
colorFactory := NewFactory("color")
colorFactory.ColorFactory("red").color()
shapFactory := NewFactory("shape")
shapFactory.ShapeFactory("cir").shape()
}
二、单例模式
1、饿汉式
好处:初始化就加载,不用担心多线程多次创建
坏处:初始化就加载,如果相对耗时,初始化加载时间会延长
type SingleObject struct {}
var instance *SingleObject = &SingleObject{}
func getInstance() *SingleObject {
return instance
}
2、懒汉式
- 默认懒汉
type SingleObject struct {} var instance *SingleObject func getInstance() *SingleObject { if instance == nil { instance = &SingleObject{} } return instance }
- 懒汉加锁(避免多线程操作)
方式1:这种方法可能会导致所有线程阻塞
方式2:var mutex sync.Mutex type SingleObject struct {} var instance *SingleObject func getInstance() *SingleObject { mutex.Lock() defer mutex.UnLock() if instance == nil { instance = &SingleObject{} } return instance }
once.Do
第一次加载时执行的代码,避免加锁阻塞var once sync.Once type SingleObject struct {} var instance *SingleObject func getInstance() *SingleObject { once.Do(func(){ instance = &SingleObject{} }) return instance }
三、建造者模式
建造者模式可以理解为,一层一层的建造。将一块的业务逻辑抽离,由底层分解。
理解:
比如,吃汉堡,需要包装纸(包装属于一个类),汉堡使用纸包装,汉堡是所有品种的大类,具体类可以是蔬菜汉堡、炸鸡煲等。这些创建好,需要一个统一的点菜类,这个类可以添加菜品,可以显示当前点菜的数量,总价等。我们甚至可以依赖此类,来做一个套餐方法,基础菜品默认添加到该套餐内。
理解如下图
- 创建包装类
// ===== 包装类 ===== type Packing interface { Pack() string } // 包装:纸 type Wrapper struct {} func (this *Wrapper) Pack() string { return "Wrapper" } // 包装:杯 type Bottle struct {} func (this *Bottle) Pack() string { return "Bottle" }
- 创建品类结构体
// ===== 品类 ===== type Item interface { Green() bool // 是否健康 Packing() Packing // 包装 Name() string // 名称 Price() float64 // 价格 }
- 创建品类的大类
// 汉堡父类 type Burger struct {} func (s *Burger) Green() bool { return false } func (burger *Burger) Packing() Packing { return &Wrapper{} } func (burger *Burger) Name() string { return "" } func (burger *Burger) Price() float64 { return 0.0 } // 冷饮父类 type ColdDrink struct {} func (s *ColdDrink) Green() bool { return true } func (coldDrink *ColdDrink) Packing() Packing { return &Bottle{} } func (coldDrink *ColdDrink) Name() string { return "" } func (coldDrink *ColdDrink) Price() float64 { return 0.0 }
- 汉堡子类
// 蔬菜汉堡 type VegBurger struct { Burger } func (coldDrink *VegBurger) Name() string { return "蔬菜汉堡" } func (coldDrink *VegBurger) Price() float64 { return 12.5 } // 炸鸡汉堡 type ChickenBurger struct { Burger } func (coldDrink *ChickenBurger) Name() string { return "炸鸡汉堡" } func (coldDrink *ChickenBurger) Price() float64 { return 22.5 }
- 冷饮子类
// 可口可乐 type Coker struct { ColdDrink Category string // 品类 } func (coldDrink *Coker) Name() string { return "可口可乐" } func (coldDrink *Coker) Price() float64 { return 3.0 } // 牛奶 type Milk struct { ColdDrink Category string // 品类 } func (coldDrink *Milk) Name() string { return "牛奶" } func (coldDrink *Milk) Price() float64 { return 6.0 }
- 套餐类
type Meal struct { item []Item } // 添加食物 func (this *Meal) AddItem(item Item) { this.item = append(this.item, item) } func (this *Meal) ShowAllPrice() float64 { prices := 0.0 for i := 0; i < len(this.item); i++ { prices += this.item[i].Price() } fmt.Println("总价:", prices) return prices } // 显示食物 func (this *Meal) ShowItem() { for _, item := range this.item { fmt.Println("名称:", item.Name()) fmt.Println("包装:", item.Packing().Pack()) fmt.Println("价格:", item.Price()) } }
- 创建套餐
func Package01() Meal { meal := Meal{ item: []Item{}, } meal.AddItem(&VegBurger{}) meal.AddItem(&ChickenBurger{}) meal.AddItem(&Coker{}) return meal }
四、桥接模式
桥接可以理解为 灵魂和肉体,灵魂为轴心不变,肉体可以随意选择
如下案例可以理解为:圆是灵魂,颜色是肉体
- 基础画笔类
type Draw interface { drawCircle(string) } type Circle01 struct {} func (this *Circle01) drawCircle(color string) { fmt.Println("画圆01 [ color: " + color + " ]") } type Circle02 struct {} func (this *Circle02) drawCircle(color string) { fmt.Println("画圆02 [ color: " + color + " ]") }
- 抽象类
type Shape struct { draw Draw } // 3 func (this *Shape) Shape(draw Draw) { this.draw = draw }
- 抽象实体类
type Circle struct { shape Shape color string } func InitCircle(color string, draw Draw) *Circle { circle := &Circle{ color: color, } // 2 circle.shape.Shape(draw) return circle } func (this *Circle) Draw() { this.shape.draw.drawCircle(this.color) }
- 调用
&bridge.Circle01{} 1 => Draw接口接收 2 => 传递给Shape 3func main(){ // 1 c1 := bridge.InitCircle("红色", &bridge.Circle01{}) c1.Draw() // 圆1 c1.shape.Shape(&bridge.Circle02{}) c1.Draw() // 圆2 c2 := bridge.InitCircle("黄色", &bridge.Circle02{}) c2.Draw() // 圆2 }
案例2:画家是灵魂,形状是肉体
type DrawImpl interface { draw() } type DrawCricle struct {} func (this *DrawCricle) draw(color string){ fmt.Println("圆形;",color) } type DrawSquare struct {} func (this *DrawSquare) draw(color string){ fmt.Println("正方形;",color) } type DrawAbstract interface { DrawShape() } // 画家 type Painter struct { DrawImpl } func NewPainter(draw DrawImpl) DrawAbstract { return &Painter{draw} } func (this *Painter) DrawShape(){ this.draw() } func main(){ painter := NewPainter(&DrawSquare{}) painter.DrawShape() }
五、命令模式
-
股票
type Stock struct { name string // 库存 quantity int // 数量 } func (this *Stock) buy() { this.quantity++ fmt.Println("买入:", this.name, this.quantity) } func (this *Stock) sell() { this.quantity -= 10000 fmt.Println("卖出", this.name, this.quantity) }
-
购买股票需要订单,所有定义订单接口
type Order interface { execute() // 执行 }
-
买卖需要对应订单操作
// 买入股票 type BuyStock struct { stock *Stock } func NewBuyStock(stock *Stock) Order { return &BuyStock{stock: stock} } func (this *BuyStock) execute() { this.stock.buy() } // 卖出股票 type SellStock struct { stock *Stock } func NewSellStock(stock *Stock) Order { return &SellStock{stock: stock} } func (this *SellStock) execute() { this.stock.sell() }
-
股票操盘手命令
// 股票操盘手 type Operator struct { orders []Order } func (this *Operator) takeOrder(order Order) { this.orders = append(this.orders, order) } func (this *Operator) placeOrders() { for _, order := range this.orders { order.execute() } this.orders = []Order{} } // 。。。。。后续可以增加命令,比如回购股票等等的命令
-
操作
func main(){ // 特斯拉股票 stock := &Stock{ name: "特斯拉", quantity: 100000, } // 初始化买卖的操作 orderBuy := NewBuyStock(stock) orderSell := NewSellStock(stock) // 初始化操盘手 operator := Operator{ orders: []Order{}, } // 先买三只股票 operator.takeOrder(orderBuy) operator.takeOrder(orderBuy) operator.takeOrder(orderBuy) operator.placeOrders() // 再买两只股票 operator.takeOrder(orderBuy) operator.takeOrder(orderBuy) operator.placeOrders() // 卖出股票 operator.takeOrder(orderSell) operator.placeOrders() }
六、迭代器模式
迭代器模式就是java中的Iterator,是一个思想实现的数据结构
- 迭代器接口
type Iterator interface { HasNext() bool Next() interface{} }
- 实现迭代器
type aggIterator struct { index int container *Container } func (this *aggIterator) HasNext() bool { if this.index < len(this.container.Datas) { return true } return false } func (this *aggIterator) Next() interface{} { if this.HasNext() { data := this.container.Datas[this.index] this.index++ return data } return nil }
- 数据容器
// 容器 type Container struct { Datas []interface{} } func (this *Container) GetIterator() Iterator { // 容器存放具体数据 // 迭代元素交给Iterator return &aggIterator{ index: 0, container: this, } }
- 调用
func main(){ datas := []interface{}{1,2,31,4,1,31,2} container := &Container{ Datas: datas, } iterator := container.GetIterator() for { if a := iterator.Next(); a == nil { break } else { fmt.Print(a,"\t") } } }