Skip to content

Commit a4d9765

Browse files
committed
add template method
1 parent a0d7689 commit a4d9765

File tree

3 files changed

+101
-0
lines changed

3 files changed

+101
-0
lines changed

14_template_method/README.md

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# 模版方法模式
2+
3+
模版方法模式使用继承机制,把通用步骤和通用方法放到父类中,把具体实现延迟到子类中实现。使得实现符合开闭原则。
4+
5+
如实例代码中通用步骤在父类中实现(`准备``下载``保存``收尾`)下载和保存的具体实现留到子类中,并且提供 `保存`方法的默认实现。
6+
7+
因为Golang不提供继承机制,需要使用匿名组合模拟实现继承。
8+
9+
此处需要注意:因为父类需要调用子类方法,所以子类需要匿名组合父类的同时,父类需要持有子类的引用。

14_template_method/templatemethod.go

+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package templatemethod
2+
3+
import "fmt"
4+
5+
type Downloader interface {
6+
Download(uri string)
7+
}
8+
9+
type template struct {
10+
implement
11+
uri string
12+
}
13+
14+
type implement interface {
15+
download()
16+
save()
17+
}
18+
19+
func newTemplate(impl implement) *template {
20+
return &template{
21+
implement: impl,
22+
}
23+
}
24+
25+
func (t *template) Download(uri string) {
26+
t.uri = uri
27+
fmt.Print("prepare downloading\n")
28+
t.implement.download()
29+
t.implement.save()
30+
fmt.Print("finish downloading\n")
31+
}
32+
33+
func (t *template) save() {
34+
fmt.Print("default save\n")
35+
}
36+
37+
type HTTPDownloader struct {
38+
*template
39+
}
40+
41+
func NewHTTPDownloader() Downloader {
42+
downloader := &HTTPDownloader{}
43+
template := newTemplate(downloader)
44+
downloader.template = template
45+
return downloader
46+
}
47+
48+
func (d *HTTPDownloader) download() {
49+
fmt.Printf("download %s via http\n", d.uri)
50+
}
51+
52+
func (*HTTPDownloader) save() {
53+
fmt.Printf("http save\n")
54+
}
55+
56+
type FTPDownloader struct {
57+
*template
58+
}
59+
60+
func NewFTPDownloader() Downloader {
61+
downloader := &FTPDownloader{}
62+
template := newTemplate(downloader)
63+
downloader.template = template
64+
return downloader
65+
}
66+
67+
func (d *FTPDownloader) download() {
68+
fmt.Printf("download %s via ftp\n", d.uri)
69+
}
+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package templatemethod
2+
3+
func ExampleHTTPDownloader() {
4+
var downloader Downloader = NewHTTPDownloader()
5+
6+
downloader.Download("http://example.com/abc.zip")
7+
// Output:
8+
// prepare downloading
9+
// download http://example.com/abc.zip via http
10+
// http save
11+
// finish downloading
12+
}
13+
14+
func ExampleFTPDownloader() {
15+
var downloader Downloader = NewFTPDownloader()
16+
17+
downloader.Download("ftp://example.com/abc.zip")
18+
// Output:
19+
// prepare downloading
20+
// download ftp://example.com/abc.zip via ftp
21+
// default save
22+
// finish downloading
23+
}

0 commit comments

Comments
 (0)