オブジェクト指向設計実践ガイドを読む No.1【設計の目的と実践】
こんにちは。 sasumasa です。
僕は Web エンジニアとして働いており、主にサーバーサイドで使用する言語の 1 つに Ruby があります。
僕が Web プログラミングを始めた時に最初に学んだ言語も Ruby であり、最初に学んだフレームワークは Ruby on Rails でした。
今回はその Ruby を使ってオブジェクト指向設計をするときに使えるノウハウをまとめた本である『オブジェクト指向設計実践ガイド』の序盤についてまとめていけたらと思います。
なお、本記事では「オブジェクト指向設計とは何か」とかについて言及はしません。
ただ本の内容をまとめるだけでなく、僕の経験を踏まえてまとめていきたいと思います。
なぜ設計するのか
先に述べたように本書はオブジェクト指向設計についての本ですが、エンジニアはなぜ設計するのでしょうか?
本書の言葉を借りるとその答えは「変更の容易性を確保するため」となります。
プログラムを書いて作る機能はほとんどの場合、変更する必要に迫られます。既存の機能にバグがあったら修正する必要が出てくるし、要件によって変更をすることがあるかもしれないし、新しい機能を追加するために拡張するかもしれません。0 から機能を作るより、変更する機会の方が多くなる可能性は十分にあります。
その変更が必要になってくる際により効率的に、楽しく目的を達成する。これがオブジェクト指向設計をする理由だと本書では述べられています。
そう言われるとオブジェクト指向設計は「市場価値を上げるために勉強すべきこと」だとか「学ぶべきと言われたから」とかいったモチベーション学ぶよりもずっと意義のあるものだと思えてきます。
0 から機能を作るのは自分だとしても、変更をするのは未来の自分かもしれないからです。
自分が楽しくコードを書くために設計を学び、自ずとそれがエンジニアとしての成長に繋がる。それがオブジェクト指向設計だと僕は考えています。
設計のための武器
オブジェクト指向設計をする意義をある程度納得したところで、僕たちが設計をする際に使える武器について確認しておきます。
- 設計原則
- デザインパターン
設計原則とは(後に言及します)SOLID 原則 や DRY、デメテルの法則(LoD: Low of Demeter)などがあります。こういった原則に従うことがどれだけのメリットが得られるかは具体的な研究とその結果に譲るとして、これらの効果は信頼に足るものだと説明されています。
デザインパターンによって課題を解決することもあります。例えば Form Object や Decorator Pattern, Query Object, 本書でも出てくる Template Method, Factory Pattern や Factory Method Pattern… 少しググったら呼び名は違えどデザインパターンが色々出てくると思います。これらもまた、良い設計手法をパターンとしてまとめたものです。
この 1 と 2 のどちらも活用するのがプログラムを書く際には重要だと思いますが、本書では 1 の設計原則を重点的に言及しています。 1 を理解することが 2 のパターンを理解するための準備になるとも言っています。
設計を実践する
設計する理由と設計の際に役立つ方針がわかったとしても、設計ができることは保証されません。設計をするにはいくつかの困難性があり、それこそがエンジニア自身で乗り越えるべきポイントとなります。
僕の経験も踏まえてまとめると、いい設計を実践する際には以下の不確定要素に向き合わなければなりません。
- 設計を意識できるか
- 設計をどこまで実践できるか
- 設計をいつ行うか
- 設計をどこまで行うか
最後にこれらのポイントについて軽く触れていきます。
設計を意識できるか
僕が「不確定要素」として列挙した項目の中にこれを見たときに首を傾げた方もいるかもしれません。そういった方は「設計は常に意識するものだろう」と思っているかもしれません。それは何も間違っておらず、僕も賛同したい態度だと思います。
しかし(僕のように)まだまだ未熟なエンジニアは厳しいスケジュール、実装難易度の高い課題、そしてチームをリードする責任やそれに伴う他のタスクなど、色んな要因にさらされながら機能を実装をしていくには実力や精神力が足りないことが多々あります。
そういった状況の中でどれだけコードを書く際に「設計を意識することが後の自分を救う」と意識できるか。とりあえず動くコードを書いて次のスプリントやクライアントとの MTG までに用意したいという誘惑に負けず心を落ち着かせて設計から考えられるか。そこが 1 つの不確定要素だと僕は考えます。
設計をどこまで実践できるか
当たり前ですが、設計を意識できたとしても、設計に対する知識がなければ実践することができません。
この課題は本書の設計ノウハウを理解することにより解決に近づくと思います。また、本書を読み終えた後に日頃から設計パターンについてインプットすること、そして設計を何度も試みることによって実践力が身に付いていくと思われます。
どこかで見たツイートで、有名な海外のプログラマが「いいコードを書けるようになるために一番勉強になったのは、過去に自分が書いた酷いコードをメンテしたことだ」というようなことを言っていました。
月並みですが、本書の内容を理解して(厳密には「理解した気になって」)とにかく実践することでより良いアウトプットに近づくのではないでしょうか。
設計をいつ行うか
今まで簡単に「設計をする」という言葉を使ってきましたが、設計とはあるタイミングで「する」ものであり、それが終わればしなくてよくなるものなのかというと、どうやらそういうことではなさそうです。
設計に関するある決定の良し悪しを決める際にはもちろんアンチパターンに則っていないことや先に述べた設計原則やデザインパターンに沿っているかも大事なのですが、仕様に関する知識がとても大きな要因を占めると僕は考えています。
特に顧客も本当に欲しいものが何かなどわかっていない状態で開発を進めていく場合、仕様が本当の意味で確定することなどありません。その中で情報を集めながらその時その時の最善の手を打っていく必要があります。
その際に重要なのが変更が起きることを許す設計をしておくこととなります。
完璧で非の打ちどころの無い設計ではなく、これからの変化に耐えうる設計という視点。これが設計者には必要不可欠だと僕は思います。
設計をどこまで行うか
設計は何も価値を生み出しません。設計をした後に実装をすることで価値を生み出します。
そのため、設計作業には常に「それにはどれくらい価値があるか」という議論がついて回ります。エンジニアはどの程度まで設計をすればいいのでしょうか。
その疑問に答えるには 2 つの要素が関係してきます。
- エンジニア自身のスキル
- 結果が出るまでの時間
この 2 つを鑑みて設計の時間を取ることはとても重要です。
個人的にはいわゆる「いい設計」や「いい実装」をすることよりも期限内に納品すること、リリースすることが重要だと僕は考えています。そのアプリケーションが価値があればまた実装に携われる機会はくるでしょうし、そうでなければ二度とコードには触れないでしょう。そう考えると、まずは上記の 1 とスケジュールを踏まえた意思決定が重要になってくるかと思います。
また 2 の結果が出るまでの時間も一考に値します。ある設計が 1 年後にしか役に立たないようなものであれば、その 1 年後が来ないかもしれないことを考えておいた方がいいと思います。
ここまで言っておいてなんですが、「いつかリファクタする」は大体リファクタされないので基本的にはその時のベストを尽くすことが基本的には重要だと思っています。
ただし、設計には常にコストが伴うことを意識するべきです。自身のスキルでは設計や実装のコストが高すぎる場合、それはそのコストを下げられるようなエンジニアになるように成長しなければならないということだと僕は思います。
今日はここまでにしておきます。オブジェクト指向設計実践ガイドの第 1 章について僕自身の意見も踏まえながらまとめてみました。
Discussion