面试题答案
一键面试代码可读性方面
- 保持接口单一职责
- 每个接口应该专注于一个特定的行为集合。例如,在一个图形绘制系统中,可以定义
Shape
接口,它只负责图形的基本绘制行为:
type Shape interface { Draw() }
- 这样的接口清晰明了,从名字和方法就可以很容易理解其用途,增强了代码的可读性。
- 每个接口应该专注于一个特定的行为集合。例如,在一个图形绘制系统中,可以定义
- 合理命名嵌套接口
- 嵌套接口的命名要能够反映其组合的功能。假设在上述图形绘制系统中,有一个带填充功能的图形接口,可以这样定义:
type Fillable interface { Fill(color string) } type FillableShape interface { Shape Fillable }
FillableShape
这个名字清晰地表明它既具备Shape
的绘制功能,又具备Fillable
的填充功能。
可维护性方面
- 减少接口嵌套深度
- 过深的接口嵌套会使代码难以理解和维护。例如,尽量避免像这样多层嵌套:
type A interface {} type B interface { A } type C interface { B } type D interface { C }
- 这种多层嵌套会让追踪接口行为变得困难。一般来说,嵌套深度不超过两层为宜。如果确实需要更多功能组合,可以通过组合多个简单接口来实现。
- 避免过度抽象
- 不要为了接口嵌套而过度抽象。例如,不要定义一些没有实际意义或很少会被实现的接口只是为了嵌套。假设定义一个
GenericFeature
接口,它没有任何方法,只是为了被其他接口嵌套:
type GenericFeature interface {} type SpecificFeature interface { GenericFeature DoSomething() }
- 这种
GenericFeature
接口没有实际功能,反而增加了代码的复杂性,不利于维护。
- 不要为了接口嵌套而过度抽象。例如,不要定义一些没有实际意义或很少会被实现的接口只是为了嵌套。假设定义一个
扩展性方面
- 设计可插拔的接口
- 接口嵌套应该使得新功能的添加容易。比如在一个电商系统中,有一个
Product
接口:
type Product interface { GetPrice() float64 }
- 如果后续需要添加促销功能,可以定义一个新接口并嵌套到
Product
相关的接口中:
type Promotable interface { GetPromotionPrice() float64 } type PromotableProduct interface { Product Promotable }
- 这样通过接口嵌套,新的促销功能可以很方便地添加到相关产品类型中,而不影响原有的
Product
接口实现。
- 接口嵌套应该使得新功能的添加容易。比如在一个电商系统中,有一个
- 考虑接口的兼容性
- 在进行接口嵌套扩展时,要确保新的嵌套接口与原有的代码兼容。例如,在一个日志系统中,原有的
Logger
接口:
type Logger interface { Log(message string) }
- 如果要添加日志级别功能,新的接口应该以兼容的方式嵌套:
type LeveledLogger interface { Logger SetLevel(level string) }
- 这样原有的只实现了
Logger
接口的代码依然可以正常工作,而新的功能也可以在需要的地方通过实现LeveledLogger
接口来使用。
- 在进行接口嵌套扩展时,要确保新的嵌套接口与原有的代码兼容。例如,在一个日志系统中,原有的
避免反模式
- 避免接口污染
- 不要将不相关的功能放入同一个接口嵌套结构中。例如,在一个用户管理系统中,不应该将用户登录功能和文件上传功能放在同一个接口嵌套结构中:
// 反模式示例 type UserLogin interface { Login(username, password string) bool } type FileUpload interface { Upload(filePath string) error } type BadCombinedInterface interface { UserLogin FileUpload }
- 这种组合会导致接口职责不清晰,难以理解和维护。应该将它们分开,保持接口的单一职责。
- 防止循环嵌套
- 避免接口之间出现循环嵌套。例如:
// 反模式示例 type A interface { B } type B interface { A }
- 这种循环嵌套会导致编译错误,并且逻辑上也不合理,应该通过重新设计接口结构来避免。