c/fe

http://d.hatena.ne.jp/uzulla から移行しました。

オブジェクト指向の継承をある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行だけど、仮にもんのすげー長いテキストだったり、そこがプログラムだったり、差異があったら賠償ものだとかいわれたら、一箇所にまとめて間違いなくしたい」
「まあ、そこまで言うなら、そういう事にします」



「さておき、こういう風に継承をつかい、さらに値を上書きすることで、親の情報を必要な物だけとりだしたり、はたまた変更したり。そしてそれをさらに親として子を作る事ができる。継承とはそういうものなのですよ」
「なるほど、多少便利そうではあるけど、凄いのかはよくわかんないでした。」
「まあ、その便利ってのが重要なんじゃね?」

  • -

つづくかもしれない。