Factory Method Pattern

本文讨论了 Factory Method Pattern 工厂方法模式的 Go 实现

Factory Method Pattern 工厂方法

  • 有利于产品族内产品的增加。

接口类型

1
2
3
4
5
6
7
package data

import "io"

type Store interface {
Open(string) (io.ReadWriteCloser, error)
}

不同的产品实现

  • diskStorage : 磁盘存储实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
package data

import (
"io"
)

type diskStorage struct {
Store
}

func newDiskStorage() (Store, error) {
return new(diskStorage), nil
}

func (p *diskStorage) Open(f string) (rwc io.ReadWriteCloser, err error) {
// ...
return rwc, err
}
  • memoryStorage : 内存存储实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
package data

import (
"io"
)

type memory struct {
io.ReadWriteCloser
buf []byte
}

func (m *memory) Read(p []byte) (n int, err error) {
for i, v := range m.buf {
p[i] = v
}
return len(p), nil
}

func (m *memory) Write(p []byte) (n int, err error) {
m.buf = append(m.buf, p...)
return len(p), nil
}

func (m *memory) Close() error {
m.buf = m.buf[0:0]
return nil
}

type memoryStorage struct {
Store
}

func newMemoryStorage() (Store, error) {
return new(memoryStorage), nil
}

func (m *memoryStorage) Open(f string) (rwc io.ReadWriteCloser, err error) {
return new(memory), nil
}
  • tempStorage
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package data

import "io"

type tempStorage struct {
Store
}

func newTempStorage() (Store, error) {
return new(tempStorage), nil
}

func (t *tempStorage) Open(f string) (rwc io.ReadWriteCloser, err error) {
return rwc, err
}

工厂方法实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package data

type StorageType int

const (
DiskStorage StorageType = 1 << iota
TempStorage
MemoryStorage
)

func NewStore(t StorageType) (s Store, err error) {
switch t {
case MemoryStorage:
return newMemoryStorage()
case DiskStorage:
return newDiskStorage()
default:
return newTempStorage()
}
}

使用

1
2
3
4
5
6
7
8
9
10
11
12
13
func main() {
store, _ := data.NewStore(data.MemoryStorage)
f, _ := store.Open("file")
defer f.Close()

f.Write([]byte("Hello,"))
f.Write([]byte(" factory method."))

s := make([]byte, 100)
n, _ := f.Read(s)

fmt.Println(string(s[0:n]))
}