みなさまこんにちは、れおりんです。この記事はQiitaのYYPHP Adventカレンダーの15日目の記事。
この記事では、全部の技術的な要素を説明することは時間的に難しいので、大事な用語を紹介することと、僕の勝手な意見を書いていこうとおもう。この記事はソフトウェア開発をこれからやる、もしくは少しやっているといった方が対象だ。なので技術的な詳細よりも完結で全体を把握のしやすさを念頭に置いている。
複雑さに立ち向かう
ソフトウェアを開発していると、不具合がでたり、新機能を追加したらバグったり、納期に間に合わなかったり、機能が足りなかったり色々な問題が起るとおもう。その問題はソフトウェアは複雑になりやすいという側面があるからだ。その複雑さを軽減する方法が日々世界中の偉い人が考えてくれている。ほんの少し、それらを紹介していこうと思う。
オブジェクト指向
オブジェクト指向は、コンピュータの性能が上り、価格がどんどん安くなったとき、徐々に大規模になっていったソフトウェアが従来の手法ではコードが複雑になりすぎて開発コストが大幅に上昇してしまった際に考えだされたものだ。
オブジェクト指向を正しく使うと、不具合が少なく、機能が追加しやすいソフトウェアが作れる可能性が高くなる。
オブジェクト指向は、プログラミングにおける所謂 "パラダイム(Paradigm)" だ、パラダイムとは哲学的に言うと、
(科学上の問題などについて)ある時代のものの見方・考え方を支配する認識の枠組み。
となっている。他にもパラダイムはある、たとえば"手続き型プログラミング"や、"構造化プログラミング"や、"関数型プログラミング"などがある。様々なパラダイムがあり、どれも長所があるので興味があれば調べてみてほしい。
書いたプログラムが、どうなっていればオブジェクト指向だという明確な決まりがあるわけではないところがオブジェクト指向の理解されにくいところだ。たとえば多くのウェブアプリケションフレームワークでは、コントローラやモデルとなる機能を作るときにはクラスを使っているだろう。このコントローラやモデルをクラスで作ったからといってオブジェクト指向になっているわけではないので注意してほしい。
じゃぁどうなっていたらオブジェクト指向で書けていると言えるのだろうか? これは人によって答えが異なるところかもしれないが、僕としては、"作りたいシステムの概念が、適切なクラスとして表現され、複数のクラスが理路整然と配置され協調して動作しているコード" を実現できていればある程度オブジェクト指向で書けているとおもう。
オブジェクト指向の他にもパラダイムがあるが、ひとつのパラダイムだけを採用できるということではない。複数のパラダイムを適材適所で組み合わせてソフトウェアを構成することができる。
オブジェクト指向における"SOLID"原則
SOLID(ソリッドと発音する)は、Robard C Martinが提唱しているオブジェクト指向における原則だ。このSOLID原則を正しく守るとオブジェクト指向の強みを活かしたコードが書けるようになる。もちろんSOLIDだけを守っていればよいというものでもないが、オブジェクト指向の考えかたに慣れていない場合は、まず忠実に守ってみると、この原則の良いところから、オブジェクト指向の理解が深まるとおもう。SOLIDの詳細については本記事では詳細すぎるため割愛する。
設計手法
決定はできるかぎり遅らせる
ここでいう決定とは、技術的な決定だ。例えばデータの永続化にRDBMSを使うか、NoSQLを使うかといったことや、なにかしらの情報をユーザへ伝えるときにメールを使うとか、MMSを使うとかいったことだ。
DDD
DDDはドメイン駆動設計(Domain Driven Design)の略称だ。ここでいう、"ドメイン" という言葉は、ブラウザのURLで使われるドメイン名とは別のものだ。"ドメイン"という言葉そのものは、"領域"とか"分野"という意味になる。ドメインとは現実世界の"実体(Entity)"を認識しシステムを構成していく。
ドメイン駆動設計の、"ドメイン" は、作りたいシステムや業務の中核となる概念を中心に据えた設計を行うということだ。
ドメイン駆動設計には、チーム構成や組織の構造を考慮したソフトウェアのアーキテクチャを設計する戦略設計と、技術的にどう実装していくかという戦術設計がある。
DDDは戦略設計だけでも、戦術設計だけでも実践をはじめることができる。チームやシステムの規模が大きいときは戦略設計から導入すると効果が大きくなるだろう。
シンプルなアプリケーションではDDDを導入すると逆に複雑さが増すだけという結果になることが多い。また、DDDには深いドメインの知識が必要になるため対象システムの知識が少なすぎる場合には導入に注意が必要だ。もしそれでも導入する場合は、知識が少い中でプロジェクトを進めるとコードへの変更が多く入ることになる。こうおもっていたけど、実は違ったなどだ。この問題に対処するためには、データベースや技術的な実装はせずに、ドメインモデルだけを実際に動作させることだ。ドメインモデルしかなければ変更が入ったときにも変更する部分が少なく対応が早くなる。
レイヤードアーキテクチャ
レイヤードアーキテクチャは、クラスを役割毎に各層に分類する方法だ。各層は、自分より下位の層か、上位の層のことしか認識しない。そのため、各層をごっそり入れ替えることも可能になる。たとえばTCP/IPやOSI参照モデルのレイヤーでは、IPの伝送がWi-Fiで行われているか、有線LANで行われているかは気にせずに通信ができる。これがレイヤードアーキテクチャの利点だ。
役割を層に分割すると、各層ごとに実装することが明確になるため複雑で大きいソフトウェアを整理しやすくなる。
オニオンアーキテクチャ
オニオンアーキテクチャは、レイヤードアーキテクチャと似た概念だが、オニオンアーキテクチャでは層の依存は求心方向のみの依存のみを許す。
クリーンアーキテクチャ
クリーンアーキテクチャはオニオンアーキテクチャの各層について、下記の4層に役割を分割したものだ。
中心から、
- 実体達(Entities)層
- ユースケース層
- コントローラ/ゲートウェイ/プレセンター層
- ウェブ/UI/デバイス/DB/外部インタフェイス層
となっている。
開発プロセス
アジャイルとスクラムについて書きます。(あとで)
色々な原則
あとで書く。
- SOLID
- DRY
- YAGNI
- 驚き最小の法則
プロとしての態度
転職してスキルアップしたいとか、会社が本を買ってくれないとか、そういう意見を耳にするが、それは完全に間違っている。自分のキャリアを会社に頼ってはいけない。スキルアップは自分でするものだし、勉強するための書籍などは自分で購入する必要がある。
どうやって勉強していくか
あとで書く。
見積
期間・品質・機能のトレードオフについてあとで書く。
100%正しい見積を出すには、実装するのと同じ期間がかかる。