始めに
私たちパクテラ・コンサルティング・ジャパン(以下:パクテラ)は世界基準のナレッジを有し、デジタル領域に強みを持つグローバルカンパニーです。
大規模のプロジェクトを進めていく上で、従業員のボトムアップが常に求められている現状から、社内研修制度の一環としてITのスペシャリストによるセッション「PETS」を開催しております。
本投稿ではその第2回目の内容をレポートさせていただきます。是非、ご一読ください。
PETSとは?
PETSとはPactera Engineer Training Session のそれぞれの頭文字を取ったITのエキスパートを養成するためのパクテラ・ジャパン独自の社内研修です。毎回、外部講師を招待し、日本のDX化を促進させる上での専門性や思考力をセッションを通じて身に付けてまいります。
講師
川島 義隆
株式会社ウルフチーフ 代表取締役
大手SIerで20年間、多数のWebアプリケーション開発プロジェクトのアーキテクチャ設計を担当、また社員教育、技術者採用、研修講師などを努め、2018年10月アーキテクチャ設計専業の株式会社ウルフチーフを創業する。その他、技術コミュニティを中心に登壇多数。
テーマ:デザインパターンを基にしたソフトウェア設計
ソフトウェアの開発・設計はハードウェアとは違いユーザーに合わせて変更・修正が必要となるためシステムの保守性の担保は重要な要素となります。
今回は川島さんに変更に強いシステム設計を行うためのマインドやポイントをレクチャーしていただきました。
デザインパターンとシステムの保守性の必要性
昨今、ビジネスの中でのソフトウェアの重要性はさらに高まっています。アップデートが不可欠であるソフトウェアにおいて変更・修正は大きな工数やコストがかかる工程です。変更のたびにコードを書き換え全体でテストを行うとなると多くの手間がかかってしまい、保守性の低いシステムとなってしまいます。
そこで、設計の時点で変更に強く保守性の高い構造にしておくことで、効率よくプロジェクトの進捗を取ることができるのです。
ソフトウェアの機能拡張、不具合修正などにかかる要求、コストは増えていきます。ソフトウェアは変更されることが必須であるため、保守コストの軽減というのは非常に重要なメリットがあるのです。
ソフトウェア設計における3つのデザインパターン
GoFには23個のデザインパターンが載っていますが、これらを駆使してアプリケーションを作るものではなく、現代では言語・フレームワークでカバーされており、アプリケーション開発者が意識することが少ないパターンも存在します。
ですが、そのいくつかは保守性の高いコードを書くためには必要不可欠で、なかでもふるまいのパターンはアプリケーション開発者にとっても重要なものが多いのです。
例)言語・フレームワークでカバーされているパターン
生成のパターン:
開発・設計プロセスにおける効率化を図るためのパターン。機能同士の依存関係が強い場合に「メモリの使用量を減らしながらいかに効率よく開発するか」という観点で活用される。
構造のパターン:
データ構造を簡略化させるパターン。「いかに再利用しやすくメンテナンスが容易なデータ構造にするか」という観点で活用される。
例)保守性の高いコードを実現させるためのパターン
ふるまいのパターン:
ソフトウェアの提供価値を最大化させるパターン。ユーザーの使い勝手や、導入サイドの意図通りにシステムを機能させるため「どのようにインタラクションを設計するか」という観点で活用される。
また、主な代表的なふるまいのパターンとしてChain of Responsibility、Command、Interpreter、Iteratorなどが存在します。
ソフトウェアの価値を図る指標
ソフトウェアの概念を構造化すると上記のスライドのようになります。私たちが目にするインターフェースはプラティクスセットの上に成り立っているものであり、さらにその下には、法則、原則、最終的には公理へと行きつくのです。
ソフトウェアの世界における公理は不変の概念とされており、疎結合と高凝集の2つの要素が存在します。
疎結合:
システムの構成要素間の結びつきや互いの依存関係、関連性などが弱く、各々の独立性が高い状態
高凝集:
クラスやパッケージ内の機能要素と情報要素間の関連性の強く、変更や修正がしやすい状態
時代やユーザーの要望に合わせて変更しやすく、扱いやすいソフトウェアを設計するには、以上の2つの要素を満たさなければなりません。そのため保守性の高い設計は公理の達成に直接的に関係するものであり、ソフトウェアの価値を決定づけるの重要な指標となるのです。
デザインパターンの根源
保守性の高い設計を実現するにあたり、デザインパターンの根源であるSOLID原則を参考にします。
SOLID原則とはオブジェクト指向プログラミングを前提としたソフトウェアの5つの原則で、ソフトウェアをより理解しやすく、より柔軟に、よりメンテナンス性の高いものにするために考案されたものです。
特に着目すべき点は、Open Cloosed の原則で、モジュールは変更に対して開いており、修正に対して閉じているべきとされており、長期メンテナンスされるソフトウェアの保守性を大きく左右する設計原則となります。
つまり、機能追加に対して拡張機能備わっており、修正する必要が全くないことが保守性の高いソフトウェアの理想状態となるのです。
演習:ETC割引ルールの実装
以上の内容を踏まえて、以下の演習を考えてみましょう。
(今回はコードは書かずに、設計プロセスの考え方まで解説いたします。)
設計を考える前に、前回の要件定義のストーリー(下記のリンクになります。)をご覧になった方はお気づきかもしれませんが、この要件には一つ曖昧な点がございます。
お分かりでしょうか?それは割引が適用される時間帯の判定です。
適用時間内で高速道路に乗降どちらかをしたら割引されるのか、時間内に高速道路に乗っていれば割引されるのか、または時間内に高速道路を降りていれば割引されるのか、まずはこの割引適用期間の定義を明確にしなければなりません。
そして、割引期間と利用期間の関係ををまとめると以下の6通りになります。なお、今回は割引期間に利用期間が重なっていれば適用されるケースとします。
上記のようにパターンを図表化すると、コードへ落とし込む適用時間帯の定義は赤点線で囲った範囲になります。
ちなみにこのような入り組んだ条件は一見書きにくいようですが、コードとして書いてみると、
if (ts <= re && te >= rs) {// 30%OFFの処理}
となります。
それでは実際に割引計算ロジックの設計をしていきましょう。
上のスライドがシステム設計フローになります。Open-Closedの原則をベースに保守性を高めることに留意し設計を行います。
設計の際には2つステップを踏むことが重要です。
1.ルールの抽象化
2.メソッド化
1つ目のステップであるルールの抽象化は与えられたそれぞれの要件(ルール)自体の共通項や属性をグルーピングすることで入力されたデータ(走行記録)から必要な情報の取捨選択をします。
2つ目のメソッド化というのは抽象化された要件を基に入力データがそれぞれのルールへ適用されるか判別するフィルターと、適用後の実際の業務処理のマップを設けることです。
ルールにインターフェースを備えることで、ルール同士が影響を与え合うことを防ぎます。
このように、それぞれのルールをオブジェクトとして独立させ、その中の処理業務をメソッド化することで変更・修正の工程が簡略化されるため、保守性の高いシステムを設計することができるのです。
もし、深夜割引を40%へ変更となった場合は、深夜割引のオブジェクト内の数値を書き換えるだけで変更は完了します。また、ルールは変更せず、数値を変換するだけなので、バグやエラーが生じやすい条件式などの部分的なテストも容易に実行することが可能です。
それだけでなく、ルール同士が依存しあっていないため、新しくルールクラスを一つ増やし、フィルターにかけるだけで機能追加も容易に行うことができます。
終わりに
以上が今回のPETSのレポートでした。いかがでしたか?
こちらをご覧になられた方の力に少しでもなれたら幸いです。
工数のかかるシステムの機能変更・追加業務がソフトウェアの概念や設計原則を理解することで、簡略・効率化できることが分かりました。
パクテラでは引き続き、日本のDX化を促進させる活動の一環として社内研修の内容をご報告させていただきます。ぜひ、今後ともよろしくお願いいたします。
最後になりますが、ご一読いただきありがとうございました。
パクテラ・コンサルティング・ジャパン株式会社では一緒に働く仲間を募集しています