面试题答案
一键面试接口帮助实现不同模块解耦的原理
在Go语言中,接口定义了一组方法的签名,但不包含方法的具体实现。不同模块之间通过接口进行交互,而非直接依赖具体的结构体类型。这样一来,一个模块不需要了解另一个模块的内部实现细节,只需要知道接口所定义的行为。这就实现了模块之间的解耦,使得各个模块可以独立开发、测试和维护。
举例说明通过接口替换具体实现以增强可维护性和扩展性
假设我们有一个简单的电商系统,其中有一个模块负责计算商品的价格,另一个模块负责展示商品信息。
- 定义接口
// 定义计算价格的接口
type PriceCalculator interface {
CalculatePrice(product Product) float64
}
- 定义商品结构体
type Product struct {
Name string
Price float64
}
- 具体实现计算价格的结构体和方法
// 普通价格计算实现
type NormalPriceCalculator struct{}
func (npc NormalPriceCalculator) CalculatePrice(product Product) float64 {
return product.Price
}
// 打折价格计算实现
type DiscountPriceCalculator struct {
Discount float64
}
func (dpc DiscountPriceCalculator) CalculatePrice(product Product) float64 {
return product.Price * (1 - dpc.Discount)
}
- 商品展示模块使用接口
// 商品展示模块
type ProductDisplay struct {
Calculator PriceCalculator
}
func (pd ProductDisplay) Display(product Product) {
price := pd.Calculator.CalculatePrice(product)
println("Product:", product.Name, "Price:", price)
}
- 使用示例
func main() {
product := Product{Name: "Laptop", Price: 1000}
// 使用普通价格计算
normalCalculator := NormalPriceCalculator{}
pd1 := ProductDisplay{Calculator: normalCalculator}
pd1.Display(product)
// 使用打折价格计算
discountCalculator := DiscountPriceCalculator{Discount: 0.1}
pd2 := ProductDisplay{Calculator: discountCalculator}
pd2.Display(product)
}
在上述示例中,ProductDisplay
模块只依赖PriceCalculator
接口,而不依赖具体的价格计算实现。这样,当需要改变价格计算逻辑时(比如从普通价格计算切换到打折价格计算),只需要创建新的实现PriceCalculator
接口的结构体,并替换ProductDisplay
中的Calculator
即可,而无需修改ProductDisplay
模块的其他代码,大大增强了代码的可维护性和扩展性。