エンジニアとしての日記2 ソフトウェアとは何か

 ## 

以下からの転記です

https://codenote.online/edit/notebooks/82 

or

https://zenn.dev/aa/articles/b85d4fc5de8083d6ed07

## はじめに

プログラマーは毎日プログラムを書いています。そして、プログラムは集合として一つのソフトウェアを構築するために記述されています。しかし、ソフトウェアとは何かについて考える機会は意外と少ないように思います。

ここでソフトウェアの物理的な定義はプログラムの集合とします。ではプログラムとは何でしょうか。概念的なことはおいておき、感覚的にな説明は明らかです。僕らが日常的に書いているこういうやつのことです。

```typescript
console.log("Hello world")
```

自分の中ではソフトウェアの定義は明確で「特定の問題に対しての解決パターンをプログラムで表現したもの」です。キーワードは「**特定の問題**」と「**解決パターン**」と「**プログラム**」です。このことについて書いてみます。

## プログラムの原理

ソフトウェアとは何かについて考える前に、プログラムの原理を考えてみます。プログラムは電気で表現された0と1のを組み合わせを用いて計算し、別の0と1の組み合わせを生みます。これがプログラムの動作原理です。

そして、0と1の数を増やすと指数関数的に組み合わせの通数が増えていきます。プログラムはこの0と1の組み合わせパターンと情報を1:1に対応づけることで世の中のあらゆる情報を表現します。

そしてこのプログラムは0と1を直接書くのではなく、プログラミング言語を用いて記述されます。
ではここで、プログラミング言語は何故必要なのでしょうか。

## プログラミング言語の必要性

プログラミング言語を使う理由は0と1の羅列を記述するだけで人間が意味を感じ取れる計算を構築するのが非常に困難なためです。コンピューターの計算効率が多少わるくなっても、0と1でなくプログラミング言語を用いてプログラムを書き、再度書いたプログラムを0と1の電気的な処理に変換して計算します。**プログラミング言語は人間が計算をしやすくするため**に生まれています。

## プログラミング言語が出来ること

プログラミング言語を利用すれば基本的にコンピューターが実行可能な全ての計算を実行することができます。具体的に実行したい処理をプログラミング言語を用いて記述したのがプログラムです。

したがって、必要に応じてプログラムを書いていけばあらゆる計算問題が解決可能です。

## プログラムをソフトウェアにする理由

プログラムがあらゆる計算を実行可能であることを説明しました。それでもプログラムは集合としてまとめあげられて、特定の機能を持つソフトウェアという形にまとめあげられます。

プログラミング言語さえあればあらゆる問題が計算できるのに、何故フレームワークやパッケージサービスなどのようにソフトウェアという単位でプログラムが提供される必要あるのでしょうか。

それはプログラミング言語ができた理由と同じで、プログラミング言語だけではまだまだ問題を扱うのが難しいためです。

## 汎用性と扱いやすさのトレードオフ

0と1(機械語)からプログラミング言語になると、簡単になる一方で様々な制約がうまれます。あらゆる計算が可能とはいえ、0と1だけでプログラムを記述した方が計算効率を最適化できます。
また、フレームワークやライブラリよりもプログラミング言語そのものの方が汎用性が高いのですが、**特定の問題**を扱うにはフレームワークやライブラリーなどの方が扱い易いのです。

ここで「特定の問題」というキーワードがようやくでてきました。ソフトウェアというのは、汎用性とのトレードオフに「特定の問題」に対して扱い易さを提供するものだと言えます。

ソフトウェアは「特定の問題」を「人間が扱いやすくなる」ためにあります。

## 何故ソフトウェアは人間が特定の問題を扱うのを分かりやすくするのか

簡単な1ページのWebサイトを構築することを考えてみましょう。Webサイトを構築したことが無い人は、Webサイトを構築するために、画面に構造をつくる"HTML"があることやレイアウトを表現する"CSS"があること、挙動を制御する"JavaScript"があること、データを保持するDBがあることなどは想像がつきません。**人はそもそも問題と問題の解決パターンが理解できていません。**

しかしフレームワークはそもそもWebサイトを作るためにはどのような枠組みで考えればいいかを教えてくれ、それぞれに対する解決パターンも提供しれくれます。

つまりソフトウェアは「**特定の問題に対する解決のパターン**」を教えてくれるのです。これはあらゆるソフトェアに共通する性質です。

例えばブログサイトでは、そもそもブログにはブログを書くことの他にも他人をフォローすること、閲覧数を分析すること、記事をストックすること、記事を検索すること、記事をブログの表示順を並べ変えること、記事をカテゴリー毎に分けて管理することなど、様々な問題を認知させ解決方法を提供しれくれます。

これがソフトウェアです。

## ソフトウェアの目的
ソフトウェアの目的は特定の問題に対しての解決パターンを提示し、**問題を扱いやすくする**ことです。繰り返しになりますが、扱いやすくなくても良いのであればプログラミング言語そのもの、あるいは0と1のバイナリの方が優れています。

それでもソフトウェアを利用するのは想定する**問題領域を狭める代わりに扱いやすさを手に入れるため**です。

## ソフトウェアを作る上で重要なこと
特定問題に対して解決パターンを与え扱いやすくするのがソフトウェアの目的であるとすると、必然的にソフトウェアを作るうえで重要なことが見えてきます。

- 特定問題を明らかにする
- 解決パターンを明らかにする
- 扱いやすい

### 問題を明らかにする
ソフトウェアは特定の問題を想定することで、**汎用性とトレードオフ**に利便性を与えるものです。ここで重要なのが想定する問題に制限をかけていくことです。問題に対する一定の想定を置くことで始めてプログラミング言語ではなくソフトウェアを考えることができます。

SaaS、ノーコード、フレームワーク、ライブラリー、様々なソフトウェアがありますがこれらは全て問題範囲の限定によって特定の解決パターンを提示し、汎用性と利便性の新たなトレードオフを提示しているものと捉えることができます。

### 解決パターンを明らかにする
扱いたい問題領域を定まったとしても、まだ問題に対して何をすればいいかは人間にとって明らかではありません。ブログサイトの例のように、そもそも問題にどのような行為が関係するのかを洗い出しセットにして提供することで、ブログに関係する行動が一通り楽になる必要があります。

### 扱いやすくする
「扱いやすい」というのは、人間が感じることです。ここで、"扱いやすさ"は人間の主観に依存するので、"誰にとって扱いやすくする必要があるのか"を意識するのがとても重要です。

例えばブログサイトでいうと扱いやすいと感じる必要があるのは第一にブログを書く人や読む人です。

次に、ブログサイトのソフトウェアを書くプログラマ自身です。プログラムを見ると、様々なクラスや関数などが定義されています。これらもソフトウェアの中の部分的なソフトウェアです。これらの部分的なソフトウェアはプログラマ自身のためにあります。

ソフトウェア全体として提供される相手へ分かりやすいものが提供される必要があると同時に、ソフトウェアを書く内部のプログラマーへも分かりやすくプログラムを構築する必要があります。

## 結論
ソフトウェアは特定の問題に対しての解決パターンをプログラムで表現したものだと述べました。このことから明らかになるのは、ソフトウェアでは問題の定義と解決パターンの明確化が必要であるということです。また、その目的は扱いやすさを提供することであり、エンドユーザーの扱いさとプログラマ自身の扱いやすさの問題があることを述べました。ソフトウェアが何かを考えることで、ソフトウェアで意識すべきことをより明らかにすることができます。

この記事が気に入ったらサポートをしてみませんか?