オブジェクト指向が0.005%理解できる記事

# とあるWeb制作会社にて
上司くん「なあ、やめ太郎くん。Aくんが作ったこのページにハンバーガーメニュー付けてぇや」
ワイ「はい！よろこんで！（Aくんにやらせろや、ダボが！）」
# とりあえず作ってみる

ワイ「メニュー部分のタグにはmenuっちゅうIDが付いとるから・・・」
ワイ「その要素を取ってきて定数menuに格納するんや。」

```javascript:hamburgerMenu.js
const menu = document.getElementById("menu");
//menuというIDを持つ要素を取ってきて定数menuに格納　。
```

ワイ「ハンバーガーボタンも定数に入れとこ」

```javascript:hamburgerMenu.js
const hamburgerBtn = document.getElementById("hamburgerBtn");
//hamburgerBtnというIDを持つ要素を取ってきて定数hamburgerBtnに格納。
```

ワイ「初期状態ではメニューは非表示やな」

```javascript:hamburgerMenu.js
menu.style.display = "none";
//初期状態ではメニューを非表示に。
```

ワイ「ハンバーガーボタンをクリックしたら、メニュー開閉用の関数が実行されればええねん」

```javascript:hamburgerMenu.js
hamburgerBtn.addEventListener("click", hideAndShow);
//ハンバーガーボタンをクリックしたらメニューの表示非表示を切り替える関数が実行されるようセット。
```

ワイ「メニュー開閉用の関数はこないな感じやな。閉じとったら開く、開いとったら閉じる。」

```javascript:hamburgerMenu.js
//メニューの表示非表示を切り替える関数
function hideAndShow(){
	if(menu.style.display === "none"){
		//現在メニューが非表示なら表示させる。
		menu.style.display = "block";
	}else{
		//現在メニューが表示されているなら非表示に。
		menu.style.display = "none";
	}
}
```

ワイ「・・・動きよったわ！完成や！」

```javascript:hamburgerMenu.js（完成版）
const menu = document.getElementById("menu");
//menuというIDを持つ要素を取ってきて定数menuに格納　。

const hamburgerBtn = document.getElementById("hamburgerBtn");
//hamburgerBtnというIDを持つ要素を取ってきて定数hamburgerBtnに格納。

menu.style.display = "none";
//初期状態ではメニューを非表示に。

hamburgerBtn.addEventListener("click", hideAndShow);
//ハンバーガーボタンをクリックしたらメニューの表示非表示を切り替える関数が実行されるようセット。

//メニューの表示非表示を切り替える関数
function hideAndShow(){
	if(menu.style.display === "none"){
		//現在メニューが非表示なら表示させる。
		menu.style.display = "block";
	}else{
		//現在メニューが表示されているなら非表示に。
		menu.style.display = "none";
	}
}
```

#上司くんに提出してみる
ワイ「できました！ユーザビリティを考慮した結果、敢えてアニメーションとか付けずにシンプルな実装になってます〜」
上司くん「ええで、ええで！こないな感じや」
ワイ「おおきに、ほな失礼します」
# 時は経ち、上司くんがナイスな追加仕様を思いつく
<b>〜１ヶ月後〜</b>
上司くん「やめ太郎くん、すまん」
ワイ「えっ？」
上司くん「画面の右上のハンバーガーボタンだけやなく、メニュー自体の一番下のとこにも閉じるボタン付けてや」
ワイ「ええですよ〜（前の時に言えや、ボケが！）」

#先月書いたJSを修正していく
ワイ「先月書いたコードなんて忘れてもうたわ・・・<b>3秒経ったら他人のコード</b>いうやつや・・・まぁ何とかなるやろ」
ワイ「要はハンバーガーボタンのほかに、閉じるボタンがクリックされた時もメニューが開閉すればええねん」
ワイ「閉じるボタンにはcloseBtnいうIDを付けといたから・・・こんな感じや。」

```javascript:hamburgerMenu.js
/* 追加コード ここから */
const closeBtn = document.getElementById("closeBtn");
//closeBtnというIDを持つ要素を取ってきて定数closeBtnに格納。
```

