【第5回】リファクタリングの実践手順|OutSystems Architecture Specialist 合格対策

ArchitectureSpecialist(O11)

プロジェクトが成長し、要件が複雑化すると、当初のクリーンな設計は崩れがちです。気づけばEnd-Userモジュールにビジネスロジックが混入し、モジュール同士が複雑に絡み合った「スパゲッティ・アーキテクチャ」が誕生してしまいます。

第5回では、DiscoveryなどのツールISで特定した「アーキテクチャ違反」を、システムの整合性を保ったまま効率的に解消する手順を解説します。



1. リファクタリングの鉄則:新機能開発と混ぜない

リファクタリングを行う際、最も重要なルールは「リファクタリングのみを行い、新規開発を含めない」ことです。

📝 OutSystemsのベストプラクティス

修正したアーキテクチャ変更を本番環境へデプロイして安全を確認してから、新しい要素を追加します。「直す」と「作る」を同時に行うと、問題発生時の原因特定が困難になります。



2. 優先順位の決定(どこから直すべきか?)

複数の違反が見つかった場合、以下の優先順位(影響力の大きさ)に従って着手します。

順位 対象の違反 理由
🔴 1位 End-Userレイヤーの上方・サイド参照 最上位での違反は、不要なモジュールを芋づる式に引き連れる「巨大なクラスター」を作る最大の原因です。
🟠 2位 Coreレイヤー内の循環参照(Cycle) 解決することで、クラスターの影響範囲をCore層以下に限定できます。
🟡 3位 Coreレイヤーへの違反
(Foundationからの参照など)
下位モジュールがCoreに依存している不適切な結合を解消します。
🟢 4位 Foundation(Library)レイヤー間のサイド参照 階層の底部であり、他への波及が少ないため最後で構いません。

📝 覚え方のコツ

「上から下へ、絡まりを解く」と覚えましょう。同じカテゴリに複数の違反がある場合は、「消費者(Consumers)が最も多いモジュール」から修正すると、最も効率的に多くの衝突を解消できます。



3. 要素移動の落とし穴と「データの永続性」

アクションやUIブロックの移動は比較的簡単ですが、エンティティ(Entity)の移動には細心の注意が必要です。

⚠️ 注意点 エンティティを別モジュールに移動させると、物理的には「新しい空のテーブル」がデータベース内に作成され、データは引き継がれません。
解決策 データを保持したまま移動するには、Refactorコンポーネント(Forge)を使用して移行スクリプトを作成するか、物理テーブルのリンクを維持する特別な手順が必要です。



4. 【試験頻出】サービス抽出の「7つのステップ」

End-Userモジュール(X)から、外部URLを壊さず、再利用可能なサービス(X_CS)を抽出する手順は試験のハイライトです。確実に覚えてください。

Step 作業 内容
1 特定 他から消費されている共有要素(アクションやエンティティ)を洗い出す。
2 クローン モジュールXを「Clone(複製)」し、全く同じコピーを作る。
3 リネーム(元) 元のモジュールXの名前を「X_CS」に変更する。→ 物理テーブルへのリンクが維持されます。
4 リネーム(クローン) クローンした側の名前を元の「X」に戻す。→ エンドユーザーがアクセスする画面URLやブックマークを維持できます。
5 整理(X_CS) UI要素を削除し、再利用可能なコアサービスのみを残す。
6 整理(X) 抽出したサービス要素を削除し、UIのみを残す。
7 再接続 UIモジュール(X)から新しいCoreモジュール(X_CS)へ参照を張り直す。

🚫 なぜこの順番なのか?

Step3で元モジュールを先に「X_CS」に改名することで、物理テーブルのIDがX_CSに引き継がれます。Step4でクローンに「X」という名前を与えることで、URLは壊れません。この順番を逆にすると、データかURLのどちらかが失われます。



5. 疎結合(Loose Coupling)を促進するテクニック

リファクタリングは単なる「移動」だけではありません。より良いパターンへの書き換えも含まれます。

