-
3.2 模板模式
-
代码实现
举个 🌰,假设我现在要做一个短信推送的系统,那么需要:
1.检查短信字数是否超过限制
2.检查手机号是否正确
3.发送短信
4.返回状态
我们可以发现,在发送短信的时候由于不同的供应商调用的接口不同,所以会有一些实现上的差异,但是他的算法(业务逻辑)是固定的
Code
package template import "fmt" // ISMS ISMS type ISMS interface { send(content string, phone int) error } // SMS 短信发送基类 type sms struct { ISMS } // Valid 校验短信字数 func(s * sms) Valid(content string) error { if len(content) > 63 { return fmt.Errorf("content is too long") } return nil } // Send 发送短信 func(s * sms) Send(content string, phone int) error { if err: = s.Valid(content); err != nil { return err } // 调用子类的方法发送短信 return s.send(content, phone) } // TelecomSms 走电信通道 type TelecomSms struct { * sms } // NewTelecomSms NewTelecomSms func NewTelecomSms() * TelecomSms { tel: = & TelecomSms {} // 这里有点绕,是因为 go 没有继承,用嵌套结构体的方法进行模拟 // 这里将子类作为接口嵌入父类,就可以让父类的模板方法 Send 调用到子类的函数 // 实际使用中,我们并不会这么写,都是采用组合+接口的方式完成类似的功能 tel.sms = & sms { ISMS: tel } return tel } func(tel * TelecomSms) send(content string, phone int) error { fmt.Println("send by telecom success") return nil }
单元测试
package template import ( "testing" "github.com/stretchr/testify/assert" ) func Test_sms_Send(t * testing.T) { tel: = NewTelecomSms() err: = tel.Send("test", 1239999) assert.NoError(t, err) }
- 留下你的读书笔记
- 你还没登录,点击这里
-
用户笔记留言