ソフトウェア設計を学ぶということ
- #Engineering Philosophy
- #Software Architecture
ソフトウェア設計を学ぶということ
導入
ソフトウェアのプログラムを書くことを仕事にしている人は、設計という言葉を耳にする機会はとても多いです。
通常、ソフトウェアは多くのプロセスを経て動作するものが生み出されます。
様々なポジションの人からの要望であったり、ニーズに対して「要件」がまとめられ、 その要件に対して設計が行われます。
その設計に対して、技術的な側面からさらなる設計が生まれることも往々にして発生します。
技術的な観点が明瞭になると、実際にプログラムとテストコードが作成され、レビュー、テスト環境へのデプロイ、テスト環境でのテスト、そしてスケジュール調整などが行われプログラムは多くの人に使われる環境へとデプロイされていきます。
これはアジャイル開発では極一般的なプロセスですが、開発手法によってはテストが何重にも行われたり、まとまった単位でのリリースが行われるケースもあります。
さて、本題のソフトウェア設計について。この言葉が指すのは一般的にどこに含まれるのでしょうか?
私が思うには、このフローには含まれていません。いや。すべてに含まれていると言うこともできるかもしれません。
この言葉が指す意味をこれから書いていきたいと思います。
ソフトウェア設計への誤解
「ソフトウェア設計」というワードを聞くと、
- 要件をソフトウェアのレベルに落とし込むことでしょう
- アーキテクチャの話かな
- システムの初期段階の話でしょう
のように連想されることも多いかもしれません。
しかし実際はソフトウェア設計とは言葉の意味通りではないように感じます。
確かに、要件をソフトウェアのレベルに落とし込むこともアーキテクチャの話もソフトウェア設計においては登場します。 また、これらはシステムの初期段階に発生することがほとんどで、機能レベルの改修フェーズになるとほとんどの場合で意識することはなくなります。
そのため、若手のソフトウェア開発者がソフトウェア設計について触れるのはある程度経験を積んでからというケースが多いように思います。
私も例にもれず、ソフトウェア設計について触れたのはある程度の経験を積んでからです。
これについて考えてみると、設計というのは経験に大きく依存するところが多いと思います。
感覚としては、過去のプロジェクトで採用されていた設計を流用することは非常に多いです。
なので、ソフトウェア設計について深く学ばなくても、過去の例からある程度できてしまうというのがソフトウェア設計の一番の誤解だと感じます。
そのため、日々進化するトレンド技術の方が優先されソフトウェア設計について深く学ぶということのメリットはあまり語られることはありません。
転機
私もソフトウェア設計への学びはかなり後回しになってきました。
AIやデータ分析、新しいFW、言語など、ソフトウェアの発展は日進月歩です。そのため勉強したいことは山積みです。
私は実務で機能レベルの設計をすることはありますが、設計を学ぶ前はすべて感覚と経験を頼りにやっていました。
これまでの経験から、この方法が良いという選択の仕方です。 これは強ち正しい結果を導いてくれることが多いです。なぜなら実績があるからです。
ゆえに、より一層設計への興味関心というものは生まれにくくなっていたと今では感じます。
しかしあるとき、経験からの選択というものに納得感がないという感覚が沸き起こってきました。 これはまさにある程度経験を積んだからこそ、体系的に理解したいという欲求の現れだと思います。
そこから設計について体系的に学び始めました。
学びはじめて最初に思ったのは、同じ技術の話でも学びのベクトルが違うということです。
これまでの勉強は具体的なものがほとんどでした。
プログラム言語にしてもフレームワークやデータ分析にしても手法を学ぶという感覚が強いです。
それは動くものがすぐにできて、理解しやすく、実務でもすぐに使える知識になりえます。
一方で、設計の話は抽象的な話が多いです。
なぜ、疎結合が良いとされているのか、結合は悪の面だけなのか、モジュール化がなぜ良いのか、境界とは
こういった概念の話が展開されていきます。
そのため実務ですぐに活かせる知識ではありません。
これらの知識はソフトウェア技術者として長期的に作用するものだと考えています。
設計を学ぶのは哲学を学ぶこと
設計とよくセットで語られるのがアーキテクチャです。
クリーンアーキテクチャが良いという記事などは検索すればとても多く見つかります。
そして理解しないままアーキテクチャのディレクトリ構成だけ真似をしたものも多く散見されます。
ここにも大きな誤解があると、強く主張したいと思います。
さきほど、学びの性質が違うという話を書きました。 まさにこれと同じことがここで起こっています。
「手法」を学ぶという感覚でアーキテクチャを学ぶと、ディレクトリ構成を真似すればクリーンアーキテクチャになると誤解が発生すると感じます。
しかし、アーキテクチャは「手法」ではありません。 ただのパターンです。
これは万能ではなく、全てのプロジェクトに適用できるほど汎化されたものでもないということです。
ではなぜアーキテクチャを学ぶ必要があるのか。
私はアーキテクチャの背後に隠された設計哲学を学ぶためだと考えています。
どういう理由でこのファイルが分割されるのか、どういう理由でここを疎結合にしなければいけないのか、なぜ戻り値はモデルの形式ではなく値を返さないといけないのか。
そういう背景に隠れたなぜ、つまり考えであり哲学を学ぶことが設計を学ぶということだと思います。
設計哲学を学ぶ意義
より具体的な手法を学ぶ意義はすぐに学ぶことのリターンが得られるため、学ぶ意義は明確です。
これらは業務で必要な場合や、個人的興味から学ぶことになるため、すぐに業務に活かすことができます。
では、設計における哲学を学ぶ意義とはなんでしょうか。
私は普段の意識、そして選択肢の幅だと思います。
ソフトウェア開発者として働き始めたときは、プログラムが動くということにフォーカスしています。
そのため、ファイルの置き場所や処理の分割単位、スコープなどを考えた上で実装するというより、 他の実装箇所と照らし合わせて決めていくことも多いでしょう。
しかし、設計哲学を学ぶと、すべてのことに意味が見えてきます。 逆に考えられていないときは、自ら提案していく糧になります。
動くものから、より保守性、拡張性が高いシステムを作ることに意識が回るようになります。
つまり、普段のコーディングレベルから質が高まると考えています。
保守性や拡張性は未来に向けての投資です。 それはすぐにリターンが期待できるものではありません。
しかしながら、初期の設計が数年後のサービス開発のメンテナンスコストや開発速度に大きな影響を与えるということは、実体験からも感じられます。
数年レベルで同じサービス開発に携わったことがある方であれば、きっと同じ感覚があると思います。
設計の意図を明確にしながら将来への投資をしていくという観点でも、設計哲学を学ぶ意義は大きいと感じます。