Go 语言是一种静态类型、编译型的编程语言,它以其简洁、高效和并发支持而闻名。Go 语言中的接口(Interface)是一种非常强大的特性,它允许我们以一种类型安全的方式编写灵活的代码。面向接口编程是一种编程范式,它强调使用接口而不是具体实现来设计和构建软件系统。
以下是一些面向接口编程的关键概念和实践:
1. 定义接口:接口是一组方法签名的集合,它定义了一组行为,但不需要实现这些行为。在 Go 中,接口是隐式实现的,这意味着如果一个类型提供了接口中定义的所有方法,那么它就实现了该接口。
type MyInterface interface {
DoSomething()
DoAnotherThing()
}
2. 实现接口:任何类型只要实现了接口中定义的所有方法,就自动实现了该接口。
type MyStruct struct {
// 结构体字段
}
func (m *MyStruct) DoSomething() {
// 实现方法
}
func (m *MyStruct) DoAnotherThing() {
// 实现方法
}
3. 使用接口变量:你可以使用接口变量来存储实现了特定接口的任何类型的值。
var myInterface MyInterface
myInterface = &MyStruct{}
myInterface.DoSomething()
4. 多态:接口允许你编写多态代码,即同一个接口可以用于不同的类型。
type AnotherStruct struct {
// 另一个结构体
}
func (a *AnotherStruct) DoSomething() {
// 另一个实现
}
func (a *AnotherStruct) DoAnotherThing() {
// 另一个实现
}
// 可以使用同一个接口变量来引用不同类型的实例
anotherInterface := &AnotherStruct{}
anotherInterface.DoSomething()
5. 依赖注入:接口可以用来实现依赖注入,这是一种减少代码耦合性的技术。
func NewService(dependency MyInterface) *Service {
return &Service{
dependency: dependency,
}
}
6. 接口作为函数参数:你可以将接口作为函数参数,这样函数就可以接受实现了该接口的任何类型的实例。
func DoSomethingWithInterface(i MyInterface) {
i.DoSomething()
}
7. 接口的空值检查:在 Go 中,接口变量可以持有一个具体的值或者是一个 nil 值。在使用接口变量之前,应该检查它是否为 nil。
if myInterface != nil {
myInterface.DoSomething()
}
面向接口编程可以帮助你编写更灵活、更易于测试和维护的代码。通过定义清晰的接口,你可以更容易地替换组件的实现,同时也能够编写出更通用的代码。
-
- 面向接口的编程
- 定义结构体
- 面向接口的编程
type MetadataFactroy struct {
*factrydb.FacatroyDb
iface.IFactroyDb //接口
cfg *ichubconfig.IchubConfig `json:"-"`
}
func Defult() *MetadataFactroy {
var metaFactroy = &MetadataFactroy{
FacatroyDb: factrydb.NewFacatroyDb(),
cfg: ichubconfig.FindBeanIchubConfig(),
}
metaFactroy.DbClientDto = dbpkgdto.Cfg.ReadIchubDb()
return metaFactroy.Init()
}
-
-
- 初始化接口
-
func (this *MetadataFactroy) Init() *MetadataFactroy {
if this.IFactroyDb == nil {
if this.IfMysql() {
this.IFactroyDb = mysql.NewFactroyMysql()
}
if this.IfCockdb() {
this.IFactroyDb = cockdb.NewFactroyCockRoarch()
}
if this.IfPostgres() {
this.IFactroyDb = postgres.NewFactroyPostgres()
}
if this.IfMedusa() {
this.IFactroyDb = postgres.NewFactroyPostgres()
}
}
this.IFactroyDb.SetImetaCtx(this)
this.IFactroyDb.SetDbClientDto(this.DbClientDto)
this.IFactroyDb.SetTableName(this.TableName)
return this
}
func (this *MetadataFactroy) FindIFactroyDb() iface.IFactroyDb {
return this.Init().IFactroyDb
}
-
-
- 接口使用
-
func (this *MetadataFactroy) findMetaTableDto() *dbpkgdto.MetaTableDto {
var idbf = this.FindIFactroyDb()
var metaTable = dbpkgdto.NewMetaTableDto()
metaTable.Columns, _ = idbf.FindCols()
metaTable.TableSchema = this.DbClientDto.Dbname
metaTable.TableName = this.TableName
metaTable.TableExist = len(metaTable.Columns) > 0
this.BuildGoFields(metaTable)
metaTable.PkInfo = dbpkgdto.NewMetaPkInfo()
metaTable.PkInfo.TypeName = idbf.FindFactryDto().PkeyType
metaTable.PkInfo.PkName = idbf.FindFactryDto().Pkey
metaTable.PkInfo.ColName = stringutils.Camel2Case(metaTable.PkInfo.PkName)
return metaTable
}
-
-
- 接口定义
-
type IFactroyDb interface {
IniDb(conn string) (dbinst *gorm.DB)
SetImetaCtx(imetaCtx ImetaCtx)
ImetaCtx() ImetaCtx
String() string
ToString() string
BuildModel() *dto2.ModeFactors
MakeModelProto() *list.List
MakeModelProtoBody(columns *[]dto2.MetaColDto) *list.List
FindPgPkey(table string) []dto2.MetaPkInfo
FindColumns() (*[]dto2.MetaColDto, error)
FindCols() ([]dto2.MetaColDto, error)
FindTableComment()
FindTables() []dto2.MetaTableDto
FindFactryDto() *dto2.FacatroyDto
SetDbClientDto(dto *baseconfig.DbClientDto)
SetTableName(tablename string)
FindMetadata(table string) *dto2.MetaTableDto
FindFields(table string, fields string) string
}