工厂模式
定义一个创建对象的接口,让其子类自己决定实例化哪一个工厂类,工厂模式使其创建过程延迟到子类进行。让其子类实现工厂接口,返回的也是一个抽象的产品。
package factorymethod
import "log"
//Operation 运算结构体
type Operation interface {
GetResult(numberA, numberB float64) float64
}
//OperationAdd 加法运算
type OperationAdd struct {
}
//GetResult 获取加法结果
func (*OperationAdd) GetResult(numberA, numberB float64) float64 {
return numberA + numberB
}
//OperationSub 减法运算
type OperationSub struct {
}
//GetResult 获取减法结果
func (*OperationSub) GetResult(numberA, numberB float64) float64 {
return numberA - numberB
}
//OperationMul 乘法运算
type OperationMul struct {
}
//GetResult 获取乘法结果
func (*OperationMul) GetResult(numberA, numberB float64) float64 {
return numberA * numberB
}
//OperationDiv 除法运算
type OperationDiv struct {
}
//GetResult 获取除法结果
func (*OperationDiv) GetResult(numberA, numberB float64) float64 {
if numberB == 0 {
log.Fatal("除数不能为0")
}
return numberA / numberB
}
//IFactory 工厂方法
type IFactory interface {
CreateOperation()
}
//AddFactory 专门负责生产“+”的工厂
type AddFactory struct {
}
//CreateOperation 创建+法实例
func (*AddFactory) CreateOperation() Operation {
return &OperationAdd{}
}
//SubFactory 专门负责生产“-”的工厂
type SubFactory struct {
}
//CreateOperation 创建-法实例
func (*SubFactory) CreateOperation() Operation {
return &OperationSub{}
}
//MulFactory 专门负责生产“*”的工厂
type MulFactory struct {
}
//CreateOperation 创建*法实例
func (*MulFactory) CreateOperation() Operation {
return &OperationMul{}
}
//DivFactory 专门负责生产“/”的工厂
type DivFactory struct {
}
//CreateOperation 创建*法实例
func (*DivFactory) CreateOperation() Operation {
return &OperationDiv{}
}
策略模式
定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换
在有多种算法相似的情况下,使用 if...else 所带来的复杂和难以维护。
package strategy
type Strategy interface {
doOperation(a, b int) int
}
type OperationAdd struct {
}
type OperationSub struct {
}
type OperationMul struct {
}
func (*OperationAdd) doOperation(a, b int) int {
return a + b
}
func (*OperationSub) doOperation(a, b int) int {
return a - b
}
func (*OperationMul) doOperation(a, b int) int {
return a * b
}
type Context struct {
strategy Strategy
}
func (c *Context) executeStrategy(a, b int) int {
return c.strategy.doOperation(a, b)
}
装饰模式
动态地给一个对象添加一些额外的职责。就增加功能来说,装饰器模式相比生成子类更为灵活。一般的,我们为了扩展一个类经常使用继承方式实现,由于继承为类引入静态特征,并且随着扩展功能的增多,子类会很膨胀.将具体功能职责划分,同时继承装饰者模式。
package decorator
import "fmt"
//产品形状接口
type Shape interface {
draw()
}
//Circle类
type Circle struct {
}
//Rectangle类
type Rectangle struct {
}
//draw Circle
func (*Circle) draw() {
fmt.Println("Shape: Circle")
}
//draw Rectangle
func (*Rectangle) draw() {
fmt.Println("Shape: Rectangle")
}
//装饰器
type ShapeDecorator struct {
shape Shape
}
//具体装饰对象
type RedShapeDecorator struct {
shape Shape
}
func (rsd *RedShapeDecorator) draw() {
rsd.shape.draw()
rsd.setRedBorder()
rsd.setRedWidth()
}
//装饰的操作
func (rsd *RedShapeDecorator) setRedBorder() {
fmt.Println("Border Color: Red")
}
func (rsd *RedShapeDecorator) setRedWidth() {
fmt.Println("Red Width: 40")
}
package decorator
import (
"fmt"
"testing"
)
func TestDecoratorMethod(t *testing.T) {
//具体操作
csd := new(RedShapeDecorator)
//操作对象为Circle
csd.shape = new(Circle)
//使用装饰
rsdc := new(ShapeDecorator)
//装饰对象为具体操作的产品
rsdc.shape = csd
//draw()
csd.draw()
fmt.Println("========")
//装饰另一个产品
rsd := new(RedShapeDecorator)
rsd.shape = new(Rectangle)
rsdr := new(ShapeDecorator)
rsdr.shape = rsd
rsd.draw()
}
单例模式
这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。
package singleton
import "sync"
//单例模式
type Singleton struct {
}
var singleton *Singleton
var once sync.Once
func GetInstance() *Singleton {
//双重加锁机制
once.Do(func() {
singleton = &Singleton{}
})
return singleton
}
//test
package singleton
import (
"testing"
)
func TestSingleton(t *testing.T) {
ins1 := GetInstance()
ins2 := GetInstance()
if ins1 != ins2 {
t.Fatal("singleton test fail")
}
ins3 := new(Singleton)
ins4 := new(Singleton)
if ins3 == ins4 {
t.Fatal("test fail")
}
}
代理模式
一个类代表另一个类的功能。这种类型的设计模式属于结构型模式。在代理模式中,我们创建具有现有对象的对象,以便向外界提供功能接口。
package proxy
import (
"fmt"
"os/exec"
)
//代理模式 一个类代表另一个类的功能
type Image interface {
display()
}
type RealImage struct {
filename string
}
func (r *RealImage) display() {
fmt.Println("display", r.filename)
cmd := exec.Command("display", r.filename)
cmd.Run()
}
type ProxyImage struct {
realImage *RealImage
}
func (p *ProxyImage) display() {
p.realImage.display()
}
package proxy
import "testing"
func TestProxyMethod(t *testing.T) {
image := new(ProxyImage)
image.realImage = &RealImage{
"./1.png",
}
image.display()
}