#なぜ全て関数ではなく、クラスを使うといいのか?の検証 PHP使用
※初投稿です。
※リスクヘッジとして備忘録風を装っています。(自信がない主張をするときにするやつ)
※新米ですので用語の誤認識、説明の間違いなどあります。
ご指導のほどお願いします。
##経緯
この記事はPHPで簡単な登録機能を含んだページを作っている時に浮かんだ疑問がもとになっています。
DBへの接続や住所を都道府県名にちぎる工程をfunctionをつくって行っていました。
そんな時、ふと「PHPってクラス化って概念あるけど、function内に収めて全部関数化してしまえばクラスっていらないんじゃないの?」と頭に浮かびました。
パパっと調べてみると「全てを関数にするとコードが大量になった時に覚えるのが大変」という主張を見かけたのですが、「いや、そんなこと言ったらクラスつくるのだって一緒だわ!」となんでやねんをかましました。
それ以外にもクラス化した方がいい理由を見つけたのですが、どれもこれも眺めてるだけでは腹落ちせず…
クラス化による「カプセル化
、継承
、多様化
」というメリットは知ってはいたのですが、なかなか納得せず…
そこで実際に手を動かしてみようということで簡単なコードを書いて検証しました。
##最初に関数化とクラス化の歴史を踏まえておくといい
今の私たちからすると、「なんでこんな面倒臭いことになってるの!馬鹿なの?」と理解を放棄する経験はないですか?
物理学における電流と電子の流れの向きが違うことや、映画スターウォーズの最初のナンバリングがエピソード4ということなどです。
大体こういうことはその歴史(?)を学んでみると「あぁ、まぁそれなら仕方ないか」と納得できることもあります。
納得してしまえば、それだけで記憶には残りやすくなるので自分的には腹落ちできます。なので今回もそれを狙っていきます。
そこでwikiってみたところ…
1960年くらいの最初のプログラミング言語の時は手続き(シンプルに行わせたい処理を上から順に書いていくこと)や関数を作成していたそうな。
ただ、時代と共に行わせたい処理が複雑化、増大化してくるとアップアップになってくる。
そこで1970年代に行わせたい処理に必要なデータを渡すと、なんかうまくやってくれる万能な機構(つまりはオブジェクト)を作って必要な時に随時呼び出せばコードがぐちゃぐちゃにならないぞ、と提唱された。
…
何となくこんな感じでとらえました。
詳しいことは後程、このような素晴らしい資料を読んで身に着けます。
要するに大事なことは、歴史的には
関数という概念 (先) → クラスという概念 (後)
ということです。
ということは少なからず、クラスというものは関数の仕様に似ていて、かつ、関数よりも秀でた部分を有しているという想像ができます。
さて、長々となってきたので実物の方を早速見ていきましょう。
##いざ、実践(クラス化のいいところ解説)
最初は都道府県名をコードに置換するところから始まりました。
function pref_replace($target){
$arr = [
"北海道" => 1 ,
"青森県" => 2 ,
"岩手県" => 3 ,
"宮城県" => 4 ,
"秋田県" => 5 ,
"山形県" => 6 ,
"福島県" => 7 ,
"茨城県" => 8 ,
"栃木県" => 9 ,
"群馬県" => 10 ,
"埼玉県" => 11 ,
"千葉県" => 12 ,
"東京都" => 13 ,
"神奈川県" => 14 ,
"新潟県" => 15 ,
"富山県" => 16 ,
"石川県" => 17 ,
"福井県" => 18 ,
"山梨県" => 19 ,
"長野県" => 20 ,
"岐阜県" => 21 ,
"静岡県" => 22 ,
"愛知県" => 23 ,
"三重県" => 24 ,
"滋賀県" => 25 ,
"京都府" => 26 ,
"大阪府" => 27 ,
"兵庫県" => 28 ,
"奈良県" => 29 ,
"和歌山県" => 30 ,
"鳥取県" => 31 ,
"島根県" => 32 ,
"岡山県" => 33 ,
"広島県" => 34 ,
"山口県" => 35 ,
"徳島県" => 36 ,
"香川県" => 37 ,
"愛媛県" => 38 ,
"高知県" => 39 ,
"福岡県" => 40 ,
"佐賀県" => 41 ,
"長崎県" => 42 ,
"熊本県" => 43 ,
"大分県" => 44 ,
"宮崎県" => 45 ,
"鹿児島県" => 46 ,
"沖縄県" => 47
];
$keys = array_keys($arr); //県名一覧取得
$vals = array_values($arr); //コード一覧取得
$pref_code = str_replace($keys,$vals,$target); //引数の県名をコードに置換
return $pref_code;
}
このような関数を作り、県名をコードに置換したい時に
require "pref.php";
$pref_code = pref_replace("長崎県");
という対応をしておりました。
ただ、他にもDBに登録する際に登録ページの方からPOSTデータ$POST_['col_2'] = collumn2
をDBのテーブルのカラム名name
に変更したい時など、置換することが多くなってきました。
そこで毎回、置換する関数を書いていたのですが、「これ、keyとvalを使って置換するのはどの関数でも一緒じゃね?どうにかして纏められね?こういう時にクラス化の多様化
するんちゃう?」と考えるようになりました。
さて、他のファイルでクラスを作ります。
class Replace{
private $keys;
private $vals;
protected $arr;
public $res;
public function __construct($name){
$this->keys = array_keys($this->arr);
$this->vals = array_values($this->arr);
$this->res = str_replace($this->keys,$this->vals,$name);
}
}
そこから都道府県コードを並べる配列を追加(継承
)していきます。
class Pref extends Replace{
public $arr = [
"北海道" => 1 ,
"青森県" => 2 ,
"岩手県" => 3 ,
"宮城県" => 4 ,
"秋田県" => 5 ,
"山形県" => 6 ,
"福島県" => 7 ,
"茨城県" => 8 ,
"栃木県" => 9 ,
"群馬県" => 10 ,
"埼玉県" => 11 ,
"千葉県" => 12 ,
"東京都" => 13 ,
"神奈川県" => 14 ,
"新潟県" => 15 ,
"富山県" => 16 ,
"石川県" => 17 ,
"福井県" => 18 ,
"山梨県" => 19 ,
"長野県" => 20 ,
"岐阜県" => 21 ,
"静岡県" => 22 ,
"愛知県" => 23 ,
"三重県" => 24 ,
"滋賀県" => 25 ,
"京都府" => 26 ,
"大阪府" => 27 ,
"兵庫県" => 28 ,
"奈良県" => 29 ,
"和歌山県" => 30 ,
"鳥取県" => 31 ,
"島根県" => 32 ,
"岡山県" => 33 ,
"広島県" => 34 ,
"山口県" => 35 ,
"徳島県" => 36 ,
"香川県" => 37 ,
"愛媛県" => 38 ,
"高知県" => 39 ,
"福岡県" => 40 ,
"佐賀県" => 41 ,
"長崎県" => 42 ,
"熊本県" => 43 ,
"大分県" => 44 ,
"宮崎県" => 45 ,
"鹿児島県" => 46 ,
"沖縄県" => 47
];
}
こうすることで、使いたい時に
require "class.php";
$pref_code = new Pref("長崎県");
echo $pref_code->res; //「43」と表示
と使うことができます。
また、カラム名の置換をしたかった場合
class MainCollumn extends Replace{
public $arr = [
"collumn1" => "id" ,
"collumn2" => "name" ,
"collumn3" => "title" ,
"collumn4" => "content" ,
"collumn5" => "created_at" ,
"collumn6" => "updated_at" ,
];
}
みたいな感じで書いてあげれば、
require "class.php";
$mainCollumn = new MainCollumn("collumn2");
echo $mainCollumn->res; //「name」と表示
と処理することができます。
つまり、新しく置換したい項目が出てくるたびに、それを連想配列にし、Replaceクラスを継承して$arrで宣言してあげれば簡単に置換機能が付いたインスタンスを生成できるということになります。
##つまり何がイイか?
今回私が関数でなくて、クラスを今後も使っていこうと思ったことはクラスの便利機能である「多様化
」です。
多様化というのは、例えば今回で言うところの、
「△△という置換表をもとに、〇〇という文字を××に置換したい」
という機能を様々なところで使いまわしができるということです。
「都道府県コード表をもとに、都道府県名をコードに置換したい」
だけではなく
「テーブルのカラム表をもとにカラム番号をカラム名に置換したい」
という機能も作れていますよね。
##おわりに
「でもそれ、関数でできるよ。」
「いや、クラス化のメリットそこじゃねーから」
など、論破する点もあると思いますが、そこはやはり「備忘録」ということで許してください。
今回学ぶべき教訓は、
人はアウトプットによって知識が定着するということですね。
今後も「うわーそういうことだったのか、でも確信はないなぁ…、でも定着させたいなぁ…」
というときに徒然なるままに書いていきます。
##今回書いてて思ったこと・今回に限らずいまだにわからないこと
・引数っていつから生まれたの?1960年とかの関数からあったの?(オブジェクト指向が生まれてから??)
・1960年代の人めっちゃ頑張っててすごいね
・プログラミング言語の歴史もっと勉強しないと…
・クラス内で行われるDI(でぃぺんでんしーいんじぇくしょん)なるものがさっぱりわからん
参考文献
関数とメソッドの違いがわからなくて少し調べたので自分なりにまとめてみた https://qiita.com/T-N0121/items/ecf5b911463ac9fa1d3eオブジェクト指向が1%も理解できないので、歴史を勉強した。
https://qiita.com/yosshi4486/items/8f526416a7649cd2c2be