テクニック 内容・適用場面
External URLの使用 End-User間での画面遷移によるサイド参照を避けるため、Screen Destinationの代わりに外部URLを使用します。
ビジネスロジック層(_BL)の追加 2つのCoreサービス間で循環参照が起きている場合、上位に _BL モジュールを作成し、そこから両方を呼び出す(Composition)ことで解決します。
BPTの活用(Pub/Sub) 顧客情報の更新に合わせて契約情報を更新するような場合、BPTを用いたイベントベースの同期に切り替えることで、トランザクションを分離し、物理的な依存を断ち切れます。



第5回のまとめ

✅ この回のポイント

  • リファクタリングと新規開発は分離する:変更をデプロイして安全確認後に新機能を追加します。
  • 優先順位は「上から下へ」:End-User違反 → Core循環参照 → Core違反 → Foundation の順で対処します。
  • エンティティ移動はデータが消える:Refactorコンポーネントを使った移行手順が必須です。
  • 7ステップの順番を守る:Step3→4の改名順序がURLとDBリンクの両方を守る鍵です。



復習問題:合格への最終チェック!

▶ 問1:アーキテクチャ違反の修正において、最初に解決すべきなのはどのレイヤーの違反ですか?
A. Foundationレイヤー間のサイド参照  B. Coreレイヤー間の循環参照  C. End-Userレイヤーにおける上方参照  D. どのレイヤーからでも効果は同じである

正解:C(End-Userレイヤーにおける上方参照)

最上位の違反はクラスター化の最大原因であり、最優先で修正します。ここを直すだけで、芋づる式に引き連れられていた多くのモジュールが独立できるようになります。

▶ 問2:エンティティをモジュール間で単に移動(カット&ペースト)させた際の結果として正しいものはどれですか?
A. 移動先でも古いテーブルのデータをそのまま参照し続ける  B. データベース内に新しい空のテーブルが作成される  C. Service Centerが自動的にバックグラウンドでデータ移行を行う  D. エンティティのPublicプロパティが強制的にNoになる

正解:B(データベース内に新しい空のテーブルが作成される)

移動は論理定義の再作成であるため、物理的には新しい空のテーブルになります。既存データは引き継がれないため、Refactorコンポーネントなどを使った移行スクリプトが別途必要です。

▶ 問3:サービス抽出の7ステップにおいて、元のモジュールを「_CS」へ改名し、クローン側を元の名前に戻す最大の目的は何ですか?
A. 開発者の作業ミスを防ぐため  B. コンパイル時間を短縮するため  C. 物理テーブルへのリンク保持と、外部URLの整合性維持を両立するため  D. ライセンスの消費を抑えるため

正解:C(物理テーブルへのリンク保持と、外部URLの整合性維持を両立するため)

元の名前をUIに残すことでURLを守り、元のIDをCSに引き継ぐことでDBリンクを守ります。この2点を同時に達成するために、改名の順序が厳密に定められています。

▶ 問4:2つのCoreモジュール間での循環参照を解消するための最も推奨される構成は?
A. 2つのモジュールを1つの巨大なモジュールに統合する  B. 一方の参照をすべてREST APIに変更する  C. 上位にビジネスロジック(_BL)モジュールを追加し、オーケストレーションを行う  D. 両方をFoundationレイヤーへ移動する

正解:C(上位にビジネスロジック(_BL)モジュールを追加し、オーケストレーションを行う)

概念を上位で組み合わせるCompositionパターンが最も健全な解決策です。両Coreモジュールは独立したまま保ち、それらを呼び出す _BL が調整役を担うことで、循環参照を生まずに連携できます。

▶ 問5:リファクタリング作業のタイミングとして適切な説明はどれですか?
A. 新機能の開発と並行して、少しずつコードを整理する  B. リファクタリングだけを完了させて本番デプロイし、その後に新機能開発を始める  C. 開発の最終段階、本番リリースの直前に行う  D. アーキテクチャ違反はシステムの動作に影響しないため、リファクタリングは不要である

正解:B(リファクタリングだけを完了させて本番デプロイし、その後に新機能開発を始める)

変更の影響を最小化し、クリーンな状態で開発を継続するための鉄則です。リファクタリングと新規開発を混在させると、不具合発生時に原因がアーキテクチャ変更なのか新機能なのかの切り分けが極めて困難になります。

コメント

タイトルとURLをコピーしました