面试题答案
一键面试1. 命名类型设计原则
- 单一职责:每个命名类型应专注于一项明确的任务或表示一种特定的数据概念。例如,在用户相关模块中,定义一个
User
类型来表示用户信息。 - 分层设计:根据数据的功能和使用场景,将类型分层。如分为数据传输对象(DTO)层用于不同服务间数据传递,领域模型层用于业务逻辑处理等。
- 可扩展性:设计类型时预留扩展点,通过接口嵌入或组合等方式,方便未来添加新功能。
2. 示例代码设计
假设我们有一个用户管理微服务,涉及用户注册、登录等功能。
数据传输对象(DTO)
// UserRegisterDTO 用于用户注册时的数据传输
type UserRegisterDTO struct {
Username string `json:"username" validate:"required"`
Password string `json:"password" validate:"required"`
}
// UserLoginDTO 用于用户登录时的数据传输
type UserLoginDTO struct {
Username string `json:"username" validate:"required"`
Password string `json:"password" validate:"required"`
}
领域模型
// User 领域模型,代表用户
type User struct {
ID int64 `db:"id"`
Username string `db:"username"`
Password string `db:"password"`
}
服务接口
// UserService 定义用户服务接口
type UserService interface {
Register(user UserRegisterDTO) (User, error)
Login(user UserLoginDTO) (User, error)
}
服务实现
// userServiceImpl 用户服务接口实现
type userServiceImpl struct{}
func (u *userServiceImpl) Register(user UserRegisterDTO) (User, error) {
// 实际业务逻辑,如将用户信息保存到数据库
newUser := User{
Username: user.Username,
Password: user.Password,
}
// 假设这里返回新创建的用户
return newUser, nil
}
func (u *userServiceImpl) Login(user UserLoginDTO) (User, error) {
// 实际业务逻辑,如验证用户名和密码
// 假设这里找到匹配的用户
foundUser := User{
Username: user.Username,
Password: user.Password,
}
return foundUser, nil
}
通过这种方式,我们基于Go的命名类型构建了一个灵活、可扩展且易于维护的类型系统。不同模块间通过清晰定义的DTO进行数据传递,领域模型专注于业务逻辑,服务接口提供了统一的调用方式,方便扩展和维护。