:::tips 本质上 代理模式是为了解决 在不破坏原始类的情况下 扩展类功能
:::
代理模式
:::tips 用处:
- 通过引入代理来给原始类附加功能
好处:
- 代码间解耦
- 非侵入式
场景
- 非功能性需求: 监控, 统计, 鉴权, 限流, 事务, 日志等
:::
golang
典型的代理模式
package main
import "fmt"
// Userinfo 充值类
type Userinfo struct {
id string
surplus 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 main
import "fmt"
// Userinfo 充值类
type Userinfo struct {
id string
surplus 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参数可以是函数, 切片非常方便, 缺点是这样是侵入式的