一、简介
代理模式(Proxy Design Pattern)在不改变原始类(或叫被代理类)代码的情况下,通过引入代理类来给原始类附加功能。
二、优点
- 关注点分离
- 访问控制
- 延迟实例化
- 远程访问
- 缓存
- 增加附加功能
三、应用场景
- 访问控制
- 缓存
- 保护代理
- 远程对象
- 智能引用
- 其他:日志记录、监控和审计等
四、UML类图
五、案例
银行提供存款和取款两种功能,不同权限的用户功能不同,只有管理权限的账号能存取款,普通用户只能存款。
package main
import "fmt"
type BankAccount interface {
Deposit(amount float64)
Withdraw(amount float64)
}
type RealBankAccount struct {
Balance float64
}
func NewRealBankAccount(initialBalance float64) RealBankAccount {
return RealBankAccount{Balance: initialBalance}
}
func (rba *RealBankAccount) Deposit(amount float64) {
rba.Balance += amount
fmt.Printf("Deposited: %v, new balance: %v\n", amount, rba.Balance)
}
func (rba *RealBankAccount) Withdraw(amount float64) {
if rba.Balance >= amount {
rba.Balance -= amount
fmt.Printf("Withdrew: %v, new balance: %v\n", amount, rba.Balance)
} else {
fmt.Printf("Insufficient balance\n")
}
}
type BankAccountProxy struct {
UserRole string
RealBankAccount RealBankAccount
}
func NewBankAccountProxy(userRole string, initialBalance float64) BankAccountProxy {
return BankAccountProxy{UserRole: userRole, RealBankAccount: NewRealBankAccount(initialBalance)}
}
func (proxy *BankAccountProxy) Deposit(amount float64) {
if proxy.UserRole == "Admin" || proxy.UserRole == "User" {
proxy.RealBankAccount.Deposit(amount)
} else {
fmt.Printf("Unauthorized access\n")
}
}
func (proxy *BankAccountProxy) Withdraw(amount float64) {
if proxy.UserRole == "Admin" {
proxy.RealBankAccount.Withdraw(amount)
} else {
fmt.Printf("Unauthorized access\n")
}
}
func main() {
adminBankAccount := NewBankAccountProxy("Admin", 1000)
adminBankAccount.Deposit(500)
adminBankAccount.Withdraw(200)
userBankAccount := NewBankAccountProxy("User", 1000)
userBankAccount.Deposit(500)
userBankAccount.Withdraw(200)
}