SOLID 原則良いなぁ(← 適当)...と思いつつ、それが書かれているアジャイルソフトウェア開発の奥義を読んでいなかったので、最近ちらちらと読み始めた。開発プロセスのあたりにはあんまり興味がわかないので、さらさらと軽い感じに読み飛ばしている。開発プロセス関連のはなしはなるほどなぁとは思うし、全員が内容を理解した上でやっていくと意味はありそうなんだけど、現実的にそんなことは起こり得ないと思っていて、学習コストが必要になる開発プロセスに意味はあるのか...とか偉そうなことを思っている。まあそんなことはどうでもよくて、第2部からのアジャイル設計の部分は本当に参考になるなぁ...と思いながら読んでる。
注意:この文章はポエムです
アジャイル設計とは?
本によると、アジャイルはソフトウェアを少しずつ開発する手法だそうだ。基本的にラビットハウスでは完成させたソフトウェア(完成とは...という話になるが)を納品するようなお仕事ではなく、ソフトウェアを少しずつ拡張していくスタイルなので、まさに合致している。
腐敗するソフトウェアの兆候
さて、そんな「少しずつ開発していく」スタイルの場合に、どうやってソフトウェアを設計できるのだろうか?という問いが冒頭にくる。少しずつ開発するとしても、最終的な目的は大きなソフトウェアを保守可能な状態で動かすことにあるので、その段階まで持っていけるような状態を各工程(アジャイル言葉ではイテレーションとかよんでるっぽい)で踏んでいかなければならない。それを阻む要素として次のような項目が挙げられている。
- 硬さ: 設計変更が困難
- もろさ: 設計が壊れやすい
- 移植性のなさ: 設計の再利用が困難
- 扱いにくさ: 正しい設計をするのが困難
- 不必要な複雑さ: 行き過ぎた設計
- 不必要な繰り返し: マウスを使いすぎ
- 不透明さ: 整然としない表現
なるほど、たしかにという気持ちになる。こういった構造を作らないための原則として、有名な SOLID 原則が紹介されている
- 単一責任の原則(SRP: Single Responsibility Principle)
- オープンクローズド原則(OCP: Open-Closed Principle)
- リスコフの置換原則(LSP: Liskov Substitution Principle)
- 依存関係逆転の原則(DIP: Dependency Inversion Principle)
- インターフェース分離の原則(ISP: Interface Segregation Principle)
設計に関するいろいろな本がでているが、基本的にまずこれを守れてない上でそういうものを取り入れようとしても、かえってカオスになるケースのほうが多いのではないかなぁと個人的に感じている。まあ採用しているアーキテクチャなど状況によりけりでしょうけど。とはいえ、ソフトウェアのうまくいっている部分に無理やり、この 5 原則を適用しにかかるのはやめなさいという忠告も書かれている。そういう部分にはいろいろ変更がくわわってカオスになってきてから、原則に則ってリファクタしても遅くないと思うので、なるほどなぁ...と思った。こいつらについては、別記事で個別にみていく。
硬さ
ソフトウェアのちょっとした変更が難しい、1行の変更をしようとすると芋づる式に変更箇所が膨らむということを、硬い設計とよんでいる。これって要はその一行に他のモジュールが依存しているのと変わらないので、結局のところモジュールに分割している意味がないってことな気がする。そうならないようにちゃんと考えて書けよ〜ってことなんでしょうね。
もろさ
1 つの変更により他の多くの部分が壊れてしまう傾向のことを、もろい設計というらしい。そういった箇所は、ソフトウェアの部品としての抽象化に失敗しているということを指すのではないかなと思った。
移植性のなさ
他のシステムでも役に立つ部分を含んでいるのに、その場所から切り離すことが困難・リスクをともなうような状態。これも機能の抽出に失敗してしまっているときに起こるようなことかなと解釈した。移植するかしないかはともかく、移植できる状態にあることは良いことだとも思う。ただ他のシステムでも役に立つが、移植可能な状態にするのがあまりにも厳しいものはあると思うので、そういった部分はまた別の話かなぁとも思う。難しかったり前例がなかったりする実装はそうなってしまいがちなのはしょうがないと思う。バランスが大事。
(ソフトウェアの)扱いにくさ
設計構造を保持するやり方が難しく、これまでの設計とは違うが圧倒的に簡単に機能を追加したり変更したりできてしまう場合、そのソフトウェアは扱いにくい。これは非常に重要だと思っていて、難しい設計技法とかをあたまのいい人たちが頑張って取り入れても、そこに追っついていける人が開発メンバでなければ、思想のまったくことなる実装が入り組み、余計複雑なソフトウェアを生み出してしまうと思う。同じ設計手法を用いるとしても、その考え方を理解して、やり方を揃えていけるのであればきっとうまくいくのではないかなと思う。そうでない場合は失敗するだろう。当然のことのはずだけど、新しいことを覚えて感動しているときには、こういうバランス感覚を忘れてしまいがちになるはずで、気をつけなければならない。
(環境の)扱いにくさ
開発環境がクソゴミで非効率なことを指す。コンパイルに時間が掛かる場合に、設計を維持できないとわかっていてもモジュール分割してしまうみたいなこと。差分管理システムへのコミットに時間が掛かるようなことも例として書かれていた。まあ git 使ってる分にはよほどなことがない限りこんな感じにはならないかなと思う。モジュール分割については、もうちょっと考えないと本のいっていることの意味が理解しきれない。そもそもコンパイル時間を減らすことを直接の目的としてモジュール分割するのはどうなんだろうか?あたまが悪いので自分には判断がつかない。
不必要な複雑さ
設計している時点で不必要な要素が含まれている設計のことを指す。これ気をつけないとやってしまいがちですよね。結局あとから手直しするハメにあったり、つかわれることがないまましれっと削除コミットをしたり。このようなことをすると不必要にソフトウェアは複雑になるそうだ。たしかに分かるような、分からないような。不必要なコードをコミットするのは読み手にとっては非常につらみを増やすだけだが、それがソフトウェアの複雑さに結びつくかどうかの部分が自分の中であんまりはっきりとイメージできないので、これからも継続的に考えていきたい。
不必要な繰り返し
同じようなコードが繰り返しでてくる。読み手がつらい。こういうコードのレビューをしているとき、推敲されていない文章(この記事のように...)を読んでいるかのようでつらい気持ちになる。このリポジトリはお前のブログじゃねえんだよという気持ちにさせないように、ちゃんと自分の書いたコードは推敲しないといけない。でもこれを応用すれば、嫌いなレビュワーを苦しめることができるということか...(嫌いなレビュワーとは...)。そしてこれを放置していると複雑さにつながると思う。
不透明さ
わかりにくいモジュールのこと。他人が見て、わかりずれえなってところはこれに該当するんじゃないだろうか。モジュールという言葉は Java のパッケージ的なものだけでなく、普通にサブルーチン、クラスレベルを含んだ話だと解釈した。書いている本人はわかったつもりだけど、誰かが読むと意味不明なのは、日本人の書く英語のようなものなのかなぁと思う。
アジャイルな設計とはなんなのか?
アジャイルな設計とは、プロセスやイベントではなく、ソフトウェアの構造や可読性を向上させるために、原則・パターン・プラクティスを継続的に適用する行為だそうだ!(意識たかそう!!!)そのための原則とかパターンが 8 章以降に書かれているので随時まとめていきたい。
Pinned Articles
About
ウェブ界隈でエンジニアとして労働活動に励んでいる @gomi_ningen 個人のブログです
Tags
JavaScript
PowerShell
kibana
elasticsearch
fluentd
nginx
イベント
五十嵐裕美
村川梨衣
logrotate
IoT
Scala
Java
C言語
iputils
ICMP
WUG
mastodon
Swift
AWS
Clock
Windows
アーキテクチャ
PoEAA
iOS
DeviceFarm
プログラミング言語
OS
StepFunctions
Lambda
Serverless
terraform
ポエム
RHEL
ネットワーク
GraphQL
CloudWatch
Linux
Coreutils
network
nc
telnet
LinuxKernel
fpinscala
ELB
IAM
AppSync
EFS
Gradle
english