定义一个操作中的算法的骨架,而将实现逻辑步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
可以参考sort.quickSort
的Interface
接口,将Len() int
长度、Less(i, j int) bool
比较、Swap(i, j int)
交换,这些排序的具体实现逻辑交给用户实现。
type Template interface {
initialize()
startPlay()
endPlay()
}
type Game struct {
temp Template
}
// 实现模版方法
func (this *Game) play() {
this.temp.initialize()
this.temp.startPlay()
this.temp.endPlay()
}
type PlayBasketball struct {
Game //继承父类
}
func (this *PlayBasketball) initialize() {
fmt.Println("初始化")
}
func (this *PlayBasketball) startPlay() {
fmt.Println("开始游戏")
}
func (this *PlayBasketball) endPlay() {
fmt.Println("结束游戏")
}
func NewPlayBasketball() *PlayBasketball {
ball := new(PlayBasketball)
ball.Game = Game{temp: ball}
return ball
}
func main() {
ball := NewPlayBasketball()
ball.play()
}
一个空对象取代 NULL 对象实例的检查。Null 对象不是检查空值,而是反应一个不做任何动作的关系。这样的 Null 对象也可以在数据不可用的时候提供默认的行为。
行为接口
type AbstractInterface interface {
isNil() bool
getName() string
}
空对象模式
type AbstractObject struct {
name string
}
// ==== 真实对象 ====
type RealObject struct {
*AbstractObject
}
func (this *RealObject) getName() string {
return this.name
}
func (this *RealObject) isNil() bool {
return false
}
// ==== 空对象 ====
type NilObject struct {
AbstractObject
}
func (this *NilObject) getName() string {
return "nil"
}
func (this *NilObject) isNil() bool {
return true
}
工厂
var names = []string{"bob", "tom"}
func Factory(name string) AbstractInterface {
for i := 0; i < len(names); i++ {
if name == names[i] {
return &RealObject{
&AbstractObject{ name: name },
}
}
}
// 不存在就返回模拟的空对象
return &NilObject{}
}
测试
func Try() {
fact01 := Factory("bob")
fact02 := Factory("tom")
fact03 := Factory("wang")
fmt.Println(fact01.getName())
fmt.Println(fact02.getName())
fmt.Println(fact03.getName())
fmt.Println(fact01.isNil())
fmt.Println(fact02.isNil())
fmt.Println(fact03.isNil())
}
一个系统里面有许多类,它们之间的区别仅在于它们的行为,那么使用策略模式可以动态地让一个对象在许多行为中选择一种行为。
type Strategy interface {
doOperation(operation string)
}
type Operation01 struct {}
func (this *Operation01) doOperation(operation string) {
fmt.Println("策略01:", operation)
}
type Operation02 struct {}
func (this *Operation02) doOperation(operation string) {
fmt.Println("策略02:", operation)
}
type Operation03 struct {}
func (this *Operation03) doOperation(operation string) {
fmt.Println("策略01:", operation)
}
type Context struct {
strategy Strategy
}
func (this *Context) Execute(operation string) {
this.strategy.doOperation(operation)
}
func NewContext(strategy Strategy) *Context {
return &Context{
strategy: strategy,
}
}
// 打开一个锦囊
func Open(option int) Strategy {
switch option {
case 1:
return &Operation01{}
case 2:
return &Operation02{}
case 3:
return &Operation03{}
}
}
func main(){
c1 := NewContext(Open(1))
c1.Execute()
}
单独创建一个对象,作为副本,将副本存在版本中保存修改历史记录。可以想象成git的版本控制,会比较好理解。
// Note 备份
type Memento struct {
state string
}
func (this *Memento) getState() string {
return this.state
}
// 备份历史版本
type MementoVersion struct {
mementos []*Memento
}
func (this *MementoVersion) add(memento *Memento) {
this.mementos = append(this.mementos, memento)
}
func (this *MementoVersion) get(index int) *Memento {
return this.mementos[index]
}
// 正文
type Note struct {
state string
}
func (this *Note) setState(state string) {
this.state = state
}
func (this *Note) getState() {
fmt.Println(this.state)
}
// 创建正文副本
func (this *Note) saveStateToMemento() *Memento {
return &Memento{
state: this.state,
}
}
// 获取正文副本,并将状态保存给当前状态
func (this *Note) getStateFromMemento(memento *Memento) {
this.state = memento.getState()
}
func Try() {
ori := &Note{}
car := &MementoVersion{}
ori.setState("修改第1次")
ori.setState("修改第2次")
car.add(ori.saveStateToMemento())
ori.setState("修改第3次")
car.add(ori.saveStateToMemento())
ori.setState("修改第4次")
ori.getState()
ori.getStateFromMemento(car.get(0)) // 将最初修改的历史版本 拿出来
ori.getState()
ori.getStateFromMemento(car.get(1))
ori.getState()
}
可以想象成JS中的冒泡事件。由首层触发后,会一直向下执行,直到所有节点遍历完毕。
var (
INFO = 1
DEBUG = 2
ERROR = 3
)
// 接口
type BaseLogger interface {
write(message string)
LogMessage(level int, message string)
}
// 父类实现
type AbstractLogger struct {
Level int
nextLogger BaseLogger
}
// 设置下一个logger对象
func (this *AbstractLogger) setNextLogger(nextLogger BaseLogger) {
this.nextLogger = nextLogger
}
// ==== error logger =====
type ErrorLogger struct {
*AbstractLogger
}
func (this *ErrorLogger) write(message string) {
fmt.Println("error:", message)
}
// log输出
func (this *ErrorLogger) LogMessage(level int, message string) {
// 判断传入的level是否相等,相等执行当前对象的write方法
if this.Level == level {
this.write(message)
}
// 判断是否存在下一个节点,下一个存在则调用下一个节点的LogMessage
if this.nextLogger != nil {
this.nextLogger.LogMessage(level, message)
}
}
func NewErrorLogger() *ErrorLogger {
return &ErrorLogger{
&AbstractLogger{
Level: ERROR,
nextLogger: nil,
},
}
}
// ==== console logger =====
type ConsoleLogger struct {
*AbstractLogger
}
func (this *ConsoleLogger) write(message string) {
fmt.Println("info:", message)
}
func (this *ConsoleLogger) LogMessage(level int, message string) {
if this.Level == level {
this.write(message)
}
if this.nextLogger != nil {
this.nextLogger.LogMessage(level, message)
}
}
func NewConsoleLogger() *ConsoleLogger {
return &ConsoleLogger{
&AbstractLogger{
Level: INFO,
nextLogger: nil,
},
}
}
// ==== debug logger =====
type DebeugLogger struct {
*AbstractLogger
}
func (this *DebeugLogger) write(message string) {
fmt.Println("debug:", message)
}
func (this *DebeugLogger) LogMessage(level int, message string) {
if this.Level == level {
this.write(message)
}
if this.nextLogger != nil {
this.nextLogger.LogMessage(level, message)
}
}
func NewDebeugLogger() *DebeugLogger {
return &DebeugLogger{
&AbstractLogger{
Level: DEBUG,
nextLogger: nil,
},
}
}
func GetChainOfLoggers() BaseLogger {
consoleLogger := NewConsoleLogger()
errorLogger := NewErrorLogger()
debugLogger := NewDebeugLogger()
// 设置console下一个节点是errlogger
consoleLogger.setNextLogger(errorLogger)
// 设置errorlogger节点下一个是debuglogger节点
errorLogger.setNextLogger(debugLogger)
// 返回栈定的节点
return consoleLogger
}
func Try() {
loggerChain := GetChainOfLoggers()
// 会将整个链表遍历,找到与参数一箱等的level输出
loggerChain.LogMessage(INFO, "info")
loggerChain.LogMessage(ERROR, "error")
loggerChain.LogMessage(DEBUG, "debug")
}
将一对多转化成了一对一。 2、各个类之间的解耦.
想通过一个中间类来封装多个类中的行为,而又不想生成太多的子类
var chatRoom = &ChatRoom{}
// 中介
type ChatRoom struct {}
func (this *ChatRoom) ShowMessage(user *User, message string) {
fmt.Println(time.Now(), user.getName(), ":", message)
}
type User struct {
name string
}
func (this *User) setName(name string) {
this.name = name
}
func (this *User) getName() string {
return this.name
}
func (this *User) SendMessage(msg string) {
chatRoom.ShowMessage(this, msg)
}
func main() {
user := &User{
name: "张三",
}
user.SendMessage("这是一个测试,看看效果")
}