本文来自正在规划的Go语言&云原生自我提升系列,欢迎关注后续文章。
GoF(Gang of Four),GoF都是知名的软件工程师并且在面向对象编程和软件设计领域具有丰富的经验。他们于上世纪90年代一起在IBM的T.J.华生研究中心工作。这四人也即Erich Gamma、Richard Helm、Ralph Johnson和John Vlissides于1994年出版了一本《设计模式- 可复用的面向对象软件元素》。此后在软件工程领域影响深远,以致于软件工程师们大量讨论和使用书中所介绍的23种设计模式。
Go语言并没有将自己定位成面向对象的编程语言,但讨论23种设计模式对我们理解它也会有一定的帮助。
23种设计模式分为三大类:
-
创建型模式(Creational Patterns):这些模式主要关注对象创建机制,针对具体场景选择对应方式创建对象。包含有5种设计模式:
- 单例模式(Singleton Pattern)
- 工厂方法模式(Factory Method Pattern)
- 抽象工厂模式(Abstract Factory Pattern)
- 建造者模式(Builder Pattern)
- 原型模式(Prototype Pattern)
-
结构型模式(Structural Patterns):这些模式主要关注对象的组合,通过单独的对象或类形成更大型的结构。包含7种设计模式:
- 适配器模式(Adapter Pattern)
- 桥接模式(Bridge Pattern)
- 组合模式(Composite Pattern)
- 装饰器模式(Decorator Pattern)
- 外观模式(Facade Pattern)
- 享元模式(Flyweight Pattern)
- 代理模式(Proxy Pattern)
-
行为型模式(Behavioral Patterns):这些模式关注的是对象间的通信,定义对象的交互方式及分配责任。包含11种设计模式:
- 责任链模式(Chain of Responsibility Pattern)
- 命令模式(Command Pattern)
- 解释器模式(Interpreter Pattern)
- 迭代器模式(Iterator Pattern)
- 中介者模式(Mediator Pattern)
- 备忘录模式(Memento Pattern)
- 观察者模式(Observer Pattern)
- 状态模式(State Pattern)
- 策略模式(Strategy Pattern)
- 模板方法模式(Template Method Pattern)
- 访问者模式(Visitor Pattern)
单例模式(Singleton Pattern)
单例模式可对包级变量仅初始化一次,然后在整个应用中供其它代码调用。
package singleton
import (
"sync"
)
type singleton struct {
// your singleton fields here
}
var (
instance *singleton
once sync.Once
)
// GetInstance returns the singleton instance
func GetInstance() *singleton {
once.Do(func() {
instance = &singleton{}
})
return instance
}
工厂方法模式(Factory Method Pattern)
工厂方法模式可通过返回接口的函数来实现,然后按需对接口做不同实现。
package factory
type Product interface {
GetName() string
}
type ProductA struct{}
func (p *ProductA) GetName() string {
return "Product A"
}
type ProductB struct{}
func (p *ProductB) GetName() string {
return "Product B"
}
type Factory interface {
CreateProduct() Product
}
type FactoryA struct{}
func (f *FactoryA) CreateProduct() Product {
return &ProductA{}
}
type FactoryB struct{}
func (f *FactoryB) CreateProduct() Product {
return &ProductB{}
}
抽象工厂模式(Abstract Factory Pattern)
抽象工厂模式可通过接口可创建相关对象的工厂实现。
package abstract_factory
type AbstractFactory interface {
CreateProductA() ProductA
CreateProductB() ProductB
}
type ConcreteFactory1 struct{}
func (f *ConcreteFactory1) CreateProductA() ProductA {
return &ConcreteProductA1{}
}
func (f *ConcreteFactory1) CreateProductB() ProductB {
return &ConcreteProductB1{}
}
type ConcreteFactory2 struct{}
func (f *ConcreteFactory2) CreateProductA() ProductA {
return &ConcreteProductA2{}
}
func (f *ConcreteFactory2) CreateProductB() ProductB {
return &ConcreteProductB2{}
}
type ProductA interface {
GetName() string
}
type ConcreteProductA1 struct{}
func (p *ConcreteProductA1) GetName() string {
return "ConcreteProductA1"
}
type ConcreteProductA2 struct{}
func (p *ConcreteProductA2) GetName() string {
return "ConcreteProductA2"
}
type ProductB interface {
GetName() string
}
type ConcreteProductB1 struct{}
func (p *ConcreteProductB1) GetName() string {
return "ConcreteProductB1"
}
type ConcreteProductB2 struct{}
func (p *ConcreteProductB2) GetName() string {
return "ConcreteProductB2"
}
建造者模式(Builder Pattern)
建造者模式可使用结构体加构建过程中进行设置的可选参数来实现。
package builder
type Product struct {
Name string
Version int
}
type Builder interface {
SetName(name string) Builder
SetVersion(version int) Builder
Build() *Product
}
type ConcreteBuilder struct {
product *Product
}
func (b *ConcreteBuilder) SetName(name string) Builder {
b.product.Name = name
return b
}
func (b *ConcreteBuilder) SetVersion(version int) Builder {
b.product.Version = version
return b
}
func (b *ConcreteBuilder) Build() *Product {
return b.product
}
原型模式(Prototype Pattern)
原型模式可通过返回已有对象拷贝的克隆方法实现。
package prototype
type Prototype interface {
Clone() Prototype
GetName() string
}
type ConcretePrototype struct {
name string
}
func (p *ConcretePrototype) Clone() Prototype {
return &ConcretePrototype{name: p.name}
}
func (p *ConcretePrototype) GetName() string {
return p.name
}
适配器模式(Adapter Pattern)
适配器模式可使用封装已有类型的接口来与其它接口相兼容。
package adapter
type Adaptee interface {
SpecificRequest() string
}
type ConcreteAdaptee struct{}
func (a *ConcreteAdaptee) SpecificRequest() string {
return "adaptee method called"
}
type Target interface {
Request() string
}
type Adapter struct {
adaptee Adaptee
}
func (a *Adapter) Request() string {
return a.adaptee.SpecificRequest()
}
桥接模式(Bridge Pattern)
桥接模式使用接口来分离抽象及其实现。
package bridge
type Abstraction interface {
Operation() string
}
type ConcreteAbstraction struct {
implementation Implementation
}
func (a *ConcreteAbstraction) Operation() string {
return a.implementation.OperationImplementation()
}
type Implementation interface {
OperationImplementation() string
}
type ConcreteImplementationA struct{}
func (i *ConcreteImplementationA) OperationImplementation() string {
return "ConcreteImplementationA"
}
type ConcreteImplementationB struct{}
func (i *ConcreteImplementationB) OperationImplementation() string {
return "ConcreteImplementationB"
}
组合模式(Composite Pattern)
组合模式通过可表示单个对象及对象组的树状接口结构实现。
package composite
type Component interface {
Operation() string
}
type Composite struct {
components []Component
}
func (c *Composite) Add(component Component) {
c.components = append(c.components, component)
}
func (c *Composite) Remove(component Component) {
for i, comp := range c.components {
if comp == component {
c.components = append(c.components[:i], c.components[i+1:]...)
break
}
}
}
func (c *Composite) Operation() string {
result := ""
for _, component := range c.components {
result += component.Operation() + "\n"
}
return result
}
type Leaf struct{}
func (l *Leaf) Operation() string {
return "Leaf operation"
}
装饰器模式(Decorator Pattern)
装饰器模式可通过在接口中封装其它接口并添加行为来实现。
package decorator
type Component interface {
Operation() string
}
type ConcreteComponent struct{}
func (c *ConcreteComponent) Operation() string {
return "ConcreteComponent operation"
}
type Decorator interface {
Operation() string
}
type ConcreteDecoratorA struct {
component Component
}
func (d *ConcreteDecoratorA) Operation() string {
return "ConcreteDecoratorA operation " + d.component.Operation()
}
type ConcreteDecoratorB struct {
component Component
}
func (d *ConcreteDecoratorB) Operation() string {
return "ConcreteDecoratorB operation " + d.component.Operation()
}
外观模式(Facade Pattern)
外观模式使用隐藏多个子系统复杂度的包级函数来实现。
package facade
type SubsystemA interface {
OperationA() string
}
type ConcreteSubsystemA struct{}
func (s *ConcreteSubsystemA) OperationA() string {
return "SubsystemA operation"
}
type SubsystemB interface {
OperationB() string
}
type ConcreteSubsystemB struct{}
func (s *ConcreteSubsystemB) OperationB() string {
return "SubsystemB operation"
}
type Facade interface {
Operation() string
}
type ConcreteFacade struct {
subsystemA SubsystemA
subsystemB SubsystemB
}
func (f *ConcreteFacade) Operation() string {
result := "Facade operation:\n"
result += f.subsystemA.OperationA() + "\n"
result += f.subsystemB.OperationB()
return result
}
享元模式(Flyweight Pattern)
享元模式在Go语言中可使用在应用中多处共享的对象缓存来实现。
package flyweight
type Flyweight interface {
Operation() string
}
type ConcreteFlyweight struct {
state string
}
func (f *ConcreteFlyweight) Operation() string {
return "ConcreteFlyweight operation with state " + f.state
}
type FlyweightFactory struct {
flyweights map[string]*ConcreteFlyweight
}
func (f *FlyweightFactory) GetFlyweight(state string) Flyweight {
if flyweight, ok := f.flyweights[state]; ok {
return flyweight
} else {
flyweight := &ConcreteFlyweight{state: state}
f.flyweights[state] = flyweight
return flyweight
}
}
代理模式(Proxy Pattern)
Go语言中代理模式可使用实现了接口的结构体并将方法调用传递给对象来实现。
package proxy
type RealSubject struct{}
func (r *RealSubject) Operation() string {
return "RealSubject operation"
}
type Proxy struct {
realSubject *RealSubject
}
func (p *Proxy) Operation() string {
if p.realSubject == nil {
p.realSubject = &RealSubject{}
}
return "Proxy operation: " + p.realSubject.Operation()
}
责任链模式(Chain of Responsibility Pattern)
Go语言中责任链模式可使用沿请求链传递的handler列表实现。
package chain_of_responsibility
type Handler interface {
SetNext(handler Handler) Handler
Handle(request string) string
}
type ConcreteHandlerA struct {
nextHandler Handler
}
func (h *ConcreteHandlerA) SetNext(handler Handler) Handler {
h.nextHandler = handler
return handler
}
func (h *ConcreteHandlerA) Handle(request string) string {
if request == "A" {
return "ConcreteHandlerA handled request A"
} else if h.nextHandler != nil {
return h.nextHandler.Handle(request)
} else {
return "ConcreteHandlerA can't handle the request"
}
}
type ConcreteHandlerB struct {
nextHandler Handler
}
func (h *ConcreteHandlerB) SetNext(handler Handler) Handler {
h.nextHandler = handler
return handler
}
func (h *ConcreteHandlerB) Handle(request string) string {
if request == "B" {
return "ConcreteHandlerB handled request B"
} else if h.nextHandler != nil {
return h.nextHandler.Handle(request)
} else {
return "ConcreteHandlerB can't handle the request"
}
}
命令模式(Command Pattern)
Go语言中命令模式可使用表示命令的接口实现,由调用者执行这些命令。
package command
type Command interface {
Execute() string
}
type Receiver struct{}
func (r *Receiver) Action() string {
return "Receiver action"
}
type ConcreteCommand struct {
receiver *Receiver
}
func (c *ConcreteCommand) Execute() string {
return "ConcreteCommand executing " + c.receiver.Action()
}
type Invoker struct {
command Command
}
func (i *Invoker) SetCommand(command Command) {
i.command = command
}
func (i *Invoker) ExecuteCommand() string {
return i.command.Execute()
}
解释器模式(Interpreter Pattern)
Go语言中解释器模式可通过表示抽象语法树的结构体及解释该树的方法的组合来实现。
package interpreter
type Context struct {
input string
output string
}
type AbstractExpression interface {
Interpret(context *Context) error
}
type TerminalExpression struct{}
func (t *TerminalExpression) Interpret(context *Context) error {
context.output += "Terminal expression "
return nil
}
type NonterminalExpression struct{}
func (n *NonterminalExpression) Interpret(context *Context) error {
context.output += "Nonterminal expression "
return nil
}
迭代器模式(Iterator Pattern)
Go语言中迭代器模式可使用定义了next方法的接口来实现,不同集合的接口实现不同。
package iterator
type Aggregate interface {
CreateIterator() Iterator
}
type ConcreteAggregate struct {
items []string
}
func (c *ConcreteAggregate) CreateIterator() Iterator {
return &ConcreteIterator{items: c.items}
}
type Iterator interface {
Next() (string, bool)
}
type ConcreteIterator struct {
index int
items []string
}
func (c *ConcreteIterator) Next() (string, bool) {
if c.index >= len(c.items) {
return "", false
}
item := c.items[c.index]
c.index++
return item, true
}
中介者模式(Mediator Pattern)
Go语言中中介者模式可使用作为不同对象中介的结构体来实现,它帮助完成对象间的通信。
package mediator
type Mediator interface {
Notify(component Component)
}
type ConcreteMediator struct {
components []Component
}
func (m *ConcreteMediator) Notify(component Component) {
for _, comp := range m.components {
if comp != component {
comp.Receive(component.Send())
}
}
}
type Component interface {
Send() string
Receive(message string)
}
type ConcreteComponentA struct {
mediator Mediator
}
func (c *ConcreteComponentA) Send() string {
return "ConcreteComponentA sending message"
}
func (c *ConcreteComponentA) Receive(message string) {
c.mediator.Notify(c)
}
type ConcreteComponentB struct {
mediator Mediator
}
func (c *ConcreteComponentB) Send() string {
return "ConcreteComponentB sending message"
}
func (c *ConcreteComponentB) Receive(message string) {
c.mediator.Notify(c)
}
备忘录模式(Memento Pattern)
Go语言中备忘录模式可使用表示具体时间点对象状态以及管理这些状态的结构体来实现。
package memento
type Memento struct {
state string
}
func (m *Memento) GetState() string {
return m.state
}
type Originator struct {
state string
}
func (o *Originator) SetState(state string) {
o.state = state
}
func (o *Originator) SaveState() *Memento {
return &Memento{state: o.state}
}
func (o *Originator) RestoreState(m *Memento) {
o.state = m.GetState()
}
type Caretaker struct {
memento *Memento
}
func (c *Caretaker) SetMemento(m *Memento) {
c.memento = m
}
func (c *Caretaker) GetMemento() *Memento {
return c.memento
}
观察者模式(Observer Pattern)
Go语言中观察者模式可使用一组表示被观察者和观察者的接口来实现。
package observer
type Subject interface {
Attach(observer Observer)
Detach(observer Observer)
Notify()
}
type ConcreteSubject struct {
observers []Observer
state string
}
func (s *ConcreteSubject) Attach(observer Observer) {
s.observers = append(s.observers, observer)
}
func (s *ConcreteSubject) Detach(observer Observer) {
for i, obs := range s.observers {
if obs == observer {
s.observers = append(s.observers[:i], s.observers[i+1:]...)
break
}
}
}
func (s *ConcreteSubject) Notify() {
for _, obs := range s.observers {
obs.Update(s)
}
}
type Observer interface {
Update(subject Subject)
}
type ConcreteObserverA struct {
state string
}
func (o *ConcreteObserverA) Update(subject Subject) {
if subject.(*ConcreteSubject).state == "A" {
o.state = "ConcreteObserverA updated"
}
}
type ConcreteObserverB struct {
state string
}
func (o *ConcreteObserverB) Update(subject Subject) {
if subject.(*ConcreteSubject).state == "B" {
o.state = "ConcreteObserverB updated"
}
}
状态模式(State Pattern)
Go语言中状态模式可使用一组表示对象不同状态的接口,以及管理这些状态转换的上下文来实现。
package state
type Context struct {
state State
}
func (c *Context) SetState(state State) {
c.state = state
}
func (c *Context) Request() string {
return c.state.Handle()
}
type State interface {
Handle() string
}
type ConcreteStateA struct{}
func (s *ConcreteStateA) Handle() string {
return "ConcreteStateA handling"
}
type ConcreteStateB struct{}
func (s *ConcreteStateB) Handle() string {
return "ConcreteStateB handling"
}
策略模式(Strategy Pattern)
Go语言中策略模式可使用表示不同算法或行为的接口以及实现这些接口的结构体实现。
package strategy
type Context struct {
strategy Strategy
}
func (c *Context) SetStrategy(strategy Strategy) {
c.strategy = strategy
}
func (c *Context) ExecuteStrategy() string {
return c.strategy.Execute()
}
type Strategy interface {
Execute() string
}
type ConcreteStrategyA struct{}
func (s *ConcreteStrategyA) Execute() string {
return "ConcreteStrategyA executing"
}
type ConcreteStrategyB struct{}
func (s *ConcreteStrategyB) Execute() string {
return "ConcreteStrategyB executing"
}
模板方法模式(Template Method Pattern)
Go语言中模板方法模式可使用定义了模板方法的接口来实现,不同行为对接口做不同的实现。
package template_method
type AbstractClass interface {
PrimitiveOperation1() string
PrimitiveOperation2() string
TemplateMethod() string
}
type ConcreteClass struct{}
func (c *ConcreteClass) PrimitiveOperation1() string {
return "PrimitiveOperation1 implementation"
}
func (c *ConcreteClass) PrimitiveOperation2() string {
return "PrimitiveOperation2 implementation"
}
func (c *ConcreteClass) TemplateMethod() string {
result := c.PrimitiveOperation1()
result += c.PrimitiveOperation2()
return result
}
访问者模式(Visitor Pattern)
Go语言中访问者模式使用表示访问者及被访问者的接口以及接收访问者并对被访问对象执行操作的方法实现。
package visitor
type Element interface {
Accept(visitor Visitor) string
}
type ConcreteElementA struct{}
func (e *ConcreteElementA) Accept(visitor Visitor) string {
return visitor.VisitConcreteElementA(e)
}
type ConcreteElementB struct{}
func (e *ConcreteElementB) Accept(visitor Visitor) string {
return visitor.VisitConcreteElementB(e)
}
type Visitor interface {
VisitConcreteElementA(e *ConcreteElementA) string
VisitConcreteElementB(e *ConcreteElementB) string
}
type ConcreteVisitor struct{}
func (v *ConcreteVisitor) VisitConcreteElementA(e *ConcreteElementA) string {
return "ConcreteVisitor visiting ConcreteElementA"
}
func (v *ConcreteVisitor) VisitConcreteElementB(e *ConcreteElementB) string {
return "ConcreteVisitor visiting ConcreteElementB"
}