Abstract Factory-抽象工厂¶
备注
工厂模式用来创建不同但是相关类型的对象(继承同一父类或者接口的一组子类),由给定的参数来决定创建哪种类型的对象。
简单工厂模式¶
示例:
type Person struct {
Name string
Age int
}
func (p Person) Greet() {
fmt.Printf("Hi! My name is %s", p.Name)
}
简单工厂模式是最常用、最简单的。它就是一个接受一些参数,然后返回 Person 实例的函数:
func NewPerson(name string, age int) *Person {
return &Person{
Name: name,
Age: age,
}
}
抽象工厂模式¶
备注
groups object factories that have a common theme. 和简单工厂模式的唯一区别,就是它返回的是接口而不是结构体。
通过返回接口,可以在你不公开内部实现的情况下,让调用者使用你提供的各种功能:
type Person interface {
Greet()
}
// Here, NewPerson returns an interface, and not the person struct itself
func NewPerson(name string, age int) Person {
return person{
name: name,
age: age,
}
}
通过返回接口,我们还可以实现多个工厂函数,来返回不同的接口实现:
// We define a Doer interface, that has the method signature
// of the `http.Client` structs `Do` method
type Doer interface {
Do(req *http.Request) (*http.Response, error)
}
// This gives us a regular HTTP client from the `net/http` package
func NewHTTPClient() Doer {
return &http.Client{}
}
type mockHTTPClient struct{}
func (*mockHTTPClient) Do(req *http.Request) (*http.Response, error) {
// The `NewRecorder` method of the httptest package gives us
// a new mock request generator
res := httptest.NewRecorder()
// calling the `Result` method gives us
// the default empty *http.Response object
return res.Result(), nil
}
// This gives us a mock HTTP client, which returns
// an empty response for any request sent to it
func NewMockHTTPClient() Doer {
return &mockHTTPClient{}
}
要测试的实例:
func QueryUser(doer Doer) error {
req, err := http.NewRequest("Get", "http://api.zhaoweiguo.com/v1/secrets", nil)
if err != nil {
return req
}
_, err := doer.Do(req)
if err != nil {
return err
}
return nil
}
其测试用例为:
func TestQueryUser(t *testing.T) {
doer := NewMockHTTPClient()
if err := QueryUser(doer); err != nil {
t.Errorf("QueryUser failed, err: %v", err)
}
}