「ライブラリ」と「フレームワーク」は何が違うのか

>こちらの記事は、2019年2月に公開された『 [The Difference Between a Framework and a Library](https://www.freecodecamp.org/news/the-difference-between-a-framework-and-a-library-bd133054023f/) 』の和訳になります。
本投稿は転載であり、[本記事](https://medium.com/@babydegu/%E3%83%A9%E3%82%A4%E3%83%96%E3%83%A9%E3%83%AA-%E3%81%A8-%E3%83%95%E3%83%AC%E3%83%BC%E3%83%A0%E3%83%AF%E3%83%BC%E3%82%AF-%E3%81%AF%E4%BD%95%E3%81%8C%E9%81%95%E3%81%86%E3%81%AE%E3%81%8B-eb2770dc0948)はこちらになります。


# はじめに
開発者はしばしば「ライブラリ」と「フレームワーク」という言葉を混合して使うことがありますが、両者は異なるものです。

ライブラリとフレームワークはどちらも、開発上の一般的な問題の解決に使われる、他の誰かが書いたコードの集まりです。

たとえば、あるプログラムであなたは文字列の操作を実装するとします。あなたが DRY(Don’t Repeat Yourself/繰り返しを避ける)原則に従うならば、次のような再利用可能な関数を作成すると思います。

```javascript
function getWords(str) {
   const words = str.split(' ');
   return words;
}
function createSentence(words) {
   const sentence = words.join(' ');
   return sentence;
}
```

そう、この瞬間、あなたはまさに「ライブラリ」を自作したのです。

ライブラリやフレームワークは何も特別なものではありません。それらはどちらも開発上の一般的な問題をより簡単に解決できるように、他の誰かが書いた再利用可能なコードの集まりなのです。

私はよくWeb開発における概念のメタファーとして、家を使います。

例えばライブラリはIKEAに行くようなものです。あなたはすでに自分の家を持っていますが、家具が少し足りないとします。ですが、テーブルを一から作る気にはなれません。そんな時、IKEAに行けば数ある選択肢の中から気に入ったものを持ち帰ることができます。それを選ぶのはあくまでも、あなたです。

一方、フレームワークはモデルハウスを建築するようなものです。いくつかのテンプレートの中から、限られたアーキテクチャとデザインを選ぶことができます。あなたが基本的に選べるのは請負業者とテンプレートのみ。あとはその業者がピンポイントであなたが介入できるところを教えてくれます。

# ライブラリとフレームワークの技術的な違いとは

ライブラリとフレームワークの技術的な違いは、「制御の反転」と呼ばれる用語にあります。

ライブラリを使用する時、アプリケーションのフローはあなたが管理することになります。あなた自身がライブラリの機能を呼び出すタイミングと場所を指定します。対してフレームワークを使用する時、フローの管理はフレームワークが行います。そのフローの中で、あなたがコードで介入できる場所がいくつか用意され、フレームワークは必要に応じてそれらを呼び出します。

jQuery(ライブラリ)とVue.js(フレームワーク)を使用した例を見てみましょう。

例えば、エラーが発生した時にエラーメッセージを表示するようにしたいとします。この例では、ボタンをクリックするとエラーが発生するものとします。

**jqueryの場合：**

```html
<!-- index.html -->
<html>
   <head>
      <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
      <script src="./app.js"></script>
   </head>
   <body>
      <div id="app">
         <button id="myButton">Submit</button>
       </div>
   </body>
</html>
```

```javascript

// app.js
let error = false;
const errorMessage = 'An Error Occurred';
$('#myButton').on('click', () => {
  error = true; // pretend some error occurs and set error = true
  if (error) {
    $('#app')
       .append(`<p id="error">${errorMessage}</p>`);
  } else {
    $('#error').remove();
  }
});
```

jQueryの使われ方に注目してください。まさに我々が任意の場所でjQueryの機能を呼び出しているのがわかるかと思います。これは「図書館」へ行き、必要に応じて本を棚から取り出すのとよく似ています。

これは、jQueryの関数を一度呼んでしまえばインプットが不要になると言っているのではありませんが、jQuery自体はこのような関数の集まりなのです。つまり主導権は我々にあります。

**Vue.jsの場合:**

```vuejs
<!-- index.html -->
<html>
   <head>
      <script src="https://cdn.jsdelivr.net/npm/vue"></script>
      <script src="./app.js"></script>
   </head>
   <body>
      <div id="app"></div>
   </body>
</html>
```

```javascript
// app.js
const vm = new Vue({
  template: `
     <div id="vue-example">
       <button @click="checkForErrors">Submit</button>
       <p v-if="error">{{ errorMessage }}</p>
     </div>`,
  el: '#app',
  data: {
    error: null,
    errorMessage: 'An Error Occurred',
  },
  methods: {
    checkForErrors()  {
      this.error = !this.error;
    },
  },
});
```

Vueは空白を埋めるようにして使われます。Vueコンストラクターはいくつかのプロパティを持つオブジェクトです。それは私たちに何が必要かを教えてくれ、舞台裏でそれらがいつ必要になるかを決定します。Vueはプログラムの制御を反転するため、主導権はVueにあるのです。

ライブラリとフレームワークの違いはこのように「制御の反転があるかどうか」にあります。

# “opinionated”と“un-opinionated”

様々なライブラリやフレームワークはよく“opinionated”(自己主張的)または“un-opinionated”(非自己主張的)であると表現されます。これらの表現はあくまで主観に基づくものですが、こうしてコードを書いていく過程における開発者側の自由度を定義しようとしているのです。

定義上、フレームワークはそうでないものと比べて“opinionated”であると言えます。なぜなら「制御の反転」にはアプリケーション設計における自由度をある程度犠牲にする必要があるからです。

繰り返しますが、あるソフトウェアがどの程度“opinionated”であるかというのは主観的なものです。例えば、Angularは個人的にとても“opinionated”なフレームワークで、Vue.jsは比較的“opinionated”ではないフレームワークだと感じます。

# まとめ

- フレームワークとライブラリはどちらも、一般的なソフトウェアの機能を比較的簡単な方法で実装できるように、他の誰かが書いたコードの集まりです。
- フレームワークはプログラムの制御を反転します。フレームワークは必要な情報を開発者に尋ねていきます。しかし、ライブラリは異なります。プログラマは必要な場所で、必要な時にライブラリを呼び出します。
- ライブラリまたはフレームワークが開発者に与える自由度は、同時にそれがどの程度“opinionated”であるかを示します。

読んでくれてありがとう！

# 翻訳協力
Author: [Brandon Wozniewicz](https://www.freecodecamp.org/news/author/brandon/)
Thank you for letting us share your knowledge!

記事選定: yumika tomita 
翻訳/技術監査: siho1 / @nyorochan
Markdown化: @aoharu