package main
import (
"fmt"
)
// Bill 账单
type Bill interface {
Accept(viewer AccountBookViewer) //接受一个账单的访问者
}
// AccountBookViewer 账单访问者
type AccountBookViewer interface {
ViewConsumeBill(bill *ConsumeBill) //访问消费的账单
ViewIncomeBill(bill *IncomeBill) //访问收入的账单
}
// ConsumeBill 消费账单,实现 Bill接口
type ConsumeBill struct {
Amount float64
Item string
}
// NewConsumeBill 消费账单
func NewConsumeBill(amount float64, item string) *ConsumeBill {
return &ConsumeBill{
Amount: amount,
Item: item,
}
}
// Accept 实现账单 Bill 接口
func (c *ConsumeBill) Accept(viewer AccountBookViewer) {
// 直接让访问者访问自己,这相当于一次静态分派
viewer.ViewConsumeBill(c)
}
// IncomeBill 收入账单,实现 Bill接口
type IncomeBill struct {
Amount float64
Item string
}
// NewIncomeBill 收入账单
func NewIncomeBill(amount float64, item string) *IncomeBill {
return &IncomeBill{
Amount: amount,
Item: item,
}
}
// Accept 实现账单 Bill 接口
func (c *IncomeBill) Accept(viewer AccountBookViewer) {
viewer.ViewIncomeBill(c)
}
// Boss 老板
type Boss struct {
totalIncome float64
totalConsume float64
}
// ViewConsumeBill 账单访问
func (b *Boss) ViewConsumeBill(bill *ConsumeBill) {
b.totalConsume += bill.Amount
}
// ViewIncomeBill 账单访问
func (b *Boss) ViewIncomeBill(bill *IncomeBill) {
b.totalIncome += bill.Amount
}
// GetTotalIncome .
func (b *Boss) GetTotalIncome() {
fmt.Println("老板查看收入总计:", b.totalIncome)
}
// GetTotalConsume .
func (b *Boss) GetTotalConsume() {
fmt.Println("老板查看支出总计:", b.totalConsume)
}
// AccountBook 账本,提供给访问者访问
type AccountBook struct {
billList []Bill
}
// AddBill 账本添加账单方法
func (a *AccountBook) AddBill(bill Bill) {
a.billList = append(a.billList, bill)
}
// Show 账本访问方法
func (a *AccountBook) Show(viewer AccountBookViewer) {
for _, bill := range a.billList {
bill.Accept(viewer)
}
}
//客户端
func main() {
//
accountBook := &AccountBook{}
accountBook.AddBill(NewIncomeBill(100, "卖商品"))
accountBook.AddBill(NewIncomeBill(200, "卖广告位"))
accountBook.AddBill(NewConsumeBill(50, "工资"))
accountBook.AddBill(NewConsumeBill(100, "材料"))
boss := &Boss{}
accountBook.Show(boss)
boss.GetTotalIncome()
boss.GetTotalConsume()
}