前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >聊聊go-bank-transfer项目对Clean Architecture的实践

聊聊go-bank-transfer项目对Clean Architecture的实践

原创
作者头像
code4it
修改2021-03-22 10:24:11
4250
修改2021-03-22 10:24:11
举报
文章被收录于专栏:码匠的流水账

本文主要赏析一下go-bank-transfer对于 Clean Architecture的实践

项目结构

代码语言:javascript
复制
├── adapter
│   ├── api
│   │   ├── action
│   │   ├── logging
│   │   ├── middleware
│   │   └── response
│   ├── logger
│   ├── presenter
│   ├── repository
│   └── validator
├── domain
├── infrastructure
│   ├── database
│   ├── log
│   ├── router
│   └── validation
└── usecase

这里分为adapter、domain、infrastructure、usecase四层

domain

account

代码语言:javascript
复制
type AccountID string

func (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

代码语言:javascript
复制
type TransferID string

func (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

代码语言:javascript
复制
➜  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

代码语言:javascript
复制
➜  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

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 项目结构
  • domain
    • account
      • transfer
      • usecase
      • adapter
      • 小结
      • doc
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档