【Golang】使用接口模式还是组合设计模式

在实际应用过程中发现,有时候需要重写一些库中的函数,以满足当前需求。总结为以下几点,当然只是个人见解,欢迎讨论。

为了节省篇幅以下情况均为库不能满足当前需求的条件下

如果库中为struct,我们只需要定义一个struct,并包含库中的struct(注意在不存在名称冲突的情况下应该为匿名struct)

在使用我们自定义的struct的时候,对于那些符合我们工程的函数,我们不用重写,这个时候就体现了struct中匿名字段的好处了,我们在调用这些没有重写的方法时,就像在调用自己定义的方法一样(这就是Go的组合设计模式)。

如果我们需要重写一些方法,我们直接使用当前结构体作为receiver,千万不要直接去修改库文件函数(这个错误就不用说了)。在调用的时候和调用库函数一样,注意这里和其他语言的函数重载不是一回事,有兴趣的去搜索"无闻"的相关教程。

一些情况下我们可能会在库函数和自定义函数之间切换,这个时候我们可以明确表明调用那一个函数函数:例如如果调用库函数,使用product.Origin.A();使用自定义函数,直接使用product.A()。如果想做的灵活一些,就要使用接口了,通过参数传递的类型不同,'智能'选择调用的方法,后面会讲到。

库文件

package repository

import "fmt"
    
type Origin struct{}
    
func (o Origin) A() {
    fmt.Println("origin->A()")
}
    
func (o Origin) B() {}

project

package project

import "fmt"
    
type product struct {
    repository.Origin
    name string
}
    
func (p product) A() {
    fmt.Println("product->A()")
}

误区:

  • 如果你想通过接口来规范开发,这个时候需要注意,接口定义的方法需要和库文件的函数列表一致,一定不能增加方法。对于大部分函数都和库函数一致的情况下,不要把库函数copy一遍。尽量使用组合设计模式,因为我们定义的接口已经被库文件中的自定义类型实现了,使用组合设计模式时,内部字段实现了某个接口,那么这个struct也就实现了这个接口,我们只需要重写一些不符合我们生产环境的函数。在我看来,如果开发环境针对这一功能只有一个具体实现时,完全没有必要使用接口。
  • 如果你已经选择使用接口了,那么一个具体实现中struct中不应该存在接口字段。从功能上讲,你已经实现了这个接口,根本不用明面声明我实现了这个接口。在这种情况下,这个接口字段往往没有被使用。
  • 如果两个结构体都实现了我们定义的接口,这种情况适合灵活的切换实现。我们只需要在两个结构体上端设计一个'管理节点',包含接口字段,这样任何实现了该接口的实例,都可以赋值给这个接口字段。比如发工资这种情况,所有员工都有工资,由于经理和职员存在差异,这样我们就可以通过职位切换实现。

你可能感兴趣的:(【Golang】使用接口模式还是组合设计模式)