ワイ「そんでそのボタンをクリックした時にもメニュー開閉関数が実行されんねん」
ワイ「メニュー開閉関数は<b>どれやったっけ</b>・・・あぁ、これや、hideAndShowや」

```javascript:hamburgerMenu.js
closeBtn.addEventListener("click", hideAndShow);
//閉じるボタンをクリックした時にもメニューの表示非表示を切り替える関数が実行されるようにセット。
/* 追加コード ここまで*/
```

ワイ「完成や」

```javascript:hamburgerMenu.js（完成版・閉じるボタンあり）
const menu = document.getElementById("menu");
//menuというIDを持つ要素を取ってきて定数menuに格納　。

const hamburgerBtn = document.getElementById("hamburgerBtn");
//hamburgerBtnというIDを持つ要素を取ってきて定数hamburgerBtnに格納。

menu.style.display = "none";
//初期状態ではメニューを非表示に。

hamburgerBtn.addEventListener("click", hideAndShow);
//ハンバーガーボタンをクリックしたらメニューの表示非表示を切り替える関数が実行されるようセット。

//メニューの表示非表示を切り替える関数
function hideAndShow(){
	if(menu.style.display === "none"){
		//現在メニューが非表示なら表示させる。
		menu.style.display = "block";
	}else{
		//現在メニューが表示されているなら非表示に。
		menu.style.display = "none";
	}
}

/* 追加コード ここから */
const closeBtn = document.getElementById("closeBtn");
//closeBtnというIDを持つ要素を取ってきて定数closeBtnに格納。

closeBtn.addEventListener("click", hideAndShow);
//閉じるボタンをクリックした時にもメニューの表示非表示を切り替える関数が実行されるようにセット。
/* 追加コード ここまで*/
```

ワイ「でも、なんか、あんま読みやすくないな、ワイのコード・・・」
ワイ「1ヶ月も経つと、<b>どの変数に何が入ってて、どの関数が何のための機能なのか</b>忘れてまうわ」
ワイ「コメントがあるから何とかなるけども・・・」
ワイ「先輩方のコードはもっと読みやすかったような・・・」
ワイ「たしか<b>オブジェクト指向</b>いうやつで書いてはんねん、あの人らは・・・」
ワイ「<b>オブジェクト指向</b>で書けば読みやすくなるんかな・・・」

# オブジェクト指向で書き直してみる
ワイ「よっしゃ、ワイもいっちょ<b>オブジェクト指向</b>いうやつで書いてみるで」
ワイ「<b>オブジェクト指向</b>いうんは、たしか<b>オブジェクト同士がメッセージングし合って仕事をして</b>くれるらしいねん・・・どんな状況やねんそれ」
ワイ「よう分からんけど、まずは<b>オブジェクトを生成するための設計書</b>みたいな<b>class</b>いうんを書くんや」

# classを書いてみる
ワイ「<b>ハンバーガーメニュー設定くん</b>ちゅう装置を作って、そいつに指示するイメージで考えてみよか」
ワイ「ほな、クラスの名前は<b>HamburgerMenuSetteikun</b>（ハンバーガーメニュー設定くん）や」

```javascript:hamburgerMenuOOP.js
//ハンバーガーメニュー設定くん（以下、設定くん）の設計図となるクラス
class HamburgerMenuSetteikun{
}
```

ワイ「それをnewして設定くん1号を生成するんや」

```javascript:hamburgerMenuOOP.js
//ハンバーガーメニュー設定くんを実際に生成して、設定くん1号と名づける。
const setteikun1gou = new HamburgerMenuSetteikun("menu");
```

ワイ「ほんでその子に指示をするんや」
ワイ「設定くんは、ハンバーガーボタン設定メソッドを持ってんねや。それを実行せえ、と。」

```javascript:hamburgerMenuOOP.js
//設定くん1号の、ハンバーガーボタン設定メソッドを実行。IDとして「hamburgerBtn」を指定。
setteikun1gou.setBtn("hamburgerBtn");
```

ワイ「やりたい事はこんな感じや。」
ワイ「ほなこれを実現するために<b>class</b>の方に戻るで」

