🏭工厂方法模式(Factory Method)
参考
https://github.com/guanguans/design-patterns-for-humans-cn#-factory-method
现实生活中的例子:
考虑招聘经理的情况。一个人不可能对每个职位进行面试。根据职位空缺,她必须决定并将面试步骤委托给不同的人。
通俗解释:
它提供了一种将实例化逻辑委托给子类的方法。
维基百科:
在基于类的编程中,工厂方法模式是一种创建模式,它使用工厂方法来处理创建对象的问题,而无需指定将要创建的对象的确切类。这是通过调用工厂方法来创建对象来完成的 - 在接口中指定并由子类实现,或者在基类中实现并可选地由派生类覆盖 - 而不是通过调用构造函数。
Golang程序示例:
当考虑招聘经理的情况时,使用工厂模式可以将面试过程的创建和管理与招聘经理分开,从而降低耦合性并提高代码的灵活性。以下是一个使用工厂模式来处理招聘面试的示例:
package main
import "fmt"
// Interviewer 定义了面试官的接口
type Interviewer interface {
Interview(candidate string)
}
// TechnicalInterviewer 实现了面试官接口的技术面试官
type TechnicalInterviewer struct{}
// TechnicalInterviewer 技术面试官 实现自己的面试方法Interview !
func (t *TechnicalInterviewer) Interview(candidate string) {
fmt.Printf("技术面试:%s\n", candidate)
}
// HRInterviewer 实现了面试官接口的HR面试官
type HRInterviewer struct{}
// HRInterviewer HR面试官 实现自己的面试方法Interview !
func (h *HRInterviewer) Interview(candidate string) {
fmt.Printf("HR面试:%s\n", candidate)
}
// InterviewerFactory 定义了面试官工厂的接口 创建Interviewer面试官!返回值为 Interviewer
type InterviewerFactory interface {
CreateInterviewer() Interviewer
}
// TechnicalInterviewerFactory 实现了面试官工厂接口,用于创建技术面试官!
type TechnicalInterviewerFactory struct{}
// TechnicalInterviewerFactory 创建技术面试官的工厂方法实现!
func (t *TechnicalInterviewerFactory) CreateInterviewer() Interviewer {
return &TechnicalInterviewer{}
}
// HRInterviewerFactory 实现了面试官工厂接口,用于创建HR面试官
type HRInterviewerFactory struct{}
// HRInterviewerFactory 创建HR面试官的工厂方法实现!
func (h *HRInterviewerFactory) CreateInterviewer() Interviewer {
return &HRInterviewer{}
}
// RecruitingManager 招聘经理
type RecruitingManager struct {
interviewerFactory InterviewerFactory
}
// SetInterviewerFactory 招聘经理指派当前面试官
func (m *RecruitingManager) SetInterviewerFactory(factory InterviewerFactory) {
m.interviewerFactory = factory
}
// ConductInterview 执行面试!
func (m *RecruitingManager) ConductInterview(candidate string) {
if m.interviewerFactory == nil {
fmt.Println("未设置面试官工厂")
return
}
interviewer := m.interviewerFactory.CreateInterviewer()
interviewer.Interview(candidate)
}
func main() {
// 创建招聘经理
manager := &RecruitingManager{}
// 先指定使用技术面试官工厂进行技术面试
manager.SetInterviewerFactory(&TechnicalInterviewerFactory{})
manager.ConductInterview("候选人A")
// 然后使用HR面试官工厂进行HR面试
manager.SetInterviewerFactory(&HRInterviewerFactory{})
manager.ConductInterview("候选人B")
}
在这个示例中,我们首先定义了Interviewer
接口(通用面试官接口,用于让具体的面试官去实现),其中包含了一个Interview
方法。
然后,我们实现了两个不同类型的面试官,TechnicalInterviewer
(技术面试官)和HRInterviewer
(HR面试官),分别实现了Interviewer
接口的Interview
方法。
接着,我们定义了InterviewerFactory
接口,其中包含了一个CreateInterviewer
方法用于创建面试官。
然后,我们实现了两个不同类型的面试官工厂,TechnicalInterviewerFactory
和HRInterviewerFactory
分别实现了InterviewerFactory
接口的CreateInterviewer
方法。
最后,我们定义了RecruitingManager
招聘经理,该结构体可以使用不同的面试官工厂来设置和执行面试。
在main
函数中,我们创建了一个招聘经理,并使用不同的面试官工厂来进行技术面试和HR面试。
这个示例演示了如何使用工厂模式来处理招聘面试中的面试官创建和管理。你可以根据需要扩展和调整工厂模式,添加更多的面试官类型和工厂。
使用工厂模式在招聘经理的情况中有几个明显的好处:
- 解耦合和灵活性: 工厂模式将对象的创建和使用分离开来,招聘经理无需直接创建面试官对象(SetInterviewerFactory 直接指定对应的面试官),从而降低了代码的耦合性。招聘经理只需要通过工厂来获取合适的面试官对象,这使得系统更加灵活,可以随时切换或扩展面试官类型,而不需要修改招聘经理的代码。
- 扩展性: 如果需要添加新类型的面试官,只需创建新的面试官类和对应的工厂类即可,而不需要修改已有的代码。这种方式有助于保持代码的可扩展性和可维护性。
- 可维护性: 工厂模式将对象的创建集中在一个地方,使得代码更加清晰和易于维护。当需要修改创建逻辑或添加新类型时,只需修改工厂类,而不会影响到其他部分的代码。
- 代码复用: 通过工厂模式,可以将对象创建的逻辑封装在工厂类中,从而可以在不同的地方重复使用相同的创建逻辑,避免了重复编写类似的代码。
- 单一职责原则: 工厂模式有助于遵循单一职责原则,每个类只负责一种功能,提高了代码的可读性和维护性。
在招聘经理的情况下,工厂模式使得面试官的创建和管理更加灵活,能够根据不同的需求动态选择不同类型的面试官。这样做有助于减少代码的重复和耦合,同时提高了代码的可维护性和可扩展性。
评论区