Go 语言实现模版方法设计模式

简介: 在Go语言中,可以使用接口和组合来实现模板方法模式。模板方法模式是一种行为设计模式,它定义了一个算法的骨架,将一些步骤的实现延迟到子类中。下面是一个示例代码,演示了如何在Go中实现模板方法模式

实现步骤

在Go语言中,可以使用接口和组合来实现模板方法模式。模板方法模式是一种行为设计模式,它定义了一个算法的骨架,将一些步骤的实现延迟到子类中。下面是一个示例代码,演示了如何在Go中实现模板方法模式:

package main

import "fmt"

// AbstractClass 定义抽象类
type AbstractClass interface {
   
    TemplateMethod()
    PrimitiveOperation1()
    PrimitiveOperation2()
}

// ConcreteClass1 实现具体的子类1
type ConcreteClass1 struct{
   }

func (c *ConcreteClass1) TemplateMethod() {
   
    fmt.Println("ConcreteClass1 TemplateMethod")
    c.PrimitiveOperation1()
    c.PrimitiveOperation2()
}

func (c *ConcreteClass1) PrimitiveOperation1() {
   
    fmt.Println("ConcreteClass1 PrimitiveOperation1")
}

func (c *ConcreteClass1) PrimitiveOperation2() {
   
    fmt.Println("ConcreteClass1 PrimitiveOperation2")
}

// ConcreteClass2 实现具体的子类2
type ConcreteClass2 struct{
   }

func (c *ConcreteClass2) TemplateMethod() {
   
    fmt.Println("ConcreteClass2 TemplateMethod")
    c.PrimitiveOperation1()
    c.PrimitiveOperation2()
}

func (c *ConcreteClass2) PrimitiveOperation1() {
   
    fmt.Println("ConcreteClass2 PrimitiveOperation1")
}

func (c *ConcreteClass2) PrimitiveOperation2() {
   
    fmt.Println("ConcreteClass2 PrimitiveOperation2")
}

func main() {
   
    // 使用具体的子类1
    class1 := &ConcreteClass1{
   }
    class1.TemplateMethod()

    fmt.Println()

    // 使用具体的子类2
    class2 := &ConcreteClass2{
   }
    class2.TemplateMethod()
}

在上述示例中,AbstractClass 定义了一个抽象类,其中 TemplateMethod 是模板方法,它定义了算法的骨架,调用了两个抽象方法 PrimitiveOperation1PrimitiveOperation2ConcreteClass1ConcreteClass2 是具体的子类,它们实现了抽象类的方法。

通过使用接口和组合,我们可以在抽象类中定义模板方法并调用子类的抽象方法,从而实现模板方法模式。在示例中,TemplateMethod 是抽象类中的模板方法,它调用了 PrimitiveOperation1PrimitiveOperation2 方法,具体的子类根据自己的需求来实现这些抽象方法。

运行上述代码将输出以下结果:

ConcreteClass1 TemplateMethod
ConcreteClass1 PrimitiveOperation1
ConcreteClass1 PrimitiveOperation2

ConcreteClass2 TemplateMethod
ConcreteClass2 PrimitiveOperation1
ConcreteClass2 PrimitiveOperation2

可以看到,模板方法 TemplateMethod 在抽象类中定义,并且调用了具体子类实现的抽象方法 PrimitiveOperation1PrimitiveOperation2。这样,我们就实现了模板方法模式,通过基类调用子类的抽象方法来完成算法的定制化。

实现调用父类的公共方法

以上方法实现了子类调用自己的方法,下面介绍如何类似Java一样调用父类的公共方法

实现步骤

在 Go 语言中,由于语言特性的限制,无法像 Java 中那样直接调用父类的公共方法并间接调用子类实现的抽象方法。Go 语言中没有类继承的概念,只有接口和组合的方式。但是我们可以通过回调函数的方式来实现类似的效果。下面是一个优化后的示例代码:

package main

import "fmt"

// AbstractClass 定义抽象类
type AbstractClass struct {
   
    PrimitiveOperation1 func()
    PrimitiveOperation2 func()
}

// TemplateMethod 定义模板方法
func (ac *AbstractClass) TemplateMethod() {
   
    fmt.Println("AbstractClass TemplateMethod")
    ac.PrimitiveOperation1()
    ac.PrimitiveOperation2()
}

// ConcreteClass1 实现具体的子类1
type ConcreteClass1 struct {
   
    AbstractClass
}