# classの中にコンストラクタを書く
ワイ「constructorいう名前のメソッド・・・まぁ設定くんが持ってる関数みたいなもんやな」
ワイ「設定くんが生成される時、最初にこのconstructorメソッドが実行されんねん」

```javascript:hamburgerMenuOOP.js
	//コンストラクタ・・・設定くんが作られたとき、最初に実行される処理。
	//プロパティはコンストラクタの中で設定します。
	constructor(menuId){ //menuIdには"menu"という文字列が入ってくる。
		//thisは作成された設定くんを指します。
		//この設定くんにとってのメニューとは、menuというIDを持った要素だよ、と設定。
		this.menu = document.getElementById(menuId);
		//初期状態ではメニューを非表示に。
		this.menu.style.display = "none";
	}
```

# classの中にメソッドを定義していく
ワイ「設定くんが持ってる技をclassの中に書くねん」
ワイ「今回、技は基本的に１個だけや。メニュー開閉ボタンを設定してくれる<b>setBtn</b>や。」
ワイ「引数で指定されたボタンがクリックされたら、メニューが開閉するように設定する技や」

```javascript:hamburgerMenuOOP.js
	//ハンバーガーボタンを設定するメソッド
	setBtn(btnId){
		//btnId(つまりhamburgerBtn)というIDを持つ要素を定数btnに格納。
		const btn = document.getElementById(btnId);
		//hamburgerBtnがクリックされたら、
		btn.addEventListener("click", ()=>{
			//メニューの表示非表示を切り替えるメソッドを実行。
			this.hideAndShow();
		});
	}
```

ワイ「実際に開閉する部分の処理はやっぱり別メソッドにしておこか。」

```javascript:hamburgerMenuOOP.js
	//メニューの表示非表示を切り替えるメソッド
	hideAndShow(){
		if(this.menu.style.display === "none"){
			//現在メニューが非表示なら表示させる。
			this.menu.style.display = "block";
		}else{
			//現在メニューが表示されているなら非表示に。
			this.menu.style.display = "none";
		}
	}
```

ワイ「できたで！」

```javascript:hamburgerMenuOOP.js（完成版）
//ハンバーガーメニュー設定くん（以下、設定くん）の設計図となるクラス
class HamburgerMenuSetteikun{
	//コンストラクタ・・・設定くんが作られたとき、最初に実行する処理。
	//プロパティはコンストラクタの中で設定します。
	constructor(menuId){ //menuIdには"menu"という文字列が入ってくる。
		//thisは作成された設定くんを指します。
		//この設定くんにとってのメニューとは、menuというIDを持った要素だよ、と設定。
		this.menu = document.getElementById(menuId);
		//初期状態ではメニューを非表示に。
		this.menu.style.display = "none";
	}
	//ハンバーガーボタンを設定するメソッド
	setBtn(btnId){
		//btnId(つまりhamburgerBtn)というIDを持つ要素を定数btnに格納。
		const btn = document.getElementById(btnId);
		//hamburgerBtnがクリックされたら、
		btn.addEventListener("click", ()=>{
			//メニューの表示非表示を切り替えるメソッドを実行。
			this.hideAndShow();
		});
	}
	//メニューの表示非表示を切り替えるメソッド
	hideAndShow(){
		if(this.menu.style.display === "none"){
			//現在メニューが非表示なら表示させる。
			this.menu.style.display = "block";
		}else{
			//現在メニューが表示されているなら非表示に。
			this.menu.style.display = "none";
		}
	}
}

//ハンバーガーメニュー設定くんを実際に生成して、設定くん1号と名づける。
const setteikun1gou = new HamburgerMenuSetteikun("menu");

//設定くん1号の、ハンバーガーボタン設定メソッドを実行。IDとして「hamburgerBtn」を指定。
setteikun1gou.setBtn("hamburgerBtn");
```
ワイ「なんや、前のコードより長くなってもうてるやん・・・」

# 読んでみる
ワイ「コードの量は増えてもうたけど、設定くん関連の処理がclassの中にまとまってるから、<b>どこからどこまでが設定くん関連のコードなのか</b>分かりやすいな」
ワイ「あと、関数いうかメソッドも全部classの中に書いてあるから<b>このメソッドたちは設定くんのためのもの</b>いうのも一目瞭然やな」
ワイ「constructorいうのも名前が決まってるし、<b>設定くんが最初に実行する処理や</b>いうのも一目瞭然や」
ワイ「前のコードん時は<b>hideAndShow</b>が<b>設定くんのための関数</b>いう感じがせぇへんかったもんな」
ワイ「前のコードでメニュー開閉ボタンを設定する時は・・・」

