検索ガイド -Search Guide-

単語と単語を空白で区切ることで AND 検索になります。
例: python デコレータ ('python' と 'デコレータ' 両方を含む記事を検索します)
単語の前に '-' を付けることで NOT 検索になります。
例: python -デコレータ ('python' は含むが 'デコレータ' は含まない記事を検索します)
" (ダブルクオート) で語句を囲むことで 完全一致検索になります。
例: "python data" 実装 ('python data' と '実装' 両方を含む記事を検索します。'python data 実装' の検索とは異なります。)
img_for_tre_tron

Tré Thộn を食べたことがありますか?
ベトナム・ビンズオン滞在中の方は是非注文して食べてみて!
絶対に美味しいです!
ホーチミン市内へも配達可能です。お問い合わせください。

Have you ever had "Tré Thộn" before?
If you're living at Bình Dương in Vietnam, you "must" try to order and eat it.
I'm sure you're very surprised how delicious it is!!
If you're in Hồ Chí Minh, you have a chance to get it too. Please call!!
>>
practical_python_design_patterns

Practical Python Design Patterns - Python で学ぶデザインパターン: The Facade Pattern - Part. 1 「第8章: ファサードパターン - POS システムで考えよう」の巻 投稿一覧へ戻る

Published 2022年6月8日22:10 by mootaro23

SUPPORT UKRAINE

- Your indifference to the act of cruelty can thrive rogue nations like Russia -

Practical Python Design Patterns - The Facade Pattern 編
「第8章: ファサードパターン - POS システムで考えよう」の巻

Chapter 8: Facade Pattern - Considering a Point Of Sales system
(第8章: ファサードパターン - POS システムで考えよう)

The Phantom of the Opera is there, inside my mind.
(オペラ座の怪人がそこにいる、私の心の中に)
- Christine (クリスティーン: 「オペラ座の怪人」より)
Overview
(概要)
この章では、ユーザーからシステムの複雑な詳細を隠すための別の方法を見ていきましょう。システムを構成している全ての動作機構 (サブシステム) は、外部からはただ1つのエンティティと映れば十分です。
全てのシステムはパッと見た目よりは大体において複雑です。例えば POS システム (Point Of Sales) を考えてみましょう。ほとんど全ての方は、レジのお客さんとしての側からしかこのシステムとの接点はないでしょう。しかし、単純なケースにおいてさえ、すべての処理業務は多岐に渡ります。全ての売り上げを記録し、該当商品の在庫情報を更新し、会員になっている顧客のポイント数の更新作業もあるかもしれません。またほとんどのシステムでは、ある特定の商品にだけ適用する販売促進操作も可能になっています。たとえば、2つ購入するとその内の安い方が無料になる、などです。
Point of Sale Example
(POS システムを考えてみよう)
この業務処理 (transaction process) は多くのサブシステムから成り立っています; 顧客ポイントといったロイヤリティシステム (loyalty system)、在庫システム (stock system)、販売促進システム (specials or promotions system)、決済システム (payment system) 等々が1つの大きなシステムを形成しています。そしてこれらの機能をそれぞれ異なるクラスとして実装することになるでしょう。
このような業務処理自体の実装を想像するのはそれほど難しいことではありません:
pos_example.py
import datetime
import random


class Invoice:
def __init__(self, customer):
self.timestamp = datetime.datetime.now()
self.number = self.generate_number()
self.lines = []
self.total = 0
self.tax = 0
self.customer = customer

def save(self):
# 請求情報を永続ストレージ (persistent storage) に保存します
pass

def send_to_printer(self):
# 請求情報をプリントアウトします
pass

def add_line(self, invoice_line):
self.lines.append(invoice_line)
self.calculate()

def remove_line(self, line_item):
try:
self.lines.remove(line_item)
except ValueError as e:
print(f'請求データ内に該当する項目が存在しません。\n項目の削除に失敗しました: {line_item}')

def calculate(self):
self.total = sum(x.total * x.amount for x in self.lines)
self.tax = sum(x.total * x.tax_rate for x in self.lines)

def generate_number(self):
rand = random.randint(1, 1000)
return f'{self.timestamp} {rand}'


class InvoiceLine:
def __init__(self, line_item):
# 商品情報と現在の価格情報などから請求明細 (invoice line) を作成します
pass

def save(self):
# 請求明細を永続ストレージ (persistent storage) に保存します
pass


class Receipt:
def __init__(self, invoice, payment_type):
self.invoice = invoice
self.customer = invoice.customer
self.payment_type = payment_type
pass

def save(self):
# 領収書を永続ストレージ (persistent storage) に保存します
pass


class Item:
def __init__(self):
pass

@classmethod
def fetch(cls, item_barcode):
# 永続ストレージから商品情報を取得します
pass

def save(self):
# 商品情報を永続ストレージに保存します
pass


class Customer:
def __init__(self):
pass

@classmethod
def fetch(cls, customer_code):
# 永続ストレージから顧客情報を取得します
pass

def save(self):
# 顧客情報を永続ストレージに保存します
pass


class LoyaltyAccount:
def __init__(self):
pass

@classmethod
def fetch(cls, customer):
# 永続ストレージから顧客ポイント情報を取得します
pass

def calculate(self, invoice):
# 今回の購入で取得したポイントを算出します
pass

def save(self):
# 顧客ポイント情報を永続ストレージに保存します
pass
売り上げを処理する際は、これら全てのクラスの関連性を考慮しながら操作を進めることになります:
def complex_sales_processor(customer_code, item_dict_list, payment_type):
customer = Customer.fetch(customer_code)
invoice = Invoice(customer)

for item_dict in item_dict_list:
item = Item.fetch(item_dict['barcode'])
item.amount_in_stock -= item_dict['amount_purchased']
item.save()
invoice_line = InvoiceLine(item)
invoice.add_line(invoice_line)
invoice.calculate()
invoice.save()

loyalty_account = LoyaltyAccount.fetch(customer)
loyalty_account.calculate(invoice)
loyalty_account.save()

receipt = Receipt(invoice, payment_type)
receipt.save()
いかがでしょうか?1つの売り上げの処理をするだけでも、これだけ多くのクラスとの煩雑なやり取りが必要です。