:::tips 本质上 代理模式是为了解决 在不破坏原始类的情况下 扩展类功能
:::
代理模式
:::tips 用处:
- 通过引入代理来给原始类附加功能
好处:
- 代码间解耦
- 非侵入式
场景
- 非功能性需求: 监控, 统计, 鉴权, 限流, 事务, 日志等
:::
golang
典型的代理模式
package mainimport "fmt"// Userinfo 充值类type Userinfo struct {id stringsurplus int}func (u *Userinfo) Recharge(count int) {if count > 0 {u.surplus += count}}func (u *Userinfo) Payment(count int) {if count < 0 {u.surplus += count}}type UserInfoProxy struct {userinfo Userinfo}func (u *UserInfoProxy) Recharge(count int) {fmt.Println("Recharge before do something")u.userinfo.Recharge(count)fmt.Println("Recharge after do something")}func (u *UserInfoProxy) Payment(count int) {fmt.Println("Payment before do something")u.userinfo.Payment(count)fmt.Println("Payment after do something")}func main() {u := UserInfoProxy{Userinfo{"id", 100}}u.Recharge(50)u.Recharge(100)fmt.Println(u)}
- 在外面包裹了一层, 的确没有侵入代码, 但是还是有个大麻烦, 那就是你需要实现父类的所有方法, 这会导致类的数量直接翻倍, 难以维护
- 如果不是我们维护的代码, 比如 第三方类库, 也没办法直接定义一个接口, 这种代码可以通过继承来实现(golang不带, 所以在C#中再演示)
切片式
package mainimport "fmt"// Userinfo 充值类type Userinfo struct {id stringsurplus int}func (u *Userinfo) Recharge(count int) {funcAop(func() {if count > 0 {u.surplus += count}})}func (u *Userinfo) Payment(count int) {funcAop(func() {if count < 0 {u.surplus += count}})}func funcAop(fn func()) {fmt.Println("before do something")fn()fmt.Println("after do something")}func main() {u := Userinfo{"id", 100}u.Recharge(50)u.Recharge(100)fmt.Println(u)}
- golang参数可以是函数, 切片非常方便, 缺点是这样是侵入式的