```javascript:hamburgerMenu.js
hamburgerBtn.addEventListener("click", hideAndShow);
//ハンバーガーボタンをクリックしたらメニューの表示非表示を切り替える関数が実行されるようセット。
```

ワイ「・・・こないな感じで、別に分かりにくくはなかったけど、オブジェクト指向の方は・・・」

```javascript:hamburgerMenuOOP.js
//設定くん1号の、ハンバーガーボタン設定メソッドを実行。IDとして「hamburgerBtn」を指定。
setteikun1gou.setBtn("hamburgerBtn");
```

ワイ「<b>設定くん1号</b>いうのが頭に付いてるから、<b>設定くんが自分のメソッドを実行してる感</b>が出てんねん」
ワイ「閉じるボタンを追加する時もこれだけやで」

```javascript:hamburgerMenuOOP.js
//ボタンを追加したい時は、IDを変えて再度ボタン設定メソッドを実行。
setteikun1gou.setBtn("closeBtn");
```

ワイ「なんや、オブジェクト指向で書いた方が<b>コンピュータにやらせたい事</b>と<b>コードの見た目</b>が近くなるから、ワイのような<b>ザコーダー</b>でも読みやすいコードになるな」
ワイ「<b>ヒューマンリーダブルなコード</b>いうやつや」

# オブジェクト指向っぽくやってみた感想
ワイ「なんや、オブジェクト指向いうんは大規模開発向けやと思っとったけど、小規模なコードでも意外といい感じやないか」
ワイ「メソッドは各クラスの中に書いてあるから、<b>その装置の持つ機能</b>やって分かりやすいしな」
ワイ「プロパティはそのオブジェクトの状態とか情報を入れとくのに使えるな」
ワイ「ただ今回のような<b>小さいプログラム</b>なら<b>普通に処理や関数を書き連ねたほうが普通に速い</b>な。<b>手続き型</b>いうやつやな。」
ワイ「こんなページ、どうせ今後たいした修正や運用もないしな。1年後にはまたデザイン変えんねん。」
ワイ「もっと大規模な開発の場合とかは、<b>いろんな装置たちを並べてそいつらに仕事をさせる</b>イメージでプログラミングできるから、分かりやすそうやな」
# 例えば・・・
ワイ「<b>人間クラス</b>を継承した<b>DQNクラス</b>から生成した<b>たかしオブジェクト</b>が、<b>強盗メソッド</b>を実行すんねん。」
ワイ「それを受けて<b>銀行オブジェクト</b>が<b>出金メソッド</b>を実行すんねやな。」
ワイ「<b>顧客オブジェクト</b>の<b>残高プロパティ</b>は<b>0</b>や。」
ワイ「ほんなら<b>たかしオブジェクト</b>は返り値として受け取った<b>現金</b>を<b>タクシーの運ちゃんオブジェクト</b>に渡して、<b>逃走メソッド</b>を実行すんねやな。」
ワイ「たかしの<b>前科プロパティ</b>がまた1増えるんや」
ワイ「それがきっと<b>オブジェクト同士がメッセージングし合って仕事をしてくれる</b>いうやつなんやろな」
ワイ「仕事いうか<b>犯罪</b>やけどな」
ワイ「<b>オブジェクト指向犯罪</b>や」

# まとめ
ワイ「普通に処理や関数を書き連ねる場合（<b>手続き型</b>）は、<b>自分自身が呪文を唱えて戦ってた</b>感じやったけど、オブジェクト指向の場合は<b>ポケモンか何かを生み出して、そいつらに指示を出してる</b>感じやな」
ワイ「最初にそのポケモンたちの仕様を考えるのが面倒やけど、ポケモンを生み出したあとは<b>その子らが戦ってくれる</b>感じやから、<b>監督業に専念できる</b>感じでちょっと楽やねん」