アナログ金木犀

つれづれなるまままにつれづれする

設計と冗長さに対する自分の考え

最近、いろんなところで「設計と冗長さ」に関する議論をして、あらかた自分の考えがまとまってきたので、ここで文字に起こしてみます。

ただ、この話は自分の周りのお話で読者のいる環境には当てはまらない可能性があります。また、説明の都合上言い切っているところがあります。そういう背景の違いや断定の部分は察していただけると。

前提

スキルレベル様々なチーム開発内でのお話です。

設計に冗長さはつきもの

自分の関わるプロジェクトでは単純にMVCにしようといったものではなく、Layered Architectureを採用しよう、◯◯レイヤーを作ろう、◯◯レイヤー間のやりとりはこうしよう、非同期はこうしよう、永続化はこうしよう、などまで考えて、ある程度サンプルも作りそれをチームに設計方針と共有しています。

こうすることで複雑な問題は単純化され、方針が明確で詳細であるので技術レベルに多少の差があっても、設計レベルではほとんど差が出なくなり、だれでもメンテナンスできるものになります。

と、ここまではメリットなのですが、これを採用した時に出てくるデメリットがやっぱり「冗長さ」です。

複雑な問題を単純化するものであるがゆえに、はじめから単純な問題をそれに当てはめるとどうしても「冗長」と感じてしまうんですよね。

そして、それなりのボリュームのソフトウェアを作る以上、複雑度の濃淡はさまざまで、淡い部分においては冗長さが浮き彫りになるわけです。

冗長さがなぜ悪いのか

冗長さが悪い理由を考えると「面倒」などというキーワードが出てきますが、クリティカル性があるように書くと「人の時間を無駄に使ってしまう」でしょうか。

ソフトウェア開発において、時間は限られたものでやはり重要なものです。そういう意味で本当に「無駄」と言えるならやはり「冗長さ」は悪です。

では、どこからが冗長なのか。

「冗長である」という基準はどこからなのでしょうか。「冗長さ」はどうしても主観の域を超えることができないものですが、それでもチーム開発する以上何らかの判断基準は必要です。

MVCのCが冗長だよね、という人は、ではどうしてMとVを分ける必要があると考えるのか?Cが冗長なら、MVも分けなくていいのでは?

こういう会話に対する答えは基準なしでは導けません。

とはいえ、一般的な基準があるわけでもないので、ここは自分なりの答えを出してみました。それがこれです。

そのソフトウェアあるいはそのコンテキストの一番複雑な問題に当てはめても冗長と感じるかどうか。

例えば、先の<ソフトウェアの一部の機能は簡単に実装することができ、そこに関しては冗長に感じる> という事例に対して、この基準を照らし合わせると、複雑な場所において設計は機能しており冗長と感じないので、そのプロジェクトにおいては<冗長ではない>と判断できます。(許容すべき冗長さとしても良いです。)

「Hello, World」を出力するアプリを作る場合を考えます。誰がどう考えてもMVCなどは「Hello, World」を出力する上で<冗長である>ため不要であると判断できます。(例が簡単すぎたかもしれないですが、これしか思いつかず。。)

複雑度の濃淡に偏りがあるとき。例えば、ある機能の塊だけ複雑度が高いという場合、その場合はそこだけをパッケージやモジュールで区切り、区切りによって設計方針を変えましょう。コンテキストごとに設計に一貫性があれば良いと考えています。

この基準にした理由

理由は明確で「設計方針に例外を作りたくない」からです。

たとえば、ここは簡単だから冗長さを除いた書き方にすることを許してしまったとします。 そうなると、開発者によって簡単と感じるかどうかが異なるために設計レベルで箇所によって個人差が生じ、またさらに冗長さを除いた書き方の指針がないとどんどん無法地帯化していきます。 そしてすぐに全体から統一感がなくなってしまいます。統一感のないソースコードをメンテナンスすることは難解ですし、誤解を生みやすく、またバグも生みやすいです

所感

正直言うと冗長と言っても、よほどでない限りそこまで時間は取られないし、それよりは設計の一貫性を選んだ方が良いのでは?という考えでした。それに何があるかわからないから多少は冗長にやっておいた方が良いだろうくらいの。

ただ漠然と考えは持っていたものの、うまく説明できてなかったので、ここで一度整理できて良かったです。

賛否両論ありそうですが、考えを整理するきっかけになれば幸いです。