面试题答案
一键面试1. 设计模式选择
- 工厂模式:用于创建不同环境配置的实例。根据环境变量或配置文件,决定创建何种具体配置的微服务实例。例如,创建生产环境、开发环境或测试环境的配置实例。
- 策略模式:将通用逻辑(如日志服务注入)封装成策略。不同微服务可以根据自身需求选择合适的策略来复用这些通用逻辑。
2. 代码结构设计
- 配置管理:
- 创建一个
config
包,用于管理不同环境的配置。例如,config/production.go
、config/development.go
、config/test.go
,每个文件定义对应环境的配置结构体和初始化函数。 - 在
config
包中提供一个统一的接口,如type EnvironmentConfig interface { GetConfig() interface{} }
,不同环境的配置结构体实现该接口。 - 通过一个工厂函数
func NewConfig(env string) (EnvironmentConfig, error)
来根据传入的环境参数创建不同环境的配置实例。
- 创建一个
// config/production.go
package config
type ProductionConfig struct {
// 具体生产环境配置字段
DatabaseURL string
LogLevel string
}
func (pc *ProductionConfig) GetConfig() interface{} {
return pc
}
// config/development.go
package config
type DevelopmentConfig struct {
// 具体开发环境配置字段
DatabaseURL string
LogLevel string
}
func (dc *DevelopmentConfig) GetConfig() interface{} {
return dc
}
// config/config.go
package config
import (
"fmt"
)
type EnvironmentConfig interface {
GetConfig() interface{}
}
func NewConfig(env string) (EnvironmentConfig, error) {
switch env {
case "production":
return &ProductionConfig{
DatabaseURL: "prod-db-url",
LogLevel: "info",
}, nil
case "development":
return &DevelopmentConfig{
DatabaseURL: "dev-db-url",
LogLevel: "debug",
}, nil
default:
return nil, fmt.Errorf("unknown environment: %s", env)
}
}
- 通用逻辑封装:
- 创建一个
common
包,用于存放通用的注入逻辑,如日志服务注入。例如,common/logging.go
定义日志服务的创建和注入逻辑。 - 在
common/logging.go
中创建一个日志服务接口type Logger interface { Log(message string) }
,以及具体的日志实现结构体(如DefaultLogger
)和创建函数func NewLogger(config interface{}) Logger
。
- 创建一个
// common/logging.go
package common
import (
"fmt"
)
type Logger interface {
Log(message string)
}
type DefaultLogger struct {
LogLevel string
}
func (dl *DefaultLogger) Log(message string) {
fmt.Printf("[%s] %s\n", dl.LogLevel, message)
}
func NewLogger(config interface{}) Logger {
// 根据配置获取日志级别等信息
// 这里简单示例,实际可能更复杂
var logLevel string
switch v := config.(type) {
case *config.ProductionConfig:
logLevel = v.LogLevel
case *config.DevelopmentConfig:
logLevel = v.LogLevel
}
return &DefaultLogger{LogLevel: logLevel}
}
- 微服务模块:
- 每个微服务创建自己的包,例如
microservice1
包。在微服务包内,通过依赖注入的方式使用通用逻辑和环境配置。 - 在微服务的初始化函数中,先获取环境配置,然后通过通用逻辑创建所需的服务实例。
- 每个微服务创建自己的包,例如
// microservice1/microservice1.go
package microservice1
import (
"fmt"
"github.com/go-inject/goinject"
"yourproject/config"
"yourproject/common"
)
type Microservice1 struct {
Logger common.Logger
// 其他依赖
}
func NewMicroservice1(env string) (*Microservice1, error) {
cfg, err := config.NewConfig(env)
if err != nil {
return nil, err
}
logger := common.NewLogger(cfg.GetConfig())
return &Microservice1{
Logger: logger,
}, nil
}
func (ms *Microservice1) Run() {
ms.Logger.Log("Microservice1 is running")
// 其他业务逻辑
}
- 依赖注入管理:
- 使用
go - inject
框架进行依赖注入。在主程序入口,创建注入器,并将环境配置和通用逻辑相关的实例注入到微服务实例中。
- 使用
// main.go
package main
import (
"github.com/go-inject/goinject"
"yourproject/microservice1"
)
func main() {
injector := goinject.NewInjector()
env := "development" // 可以从环境变量获取
ms1, err := microservice1.NewMicroservice1(env)
if err != nil {
panic(err)
}
injector.Map(ms1)
// 其他微服务类似注入
ms1.Run()
}
通过上述代码结构和设计模式,能够有效应对不同环境配置的差异,同时确保通用逻辑的高效复用。