質問箱という匿名で質問を送れるサービスに届いた質問に対する回答。
(質問箱はテキストしか書けないため、ブログで詳細を記載しておく)
元の質問:
Traditional Webのアプリ開発において複数の画面で同じAggregateを書くケースがあったとして、そのAggregateはサーバーアクション化すべきでしょうか?例えばPreparationでAggregateを書くときにキャッシュを設定できますので画面ごとの最適化を考えた場合、サーバーアクション化しないほうが良いのでしょうか?
これは個別の事情を勘案しないとどちらにするか判断できないケース。
前提知識を整理したうえで、設計を検討してみよう。
Table of Contents
基礎知識の確認
一般的な設計の話
全く同じ処理は可能な限り独立した共通部品に切り出したい。
- まず、まったく同じ処理を複数個所で実装/テストする労力が無駄
- 同じ処理が複数の場所に散らかっていると、保守時に「漏れなく」探し出して同じ修正を適用しなければならない。工数が無駄になるし、発見や修正が漏れてしまうかもしれない
- プログラム量が膨らんでしまう
などの理由により。
ただし、共通化にあたり設計上の注意事項や前後のプログラムに影響を及ぼす、対象処理があまりにも簡単、同じ処理に見えるが、実際は異なる概念の実装である(たまたま「今は」同じ実装になっているだけ)、などの際には、共通化しない方がよいこともある。
キャッシュ機能(Cache in Minutes)
OutSystemsのキャッシュは、対象要素でCache in Minutesプロパティにキャッシュを保持する時間(単位は分)を指定すると、その期間は同じInput Parameterに対するキャッシュをメモリに保持し、高速に返してくれる。
確かにAggregate自身にCache in Minutesを指定できるが、Server Actionにも指定できる。
そのため、キャッシュを利用できるから、というのはServer Action切り出しの理由にはならない。
AggregateをServer Actionに含めるときの注意
これは、Server Actionに切り出すときの注意点。
Server ActionのOutput ParameterにAggregateの結果からEntityやそのListをそのまま返すと、Aggregateの最適化が効かず、対象Entityの全ての属性がDBからフロントエンドサーバーまで到達してしまう。
問題を検討
まず、キャッシュ機能については、AggregateでもServer Actionでも使えるため、判断基準にはできない。
ただ、真に共通する処理であれば共通化する(Server Actionに切り出す)のが自然。
よって、設計として、
- 複数のAggregateを共通化するにあたって、複雑なInput Parameterを指定することにならないか(例えば、検索条件の8割が共通していても、各画面でいくらかずつ相違点があれば、結果として切り出されたServer Actionが複雑すぎるかもしれない)
- 各画面のAggregateは「偶然、今だけ同じ実装になっているのではないか?」(本来は異なる概念に対応する実装である場合、今後修正を重ねるごとにそれぞれ独自に修正されていくかもしれない。それなら、最初から分離しておいた方がいいかもしれない)
- Aggregateから利用する属性数が大幅に異ならないか(不要な列を取得してしまうとオーバーヘッドがある)
- 共通化する労力に見合う価値があるか(1Entityに1属性でフィルタするだけ、などは共通化する労力に見合うか検討の余地がある)
といったことを検討して、問題なければ共通化することになる。