外观模式
正文:https://refactoringguru.cn/design-patterns/facade
Go代码:https://refactoringguru.cn/design-patterns/facade/go/example
module facade_module
implicit none
private
public :: new_wallet_facade, wallet_facade_type
type account_type
character(:), allocatable :: name
contains
procedure :: check_account => account_type_check_account
end type account_type
type security_code_type
integer :: code
contains
procedure :: check_code => security_code_type_check_code
end type security_code_type
type wallet_type
integer :: balance
contains
procedure :: credit_balance => wallet_type_credit_balance
procedure :: debit_balance => wallet_type_debit_balance
end type wallet_type
type ledger_type
contains
procedure :: make_entry => ledger_type_make_entry
end type ledger_type
type notification_type
contains
procedure :: send_wallet_credit_notification => notification_type_send_wallet_credit_notification
procedure :: send_wallet_debit_notification => notification_type_send_wallet_debit_notification
end type notification_type
type wallet_facade_type
type(account_type) :: account
type(wallet_type) :: wallet
type(security_code_type) :: security_code
type(notification_type) :: notification
type(ledger_type) :: ledger
contains
procedure :: add_money_to_wallet => wallet_facade_type_add_money_to_wallet
procedure :: deduct_money_from_wallet => wallet_facade_type_deduct_money_from_wallet
end type wallet_facade_type
contains
function new_wallet_facade(account_id, code) result(wallet_facade)
character(*), intent(in) :: account_id
integer, intent(in) :: code
type(wallet_facade_type) :: wallet_facade
print *, "Starting create account"
wallet_facade = wallet_facade_type(account=account_type(account_id), &
security_code=security_code_type(code), &
wallet=wallet_type(balance=0), &
notification=notification_type(), &
ledger=ledger_type())
print *, "Account created"
end function new_wallet_facade
subroutine wallet_facade_type_add_money_to_wallet(self, account_id, security_code, amount)
class(wallet_facade_type), intent(inout) :: self
character(*), intent(in) :: account_id
integer, intent(in) :: security_code, amount
print *, "Starting add money to wallet"
call self%account%check_account(account_id)
call self%security_code%check_code(security_code)
call self%wallet%credit_balance(amount)
call self%notification%send_wallet_credit_notification()
call self%ledger%make_entry(account_id, "credit", amount)
end subroutine wallet_facade_type_add_money_to_wallet
subroutine wallet_facade_type_deduct_money_from_wallet(self, account_id, security_code, amount)
class(wallet_facade_type), intent(inout) :: self
character(*), intent(in) :: account_id
integer, intent(in) :: security_code, amount
print *, "Starting debit money from wallet"
call self%account%check_account(account_id)
call self%security_code%check_code(security_code)
call self%wallet%credit_balance(amount)
call self%notification%send_wallet_credit_notification()
call self%ledger%make_entry(account_id, "credit", amount)
end subroutine wallet_facade_type_deduct_money_from_wallet
! - - - - - - - - -
subroutine account_type_check_account(self, account_name)
class(account_type), intent(inout) :: self
character(*), intent(in) :: account_name
if (self%name /= account_name) then
error stop "Account Name is incorrect"
end if
print *, "Account Verified"
end subroutine account_type_check_account
! - - - - - - - - -
subroutine security_code_type_check_code(self, incomming_code)
class(security_code_type), intent(inout) :: self
integer, intent(in) :: incomming_code
if (self%code /= incomming_code) then
error stop "Security Code is incorrect"
end if
print *, "SecurityCode Verified"
end subroutine security_code_type_check_code
! - - - - - - - - -
subroutine wallet_type_credit_balance(self, amount)
class(wallet_type), intent(inout) :: self
integer, intent(in) :: amount
self%balance = self%balance + amount
print *, "Wallet balance added successfully"
end subroutine wallet_type_credit_balance
subroutine wallet_type_debit_balance(self, amount)
class(wallet_type), intent(inout) :: self
integer, intent(in) :: amount
if (self%balance < amount) then
error stop "Balance is not sufficient"
end if
print *, "Wallet balance is Sufficient"
self%balance = self%balance - amount
end subroutine wallet_type_debit_balance
! - - - - - - - - -
subroutine ledger_type_make_entry(self, account_id, txn_type, amount)
class(ledger_type), intent(inout) :: self
character(*), intent(in) :: account_id, txn_type
integer, intent(in) :: amount
print *, "Make ledger entry for accountId ", account_id, &
" with txnType ", txn_type, &
" for amount ", amount
end subroutine ledger_type_make_entry
! - - - - - - - - -
subroutine notification_type_send_wallet_credit_notification(self)
class(notification_type), intent(inout) :: self
print *, "Sending wallet credit notification"
end subroutine notification_type_send_wallet_credit_notification
subroutine notification_type_send_wallet_debit_notification(self)
class(notification_type), intent(inout) :: self
print *, "Sending wallet debit notification"
end subroutine notification_type_send_wallet_debit_notification
end module facade_module
program facade_main
use facade_module, only: wallet_facade_type, new_wallet_facade
implicit none
type(wallet_facade_type) :: wallet_facade
wallet_facade = new_wallet_facade(account_id="abc", code=1234)
call wallet_facade%add_money_to_wallet(account_id="abc", security_code=1234, amount=10)
call wallet_facade%deduct_money_from_wallet(account_id="abc", security_code=1234, amount=5)
end program facade_main
!> Results shall be:
! Starting create account
! Account created
! Starting add money to wallet
! Account Verified
! SecurityCode Verified
! Wallet balance added successfully
! Sending wallet credit notification
! Make ledger entry for accountId abc with txnType credit for amount 10
! Starting debit money from wallet
! Account Verified
! SecurityCode Verified
! Wallet balance added successfully
! Sending wallet credit notification
! Make ledger entry for accountId abc with txnType credit for amount 5