在设计模式中,践行的理念就是面向抽象编程,而面向抽象编程的一个好处在于可以控制变化,这种变化的概念很丰富,例如具体的 UI 变化,或者是抽象的实现变化。在长期的软件开发实践中,前人已经根据自身的经验,总结出了一套适应变化的常见套路,而这篇文章要介绍的就是其中一个比较常用的简单工厂模式。本文将通过 Go 语言(Golang) 进行一个简单的实践,展示一下简单工厂模式有什么好处。

一个原始的例子

在开始介绍设计模式之前,我先介绍一个场景,这个场景是这样的,我有好几个云环境,例如 GCP / DO / Vultr,然后我开发了一套管理后台用于管理我在这些云环境的资源(主要是 VM),那么对于配置,我是简单抽象成了这样:

然后假设我要操作一个 VM 的话,那么我可能会这么写:

这里我抽象了一个 interface,用于表示云管理的操作集合,然后我又各自实现对应的具体操作:

整个目录结构是这样的:

  1. [root@liqiang.io]# tree
  2. .
  3. ├── cloud_manager.go
  4. ├── config.go
  5. └── service
  6. ├── gcp.go
  7. ├── do.go
  8. └── vultr.go

那么删除的操作,我在 main.go 里面会这么写:

这样代码是没有问题,可以走通,但是问题在于如果我再操作 Do 或者 Vultr 的话,就需要再构造两个 Manager 了,不利于后续扩展。

简单工厂模式

为了让扩展更简单,这里有个常用操作就是可以创建一个方法用于构造具体的 Manager:

这样,我的 main 函数就可以变得更加简洁灵活了:

这样你就不用在使用 Manager 的地方去关心你具体操作的是哪个云了,只需要知道当前使用的是什么配置,那么对应的 Manager 就是这个配置相应的云了。当然,这样的代码虽然解决了问题,但是不利于测试,所以,为了方便测试,我会将这个工厂方法抽象成一个 Interface,这样就可以很方便得进行 UT 了:

评价

优点

缺点

Ref