11:コントローラーには処理を書かない¶
main()
関数や Webフレームワーク の コントローラー (DjangoのView)に処理を書きすぎてはいませんか?
具体的な失敗¶
ここではWebフレームワークDjangoで、 View関数 に書かれた処理を例に説明します。
@login_required
def item_list_view(request, shop_id):
shop = get_object_or_404(Shop, id=shop_id)
if not request.user.memberships.filter(role=Membership.ROLE_OWNER, shop=shop).exists():
return HttpResponseForbidden()
items = Item.objects.filter(shop=shop,
published_at__isnull=False)
if "search" in request.GET:
search_text = request.GET["search"]
if len(search_text) < 2:
return TemplateResnponse(request, "items/item_list.html",
{"items": items, "error": "文字列が短すぎます"})
items = items.filter(name__contains=search_text)
prices = []
for item in items:
price = int(item.price * 1.1)
prices.append(f"{price:,}円")
items = zip(items, prices)
return TemplateResponse(request, "items/item_list.html", {"items": items})
このプログラムは item_list_view
関数に処理を書きすぎています。
(中略)詳細は書籍 自走プログラマー をご参照ください
ベストプラクティス¶
コントローラーでは値の入出力と、処理全体の制御のみ行うべきです。
コントローラーに細かい処理まで実装すると、コントローラーに書かれるプログラムが多くなりすぎます。
それでは処理全体の見通しが悪くなるだけでなく、 単体テスト もしにくくなります。
上記の item_list_view
View関数内の処理もほとんどは別の関数や コンポーネント に分離して実装すべきです。
処理をそれぞれ分離したあとの item_list_view
関数は以下のようになります。
@login_required
def item_list_view(request, shop_id):
shop = get_object_or_404(Shop, id=shop_id)
validate_membership_permission(request.user, shop, Membership.ROLE_OWNER)
items = Item.objects.filter(shop=shop).published()
form = ItemSearchForm(request.GET)
if form.is_valid():
items = form.filter_items(items)
return TemplateResponse(request, "items/item_list.html",
{"items": items, "form": form})
(中略)詳細は書籍 自走プログラマー をご参照ください