オブジェクト指向の継承をあるWEBデザイナーに説明した2
「先週教えてもらったオブジェクト指向プログラミング(以下OOP)ですけど、結局意義がよくわからなかったですよ」
「まあ、適当な説明だし」
「結局あんま意味なさそうですね」
「まあ、説明が悪いんだけどさ…。実際無くてもプログラムはかけるし」
「じゃあなんでこんな取り上げられてるんですか?」
「プログラマーが差別化を図る為」
「えー」
「半分くらい冗談」
「じゃあもうちょっと継承の意味ある使い方を話すか」
「おー」
あり得ないサイトに設計変更
「今回前回と似たように書くけど、全く設計を変えてしまいます」
「え?」
「オチから言うと、1つっきりの記事データを色々なテンプレートで表示する、という事をやってみます」
「そんなサイトありえないですよ?」
「まあ、たしかにありえないけど、無理矢理の例だからね」
「テンプレートいじるだけなら別に前回のままでいいんじゃないんですか?変更はできてましたよね」
「変更はできたけど、追加はどうかな?」
「ああ、追加は…どうやるんでしょうね?」
「まーできるけど、ファイル数は倍にふえちゃうね、まあそれは説明したい所じゃない」
「OOPにおいて、何が親で、何が子で、というのはかなり重要な概念なんだよね。どっちを親にして、子にする事もできるんだけど、それによって大分変わってしまう」
「へー」
「さて、設計をちょっとやり直す、前回は」
親:template.html
子:index.txt
となってんだけれど、今回templatewithmenu.htmlの親をもう一つ増やすとすれば、
親:template.htmlとtemplatewithmenu.html
子:index.txt
と、親が二つできちゃう、これはOOPとして不味い。多重継承なんてのもあるにはあるんだけど、基本的に親は一つで、子がたくさん、というのが正しい姿。なので、今回ではこういう形になることが望ましい」
親:index.txt
子:template.htmlとtemplatewithmenu.html
「ほほう…」
「この間と逆ね、で、これをベースに引き続き、あり得ないサンプルを作ると、まず親は」
<div id="text"> 本文テキスト本文テキスト </div> <div id="title"> タイトルタイトル </div>
「となり、次に子のtemplate.htmlは」
<? extend("index.txt") ?> <html> <head> <title id="title"><? include($title) ?></title> </head> <body> <div id="title"> <? include($title) ?> </div> <div id="text"> <? include($text) ?> </div> </body> </html>
「となる」
「だめですよ、メタタグとか指定しましょうよ、しかもID重複って」
「例なんだからいいじゃん、ほんじゃメニューを追加してくれってリクエストがきたとして、追加されるtemplatewithmenu.htmlはこうなる」
<? extend("index.txt") ?> <html> <head> <title id="title"><? include($title) ?></title> </head> <body> <div id="sidemenu"> ・LINK ・TO ・OTHER </div> <div id="title"> <? include($title) ?> </div> <div id="text"> <? include($text) ?> </div> </body> </html>
「なんかこないだとまったく一緒なんですけど」
「そーね、単に親子が入れ替わっただけだからね。さて、見て判る通りindex.txtは一個だけど、テンプレートが二つ追加できました。」
「そっすね、全くすごくないですね」
「さて、お客から仕様変更がきました。menu無しのtemplate.htmlの方には日付を入れたいらしいです」
「ありがちですね」
「さてデータとテンプレートを以下の様にしてみた」
<div id="text"> 本文テキスト本文テキスト </div> <div id="title"> タイトルタイトル </div> <div id="date"> 2009/04/02 </div>
<? extend_ftom("index.txt") ?> <html> <head> <title id="title"><? include($title) ?></title> </head> <body> <div id="title"> <? include($title) ?> </div> <div id="date"> <? include($date) ?> </div> <div id="text"> <? include($text) ?> </div> </body> </html>
「さてここで問題が。さっきつくったtemplatewithmenu.htmlが置き去りです」
「たしかに」
「データであるindex.txtがかわっちゃいましたけど、一体どうなったでしょうか?」
「うまく動かない?」
「ちょっと寄り道して、プロパティとメソッドの話に行く」
メソッド、プロパティ
「改めてデータであるindex.txtを見ると」
<div id="text"> 本文テキスト本文テキスト </div> <div id="title"> タイトルタイトル </div> <div id="date"> 2009/04/02 </div>
「3つのdivがあって、textとtitleとdateがある」
「ありますね」
「OOPにはまずクラスってのがある」
「そういえばクラスってなんですか」
「クラスってのは変数とメソッドの集まりが入った物。インスタンスって概念まで話すと長いから省略するけど、このindex.txtがクラスだと思ってもらって良いです。上だと、index.txtってクラスの中にtextとtitleって変数がある事になる。逆に言えば、textとtitleって変数をいれてあるのがindex.txtってクラス」
「はい」
「この変数はプロパティ変数といって、index.txtに書いてあるから、index.txtのプロパティ変数。プロパティってのは所有物って意味、index.txtが所有してるから」
「へー」
「メソッドってのは関数」
「まあ、関数くらいはわかりますよ」
「一旦ここでindex.txtをさらに解説する、index.txtは
名前(クラス名):index.txt
プロパティ変数:title, text, date
という情報をもっている」
「そっすね」
「プロパティ変数は同じindex.txtってクラスの中にはいってるけど、関連無く存在している、変数だからね。変数は名前が被らない限りは別に他の変数に影響はおよぼさない。HTMLでも一個だけid=textがあっても内容はかわらないし、10000個があっても、他が凄くでっかくても、textはかわらない」
「そうですね」
「では、別にtemplatewithmenu.htmlで、dateが存在してたとしても、読み込まなくたって、別にいいんじゃね?」
「divは変数のつもりだったんですね」
「そうね、いいわすれてたけど、XMLみたいなもんをイメージして書いてた」
「XMLはよくわからないです」
「まあ、俺もよくわからないよ」
さてさて、さらに
「さて、ってことで、index.txtにdateをふやしても、それぞれのtemplateは正しくindex.txtを親として取り込め、必要な変数を読める、不要な変数は読まなければいいだけなので、邪魔されない。」
「そうですね」
「じゃあ、今度はもう一個テンプレートを追加する」
「またですか!もういいですよ」
「(無視して)こんどはお客がタイトルを変更したいって言い出した、日付を1000年後にしたいんだって」
「そんな依頼きますか?」
「来ないね、さておきこんなテンプレートが書ける、template1000.htmlとする。」
<? extend_ftom("index.txt") ?> <html> <head> <title id="title"><? include($title) ?></title> </head> <body> <div id="title"> <? include($title) ?> </div> <div id="date"> 3009/04/02 </div> <div id="text"> <? include($text) ?> </div> </body> </html>
「できたね」
「そりゃこんなのできますよね、テンプレートかきかえちゃえば」
「さて、さらにさらにお客のリクエストがきた、こんどは1000年後の日付をつけたとき、タイトルに未来日記ってつけたいんだと、さらにそれは別のページにしてほしいと」
「そんなお客はいないでしょ?」
「いないねー、さてテンプレートtemplatemirai.htmlはこんな風になる」
<? extend_ftom("template1000.html") ?> <html> <head> <title id="title">未来日記</title> </head> <body> <div id="title"> <? include($title) ?> </div> <div id="date"> <? include($date) ?> </div> <div id="text"> <? include($text) ?> </div> </body> </html>
「さて、ここが神髄です」
「テンプレート追加しただけですよね?」
「よく見て下さい、親がtemplate1000.htmlになってます」
「あーホントだ、しかもdateの値がかきかえてないですよ?まちがえました?」
「いや、これで正しい」
オーバーライド
「index.txtとtemplate1000.htmlでは内容がちがうじゃないですか」
「でもそれはさっき説明したとおり、どっちでもdateって変数の中にちゃんとはいっている、という事なのよ」
「…あー、たしかにはいってますね、はい」
「index.txtに書いてあるデータは、そのままtemplate1000.htmlにひきつがれてるでしょ?」
「たしかに」
「だから、index.txtじゃなくて、template1000.htmlから継承しても、ちゃんとdateもtitleもtextもあるから大丈夫ってことさ。とにかくそういうことにしよう」
「はい」
「継承を繰り返すと、値を引き継いでいく。たとえば今回のtextはindex.txt > template1000.html > templatemirai.htmlとひきつがれてるじゃない?」
「はーはー、なるほど」
「ここで見せたいのは、変数を上書きする事ができるという事。dateはtemplate1000.htmlで上書きされてる、継承では上書きした値でさらに渡す事ができる、表で書くとこんな感じ」
・tmplate.htmlの場合
file | title | date | text |
index.txt | タイトルタイトル | 2009/04/02 | 本文テキスト本文テキスト |
template.html | (上そのまま) | (上そのまま) | (上そのまま) |
・tmplatewithmenu.htmlの場合
file | title | date | text |
index.txt | タイトルタイトル | 2009/04/02 | 本文テキスト本文テキスト |
templatewithmenu.html | (上そのまま) | (つかわない) | (上そのまま) |
・tmplatemirai.htmlの場合
file | title | date | text |
index.txt | タイトルタイトル | 2009/04/02 | 本文テキスト本文テキスト |
template1000.html | (上そのまま) | 3009/04/02 | (上そのまま) |
templatemirai.html | mirai日記 | (上そのまま) | (上そのまま) |
※上から下に継承していく
「なんか、わかるようなわからんような、意味あるんですか?」
「たとえば、これをしないでtemplate1000.htmlとtemplatemirai.htmlの二つに両方3009年ってかいてもいいんだけれど、どうせなら片方だけを修正したい」
「そうですかね?」
「そうなんだよ、たとえば後でお客から1000年じゃなくて、日替わりで2000年にしよう、っていわれたとき、一発で直せるじゃない」
「ふーん」
「ふーん」
「マネしないでください」
「マネしないでください」
「これはたんなる1行だけど、仮にもんのすげー長いテキストだったり、そこがプログラムだったり、差異があったら賠償ものだとかいわれたら、一箇所にまとめて間違いなくしたい」
「まあ、そこまで言うなら、そういう事にします」
「さておき、こういう風に継承をつかい、さらに値を上書きすることで、親の情報を必要な物だけとりだしたり、はたまた変更したり。そしてそれをさらに親として子を作る事ができる。継承とはそういうものなのですよ」
「なるほど、多少便利そうではあるけど、凄いのかはよくわかんないでした。」
「まあ、その便利ってのが重要なんじゃね?」
- -
つづくかもしれない。