要求と機能の良い関係を考える


## はじめに

要求を機能に落とし込む際、どの要求をどの機能で実現するべきかを迷うことがある。  
設計の経験が多い方の中には自然と対応付けられるという方も多いとも思うが、そのような方でもいざ設計レビューで意図を問われて答えに窮した経験もあるのではないだろうか。

この記事では、要求と機能の対応について意識したい点を考察する。


## 「要求」と「機能」

この記事では、「要求」のことを狭義にユーザの望む事柄と捉え、「機能」のことをシステムやソフトウェアの分割可能な1単位で実現できる動作と捉えて考察する。

> ドリルを買いにきた人が欲しいのは、ドリルではなく『穴』である

この有名な例の場合、穴がほしいという要求に対して、穴を開けるというドリルの持つ機能がある、という構図として捉える。

要求と機能という言葉には様々な使われ方がある。定義に違和感がある方は、理解しやすいよう読み替えて読んでみてほしい。

![要求と機能のイメージ](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137898/60b99037-dd35-4ce1-858f-10034cbdbb35.png)


## なぜ要求と機能の関係が重要か

要求と機能の関係についてどのような関係が良いかを論じる前に、なぜこれらの関係性が重要かを確認しておきたい。

### とりうる機能の組み合わせは要求の指数乗で増える

殆どの場合に、要求を実現する機能の対応には様々な選択ができる。  
先の例を少し改変して、「穴の開いたDIY部品がほしい」という要求の場合で考える。

![要求に対応する機能はいろいろある.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137898/59f93245-314f-4b58-a52b-0be9ffb2219d.png)

穴の開いたDIY部品がほしいという要求に対しても、様々な機能で解決できることがわかるだろう。

では、ここに別の要求「木材を接着したい」が出てきた場合を考える。

![要求に対応する機能はいろいろある_Part2.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137898/b47ed516-f0a0-4e7f-9ddb-64b4c9654f20.png)

この場合も様々な機能で解決できる。

ここで、先の「穴の開いたDIY部品がほしい」という要求と、「木材を接着したい」という要求の両方を満たす必要が出てきたとしよう。

1. 大工道具（ドリルドライバー）を買って両方解決する
1. 加工サービスのあるホームセンターで両方解決する
1. 穴あけはホムセンの加工サービスで対応し、接着はドリルドライバーを買う
1. DIY木工屋で部品を買い、接着はドリルドライバーを買う

など、様々なパターンが考えられる。解決法の数の掛け算で選択肢が増えていくことがわかるだろう。


### 要求を満たすために使えるコストは有限

ここからはソフトウェアに話を戻そう。一般にソフトウェアシステムでは、ユーザが増えるほど要求が増えていくことが知られている。  
一方で、単純にユーザ数が倍になったからといって機能開発コストがいきなり2乗に増えるケースは無いだろう。[^1]

[^1]: ソフトウェアプロジェクトは、人を追加してスケールするようなものではない、と知られて久しいように。

つまり、可能な限り少ない機能数で多くの要求を満たすことが至上命題であるわけだ。  
そのためには、適切に対応付けられた要求と機能の関係性が欠かせない。


## 要求と機能の良い関係を考える

前項では要求と機能の関係性が重要である理由を述べたが、ではどのような関係性が良いと考えるか。この論点について、本項で記す。


### 要求と機能は1対1に対応させない

先の例に記した「穴の開いた部品がほしい」と「木材を接着したい」という要求は、一つの機能で解決できる場合がある。

![要求に対する機能を集約する.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137898/14dabcc4-bb77-4bb9-8431-88195ab59c96.png)

**個々の要求を独立して機能に分解するのではなく、複数の要求を関連付けながら機能に分解し、集約できる機能を集約する**ことで、機能数を低減させ検討コストを削減することが可能。


### 要求と機能を直交させて考える

特にソフトウェアプロダクトにおいてはOSS文化などの助けもあり、多くのユーザが要求する要求については、対応する機能が部品として提供されているケースが多い。このような環境においては、要求と機能を直交[^3]させて認識すると良いと考える。

[^3]: いわゆる実装の直交性（機能間の独立性）とは別の話をしていることに注意が必要である。言葉選びが適切かわからないが、ここでは要求と仕様の対応付けマトリクスを直交的に認識することを表現している。

![要求と機能の直交.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137898/357e9ce4-d7e5-4c11-a1e6-4f7b4962207c.png)

たとえば木工のワークフローを題材にすると、このように要求軸を機能軸に分解できる。[^2]

[^2]: ここではイメージしやすいように、機能を各システムで提供できる単位から逆算して分割している。

この例では例えば **「DIY用品店」が提供できる機能** と **「ドリルドライバー」が提供できる機能** を用意することで、概ねのケースでユーザの要求を満たすことができる。

![要求と機能の直交_実現の例.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/137898/b85c7e13-b597-45c4-9577-39f04173ab95.png)

以上のように、直交性の高い要求と機能をイメージすることで、必要最低限の機能で可能な限り多くのユーザが望むシステムを実現することができると考えられる。


## おわりに：要求と機能を良い関係に維持するためには

さいごになるが、蛇足になるかもしれないが要求と機能の良い関係を維持するために必要と考えることを記して本記事を締める。

### 「工程」間の心理的安全性が大事

今ではよく認識されているように、多くの場合において要求を分析する工程と機能を実現する工程の間の心理的安全性が非常に重要と考えられる。  
要求を分析する者と機能を実現する者の間の対等な関係なしには、前述のような直交性の高い機能選択は難しいだろう。

### 「手戻り」を歓迎しよう

もし要求の分析が「上流工程」で機能を実現するのが「下流工程」という意識がある開発環境の場合、下流工程から上流工程への手戻りを歓迎すると良さそうである。  
いわゆるアジャイルの思想が浸透してきた現在では常識化しつつあるが、機能軸から要求軸へのフィードバックなしには直交性の高い機能選択は難しい。


---

以上で本記事を終える。若干ポエムみもある書きぶりになってしまったが、少しでも設計の指針になれば幸いである。