序
本文次要赏析一下go-bank-transfer对于Clean Architecture的实际
我的项目构造
├── adapter│ ├── api│ │ ├── action│ │ ├── logging│ │ ├── middleware│ │ └── response│ ├── logger│ ├── presenter│ ├── repository│ └── validator├── domain├── infrastructure│ ├── database│ ├── log│ ├── router│ └── validation└── usecase
这里分为adapter、domain、infrastructure、usecase四层
domain
account
type AccountID stringfunc (a AccountID) String() string { return string(a)}type ( AccountRepository interface { Create(context.Context, Account) (Account, error) UpdateBalance(context.Context, AccountID, Money) error FindAll(context.Context) ([]Account, error) FindByID(context.Context, AccountID) (Account, error) FindBalance(context.Context, AccountID) (Account, error) } Account struct { id AccountID name string cpf string balance Money createdAt time.Time })func NewAccount(ID AccountID, name, CPF string, balance Money, createdAt time.Time) Account { return Account{ id: ID, name: name, cpf: CPF, balance: balance, createdAt: createdAt, }}func (a *Account) Deposit(amount Money) { a.balance += amount}func (a *Account) Withdraw(amount Money) error { if a.balance < amount { return ErrInsufficientBalance } a.balance -= amount return nil}func (a Account) ID() AccountID { return a.id}func (a Account) Name() string { return a.name}func (a Account) CPF() string { return a.cpf}func (a Account) Balance() Money { return a.balance}func (a Account) CreatedAt() time.Time { return a.createdAt}func NewAccountBalance(balance Money) Account { return Account{balance: balance}}
account定义了AccountRepository接口及Account类型,同时还提供了Withdraw、Deposit办法
transfer
type TransferID stringfunc (t TransferID) String() string { return string(t)}type ( TransferRepository interface { Create(context.Context, Transfer) (Transfer, error) FindAll(context.Context) ([]Transfer, error) WithTransaction(context.Context, func(context.Context) error) error } Transfer struct { id TransferID accountOriginID AccountID accountDestinationID AccountID amount Money createdAt time.Time })func NewTransfer( ID TransferID, accountOriginID AccountID, accountDestinationID AccountID, amount Money, createdAt time.Time,) Transfer { return Transfer{ id: ID, accountOriginID: accountOriginID, accountDestinationID: accountDestinationID, amount: amount, createdAt: createdAt, }}func (t Transfer) ID() TransferID { return t.id}func (t Transfer) AccountOriginID() AccountID { return t.accountOriginID}func (t Transfer) AccountDestinationID() AccountID { return t.accountDestinationID}func (t Transfer) Amount() Money { return t.amount}func (t Transfer) CreatedAt() time.Time { return t.createdAt}
transfer定义了TransferRepository接口及Transfer类型
usecase
➜ usecase git:(master) tree.├── create_account.go├── create_account_test.go├── create_transfer.go├── create_transfer_test.go├── find_account_balance.go├── find_account_balance_test.go├── find_all_account.go├── find_all_account_test.go├── find_all_transfer.go└── find_all_transfer_test.go
这一层定义了CreateAccountUseCase与CreateAccountPresenter、CreateTransferUseCase与CreateTransferPresenter、FindAccountBalanceUseCase与FindAccountBalancePresenter、FindAllAccountUseCase与FindAllAccountPresenter、FindAllTransferUseCase与FindAllTransferPresenter接口
adapter
➜ adapter git:(master) tree.├── api│ ├── action│ │ ├── create_account.go│ │ ├── create_account_test.go│ │ ├── create_transfer.go│ │ ├── create_transfer_test.go│ │ ├── find_account_balance.go│ │ ├── find_account_balance_test.go│ │ ├── find_all_account.go│ │ ├── find_all_account_test.go│ │ ├── find_all_transfer.go│ │ ├── find_all_transfer_test.go│ │ ├── health_check.go│ │ └── health_check_test.go│ ├── logging│ │ ├── error.go│ │ └── info.go│ ├── middleware│ │ └── logger.go│ └── response│ ├── error.go│ └── success.go├── logger│ └── logger.go├── presenter│ ├── create_account.go│ ├── create_account_test.go│ ├── create_transfer.go│ ├── create_transfer_test.go│ ├── find_account_balance.go│ ├── find_account_balance_test.go│ ├── find_all_account.go│ ├── find_all_account_test.go│ ├── find_all_transfer.go│ └── find_all_transfer_test.go├── repository│ ├── account_mongodb.go│ ├── account_postgres.go│ ├── nosql.go│ ├── sql.go│ ├── transfer_mongodb.go│ └── transfer_postgres.go└── validator └── validator.go
adapter层实现了domain与usecase层定义的接口
小结
go-bank-transfer工程在domain层定义了model及repository接口,usecase层定义了usecase及presenter接口,同时调用domain层实现业务编排;adapter则实现了下面两层定义的接口。
doc
- go-bank-transfer