php5.4からtraitが追加され、使い方がよくわかってないので教えてください。
あんまないと思うんですが、下みたいに、何故かTeacherクラスを継承した各先生のクラスが2つあったばあい、なかの処理がビミョーに異なっていて、ほとんど同じって場合。
本当は親のTeacherクラスで処理かいてテンプレートパターンのような形にしたいのですが、
諸事情で親のTeacherクラスが修正出来ないとして、Teachbleのようなトレイトを作って、そこで本来やりたかったようなテンプレートパターンのような事をするのって有りなんでしょうか。
既存のコード
Teacherを継承した、山田先生と小池先生のクラスがあるとします。
各先生はsaitenメソッドを持ってますが、発言や、赤点等の基準が少し違うとします。
php
1<?php 2 3class Teacher 4{ 5} 6 7class Yamada extends Teacher 8{ 9 const NAME = "山田"; 10 11 public function saiten($point) 12 { 13 $this->startCall($point); 14 15 if ($this->isAkaten($point)) { 16 $this->akatenResponse(); 17 } 18 19 if ($this->isHeikin($point)) { 20 $this->heikinReponse(); 21 } 22 23 if ($this->isManten($point)) { 24 $this->mantenResponse(); 25 } 26 } 27 28 private function startCall($point) 29 { 30 echo sprintf("%sが採点しますね\n%d点ですか・・\n", self::NAME, $point); 31 } 32 33 private function akatenResponse() 34 { 35 echo "赤点ですね"; 36 } 37 private function heikinReponse() 38 { 39 echo "平均ですね"; 40 } 41 private function mantenResponse() 42 { 43 echo "満点ですね"; 44 } 45 46 private function isAkaten($point) 47 { 48 return $point < 30; 49 } 50 51 private function isHeikin($point) 52 { 53 return $point >= 30 && $point < 100; 54 } 55 56 private function isManten($point) 57 { 58 return $point === 100; 59 } 60} 61 62class Koike extends Teacher 63{ 64 const NAME = "小池"; 65 66 public function saiten($point) 67 { 68 $this->startCall($point); 69 70 if ($this->isAkaten($point)) { 71 $this->akatenResponse(); 72 } 73 74 if ($this->isHeikin($point)) { 75 $this->heikinReponse(); 76 } 77 78 if ($this->isManten($point)) { 79 $this->mantenResponse(); 80 } 81 } 82 83 private function startCall($point) 84 { 85 echo sprintf("%sが採点するぞこら\n%d点か・・\n", self::NAME, $point); 86 } 87 88 private function akatenResponse() 89 { 90 echo "お前赤点だよ"; 91 } 92 private function heikinReponse() 93 { 94 echo "平均だな"; 95 } 96 private function mantenResponse() 97 { 98 echo "満点かーやるやんけ"; 99 } 100 101 private function isAkaten($point) 102 { 103 return $point < 80; 104 } 105 106 private function isHeikin($point) 107 { 108 return $point >= 80 && $point < 100; 109 } 110 111 private function isManten($point) 112 { 113 return $point === 100; 114 } 115} 116 117$yamadaTeacher = new Yamada(); 118echo $yamadaTeacher->saiten(60); 119 120echo "\n\n"; 121 122$koikeTeacher = new Koike(); 123echo $koikeTeacher->saiten(60); 124
出力結果
山田が採点しますね 60点ですか・・ 平均ですね 小池が採点するぞこら 60点か・・ お前赤点だよ
traitを使ってみる
php
1<?php 2 3class Teacher 4{ 5} 6 7trait Teachble 8{ 9 public function saiten($point) 10 { 11 $this->startCall($point); 12 13 if ($this->isAkaten($point)) { 14 $this->akatenResponse(); 15 } 16 17 if ($this->isHeikin($point)) { 18 $this->heikinReponse(); 19 } 20 21 if ($this->isManten($point)) { 22 $this->mantenResponse(); 23 } 24 } 25 26 abstract public function startCall($point); 27 abstract public function isAkaten($point); 28 abstract public function isHeikin($point); 29 abstract public function isManten($point); 30 abstract public function akatenResponse(); 31 abstract public function heikinReponse(); 32 abstract public function mantenResponse(); 33} 34 35class Yamada extends Teacher 36{ 37 use Teachble; 38 39 const NAME = "山田"; 40 41 private function startCall($point) 42 { 43 echo sprintf("%sが採点しますね\n%d点ですか・・\n", self::NAME, $point); 44 } 45 46 private function akatenResponse() 47 { 48 echo "赤点ですね"; 49 } 50 private function heikinReponse() 51 { 52 echo "平均ですね"; 53 } 54 private function mantenResponse() 55 { 56 echo "満点ですね"; 57 } 58 59 private function isAkaten($point) 60 { 61 return $point < 30; 62 } 63 64 private function isHeikin($point) 65 { 66 return $point >= 30 && $point < 100; 67 } 68 69 private function isManten($point) 70 { 71 return $point === 100; 72 } 73} 74 75class Koike extends Teacher 76{ 77 use Teachble; 78 79 const NAME = "小池"; 80 81 private function startCall($point) 82 { 83 echo sprintf("%sが採点するぞこら\n%d点か・・\n", self::NAME, $point); 84 } 85 86 private function akatenResponse() 87 { 88 echo "お前赤点だよ"; 89 } 90 private function heikinReponse() 91 { 92 echo "平均だな"; 93 } 94 private function mantenResponse() 95 { 96 echo "満点かーやるやんけ"; 97 } 98 99 private function isAkaten($point) 100 { 101 return $point < 80; 102 } 103 104 private function isHeikin($point) 105 { 106 return $point >= 80 && $point < 100; 107 } 108 109 private function isManten($point) 110 { 111 return $point === 100; 112 } 113} 114 115$yamadaTeacher = new Yamada(); 116echo $yamadaTeacher->saiten(60); 117 118echo "\n\n"; 119 120$koikeTeacher = new Koike(); 121echo $koikeTeacher->saiten(60);
出力結果
山田が採点しますね 60点ですか・・ 平均ですね 小池が採点するぞこら 60点か・・ お前赤点だよ
質問
このように、traitを使うことで、また先生を増やした時にほぼ内容がまったく同じなsaiten
メソッドをコピペする必要がなくなって楽になるかと思いましたが、これってtrait
の使い方として正しいのでしょうか・・
回答1件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2016/02/10 00:09