面试题答案
一键面试依赖倒置原则
- 原理:高层模块不应该依赖低层模块,二者都应该依赖其抽象;抽象不应该依赖细节,细节应该依赖抽象。
- 关键代码结构
// 定义技能接口
type Skill interface {
Use()
}
// 战士类
type Warrior struct {
skill Skill
}
func NewWarrior(s Skill) *Warrior {
return &Warrior{
skill: s,
}
}
func (w *Warrior) Fight() {
w.skill.Use()
}
// 技能实现类,比如火球术
type FireballSkill struct{}
func (f *FireballSkill) Use() {
println("释放火球术")
}
- 解释:在上述代码中,
Warrior
(高层模块)并不直接依赖具体的技能实现(低层模块),而是依赖Skill
接口(抽象)。这样当有新的技能实现时,Warrior
不需要修改代码,只需要传入新的实现了Skill
接口的对象即可,满足依赖倒置原则。
开闭原则
- 原理:软件实体(类、模块、函数等)应该对扩展开放,对修改关闭。
- 关键代码结构
// 角色接口
type Character interface {
Play()
}
// 法师类实现角色接口
type Mage struct {
skill Skill
}
func NewMage(s Skill) *Mage {
return &Mage{
skill: s,
}
}
func (m *Mage) Play() {
m.skill.Use()
}
- 解释:当需要新增一种角色(如法师
Mage
)时,我们只需要实现Character
接口,而不需要修改已有的Warrior
等角色类的代码。同样,当有新的技能需要添加时,只需要实现Skill
接口,而不需要修改现有的角色类,满足开闭原则。例如,如果要新增一个IceSkill
,只需要实现Skill
接口的Use
方法:
// 冰系技能
type IceSkill struct{}
func (i *IceSkill) Use() {
println("释放冰系技能")
}
然后就可以将IceSkill
应用到Warrior
或者Mage
等角色上,无需修改这些角色的原有代码。