Go 设计模式-工厂模式


快速理解

工厂模式本质上就是创建了一个接口,来去创建具体的产品!!!
就像是下面的样子,这就是最简单的工厂模式

func NewRequest(requestType string) Request {
	switch requestType {
	case RequestTypeHTTP:
		return HTTP{}
	case RequestTypeBrowser:
		return Browser{}
	default:
		return HTTP{}
	}
}

而针对于不同的场景又细分出了简单工厂模式,工厂方法模式,抽象工厂模式。但是,他们本质上还是上面的这个创建器。(我觉得go里面分成简单工厂跟抽象工厂就行)
这里补充几个概念:

  • 工厂:就是我们上面的创建器
  • 产品:我们最终提供给上层的结构体、函数、接口等
  • 抽象:就是给产品套层皮,大家用的是这层皮,不是用的具体产品,这层皮再去用具体的产品。(这就是一个解耦的关键点,只要抽象层不变,上层代码均不变
模式 创建对象
简单工厂模式 具体产品
抽象工厂模式 工厂 工厂创建工厂,然后工厂创建产品

这里一个容易误解的点是,抽象工厂不是创建抽象层的,而是创建工厂的超级工厂

抽象层:抽象产品,抽象方法,抽象的工厂

抽象层都是可以由工厂创建的

适用场景

  1. 需要创建的对象属于多个产品族,而系统只消费其中某一产品族的对象。例如,有两个产品族:Windows组件和Mac组件,系统只会消费其中一族的组件对象。
  2. 系统需要在多个产品族之间进行切换,例如允许在Mac风格的组件和Windows风格的组件之间切换。
  3. 需要 independency(独立性),可以通过 abstract layer(抽象层)将具体实现和使用者分离。(这个其实是优点的一部分)
  4. 当一个系统不应当依赖于产品类实例如何被创建、组合和表达的时候。这对于构建可定制化和可配置化的系统非常有用。(即创建可以被封装,上层不需要传参的时候)
  5. 系统中有多于一个的产品族,而且很明显的是定义它们的接口是一样的。
  6. 需要提供一个产品类库,而且只想显示它们的接口而不是实现。(本质上是返回了一套方法)
  7. 需要能够替换整个产品族而不是单一的产品实例,例如能切换不同供应商的产品。(比如从 Windows 换到 Linux 这样,两者的实现不同,但是两者都是操作系统)

初始化复杂的结构体,我们可以把初始化全部封装,暴露一个 interface 给上层调用 (这样可以依赖抽象,而不是依赖具体)
使得我们最终修改底层代码时,只要函数参数及返回值不变,上层代码基本不需要修改。

简单实践

简单工厂模式

这里是采用常量来区分各种创建对象,当然也可以一种一个函数(个人觉得不够优雅)

package fetchers

import (
	"errors"
	"fmt"
	"github.com/playwright-community/playwright-go"
	"io"
	"net/http"
	"net/url"
	"serivces"
	"strconv"
	"time"
)

const (
	RequestTypeHTTP    = "http"
	RequestTypeBrowser = "browser"
)

type Request interface {
	Get(u string, proxy services.Proxy, timeout int64) (content string, err error)
}

// NewRequest returns a new Request according to the name
// 简单工厂模式
func NewRequest(requestType string) Request {
	switch requestType {
	case RequestTypeHTTP:
		return HTTP{}
	case RequestTypeBrowser:
		return Browser{}
	default:
		return HTTP{}
	}
}

type HTTP struct {
}
type Browser struct {
}

func (Browser) Get(u string, proxy services.Proxy, timeout int64) (string, error) {
    //...
}
func (HTTP) Get(u string, proxy services.Proxy, timeout int64) (string, error) {
	//...
}

参考资料


如果本文帮助到了你,帮我点个广告可以咩(o′┏▽┓`o)


文章作者: Anubis
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Anubis !
评论
  目录