func NewConcreteClass1() *ConcreteClass1 {
   
    cc := &ConcreteClass1{
   }
    cc.PrimitiveOperation1 = cc.concreteOperation1
    cc.PrimitiveOperation2 = cc.concreteOperation2
    return cc
}

func (cc *ConcreteClass1) concreteOperation1() {
   
    fmt.Println("ConcreteClass1 concreteOperation1")
}

func (cc *ConcreteClass1) concreteOperation2() {
   
    fmt.Println("ConcreteClass1 concreteOperation2")
}

// ConcreteClass2 实现具体的子类2
type ConcreteClass2 struct {
   
    AbstractClass
}

func NewConcreteClass2() *ConcreteClass2 {
   
    cc := &ConcreteClass2{
   }
    cc.PrimitiveOperation1 = cc.concreteOperation1
    cc.PrimitiveOperation2 = cc.concreteOperation2
    return cc
}

func (cc *ConcreteClass2) concreteOperation1() {
   
    fmt.Println("ConcreteClass2 concreteOperation1")
}

func (cc *ConcreteClass2) concreteOperation2() {
   
    fmt.Println("ConcreteClass2 concreteOperation2")
}

func main() {
   
    // 使用具体的子类1
    class1 := NewConcreteClass1()
    class1.TemplateMethod()

    fmt.Println()

    // 使用具体的子类2
    class2 := NewConcreteClass2()
    class2.TemplateMethod()
}

在上述代码中,我们将 AbstractClass 定义为一个结构体,其中的 PrimitiveOperation1PrimitiveOperation2 字段是回调函数,用于指向子类实现的具体方法。在具体的子类中,我们通过创建新的结构体并设置回调函数来实现类似于模板方法模式的效果。

运行上述代码将输出以下结果:

AbstractClass TemplateMethod
ConcreteClass1 concreteOperation1
ConcreteClass1 concreteOperation2

AbstractClass TemplateMethod
ConcreteClass2 concreteOperation1
ConcreteClass2 concreteOperation2

可以看到,通过回调函数的方式,我们实现了类似于模板方法模式的效果。在抽象类的模板方法中调用了子类实现的具体方法。

请注意,这种方式在 Go 语言中是一种常见的模式,可以通过回调函数来实现类似于模板方法模式的行为。虽然不同于 Java 中的继承和抽象方法的调用方式,但在 Go 语言中,通过组合和回调函数可以实现类似的效果。

相关文章
|
21天前
|
存储 Go 索引
go语言中数组和切片
go语言中数组和切片
34 7
|
21天前
|
Go 开发工具
百炼-千问模型通过openai接口构建assistant 等 go语言
由于阿里百炼平台通义千问大模型没有完善的go语言兼容openapi示例,并且官方答复assistant是不兼容openapi sdk的。 实际使用中发现是能够支持的,所以自己写了一个demo test示例,给大家做一个参考。
|
21天前
|
程序员 Go
go语言中结构体(Struct)
go语言中结构体(Struct)
94 71
|
20天前
|
存储 Go 索引
go语言中的数组(Array)
go语言中的数组(Array)
101 67
|
1天前
|
存储 监控 算法
员工上网行为监控中的Go语言算法:布隆过滤器的应用
在信息化高速发展的时代,企业上网行为监管至关重要。布隆过滤器作为一种高效、节省空间的概率性数据结构,适用于大规模URL查询与匹配,是实现精准上网行为管理的理想选择。本文探讨了布隆过滤器的原理及其优缺点,并展示了如何使用Go语言实现该算法,以提升企业网络管理效率和安全性。尽管存在误报等局限性,但合理配置下,布隆过滤器为企业提供了经济有效的解决方案。
26 8
员工上网行为监控中的Go语言算法:布隆过滤器的应用
|
21天前
|
存储 Go
go语言中映射
go语言中映射
33 11
|
22天前
|
Go 索引
go语言使用索引遍历
go语言使用索引遍历
29 9
|
22天前
|
Go 索引
go语言使用range关键字
go语言使用range关键字
28 7
|
22天前
|
Go 索引
go语言修改元素
go语言修改元素
28 6
|
13天前
|
Go 数据安全/隐私保护 UED
优化Go语言中的网络连接:设置代理超时参数
优化Go语言中的网络连接:设置代理超时参数

热门文章

最新文章