大田区から発信するゆるゆる日記

主にITエンジニアに関する備忘録日記。たまに趣味も。何か不備があればコメント頂けると幸いです。Twitterアカウント https://twitter.com/ryuzan03

プログラム設計の手順を言語化してみた

※下記の内容に不備がありましたら、コメント頂けると幸いです。また、下記の内容をご使用頂ける場合は自己責任でお願いします。

概要

業務で行っているプログラム設計の手順を言語化してみました。

今までなんとなくでやっていたプログラム設計の手順を言語化することで、他の観点や抜け漏れがないかを発見し、さらによりより手順を見つけていきたいと思います。

ただ、私はオブジェクト指向を完璧に把握しているわけでも、コーディングの百戦錬磨でもないので、違和感のある手順となっているかもしれませんが、その辺りはご了承ください。

プログラム設計

プログラム設計の意義

プログラム設計を行う理由を私は、「そのプログラムを完成させるために、人間が理解できるレベルにまでそのプログラムを分解し、人間がコーディングできるようにするため」だと考えています。

「プログラムを分解」というのは、そのプログラムを構成する1つ1つの部品を、人間が理解できるように明確に意味づけを行うイメージです。

仕様書や詳細設計書だけでコーディングを行っても、大半の方は良くないプログラムを実装すると思います。

つまり、プログラム設計をすることは、仕様書や詳細設計書などからプログラムの目的を正しく理解し、目的通りのプログラムを組みことができることになるのです。

プログラム設計の手順

1. 実装したいプログラムをモノと処理で分解する

まずは要件定義書や上流の設計書、プログラムの仕様書などを読み解き、実装したいプログラムを全体視点でモノと処理で分解していきます。

ここでいうモノとは、情報や人、システムなどの事物として具体的な対象となるものを指します。 また、処理は、モノに対して実施する編集の内容を指します。

分解していく手順ですが、まずは要件定義書や上流の設計書、プログラムの仕様書を読み解き、ユースケースを考えます。

その考えたユースケースで名詞になっているものは『モノ』としてリストアップし、目的語と動詞の部分は『処理』としてリストアップしていきます。

リストアップ時には、「モノや処理に一つの意味や役割だけが与えられているか」を注意します。
モノや処理が2つ以上の意味や役割を持っている場合は、漏れやダブリが発生している可能性が高いので、ユースケースの見直しが必要になる可能性があります。

2. モノの構成を考える

ここでは1でリストアップしたモノの構成を考えていきます。

1でリストアップしたモノは、オブジェクトとして定義されるべきモノや、そのオブジェクトの属性として定義されるモノなどのように、粒度が異なるモノが一緒くたになってリストアップされてしまっています。

また、さらに分解が必要なモノも見つかるかもしれません。
この場合は、漏れやダブリが発生している可能性が高いので、ユースケースの見直しが必要になる可能性があります。

そこで、リストアップしたモノとモノの関連を考え、モノがどのようなモノで構成されているのかを、粒度が合うように意識しながら、図に書き起こしていきます。
イメージとしては、クラス図のようなものが出来上がります。

3. モノと処理を紐付ける

2で構成したモノとリストアップしていた処理を紐付けていきます。
紐付けた処理は、2で作成した図に書き足しています。

さらに、ここで追加した処理により、他のモノとの紐付きも発生してきます。
その関係も図に書き足していきます。

こうすることで、モノを中心にどういった処理が行われるのかが視覚的に分かるようになります。

4. 処理の時系列を考える

3で作成した図を元に、新たに時間の概念を追加した図を作成します。

イメージとしては、シーケンス図のようなものが出来上がると思います。
上から下に向かって順番に処理が実行され、左から右にモノ(の処理)が呼び出されることが分かる図を作成します。

この時点で、どの部分をプログラムにするか明確になっていると思います。

5. コーディングするファイルに4を時系列で言語化していく

ここまで来るとコーディングが出来そうですが、まだコーディングはしません。

まずは、4で明確になったプログラムにしていく部分を、実際にコーディングをするファイルに、時系列で言語化していきます。
4ができていればさほど難しい作業ではないかと思います。

この時に注意したいのは、言語化した内容が、「入力したデータに対して、〜という処理を行い、結果として〜が出力される」といったような具体的な内容になっているかです。

一般的には、プログラムは外部からデータを入力され、そのデータに対して何かしらの処理を実行し、その結果を出力します。

なので、例えば「名前を渡すと、電話番号が出力される」だけだと、どんな処理によって取得した電話番号が出力されるのか不明確になってしまうので、できるだけ具体的に言語化するようにします。

6. 関数のシグネチャを考える

5で言語化した内容は、実は一つの関数に相当します(必ずしもではないですが、、、)
なので、その部分を一つの関数とし、関数のシグネチャを考えていきます。

ここでいうシグネチャは、関数・メソッド名、引数の数やデータ型、返り値の型を指しています。

7. コーディング開始

6までが終わると、ようやくコーディングを始めていきます。

おまけ

コーディングで気をつけていること

1. できるだけコード量を減らす

同じようなプログラムを作らないようにしたり、より簡素に書けるコーディングをするように心がけています。

2. 関数の返り値はできるだけ早く返す
3. 名前は誤解がないよう、より具体的に命名する
4. プログラム同士を独立させる

プログラム同士のやりとりは、可能な限りデータのみにしています。

場合によっては、処理全体の流れを実行し制御するプログラムも必要ですが、それ以外のプログラムはできるだけ結合度を弱くし、独立性を高めています。
変更に弱くなってしまいますからね。

6. 良いプログラム設計は積極的に真似る



Lambdaでコーディングする際に気を付けていること

handlerで行う処理
  1. 外部から受け取ったeventのパース処理
  2. コアロジックの実行
  3. 返り値の定義

の3点を行うようにしています。

参考

素晴らしい記事に感謝致します。
周りのプログラマーの一歩先を行く! プログラムの設計の本質と秘訣