アルゴリズムの実装を外部にカプセル化して交換できるようにするパターン
カプセル化するアルゴリズムに必要な動作をインターフェースに定義して各々実装させる。
型定義が必要な言語ではインターフェース型の変数で受ける。
謎の機能を示しますが一応動きます。
カプセル化するアルゴリズムに必要な動作をインターフェースに定義して各々実装させる。
型定義が必要な言語ではインターフェース型の変数で受ける。
/**
* Strategyパターンサンプル
* @create 2007/06/15
*/
/**
* Vehicle - 乗物のスーパークラス
*/
class Vehicle
{
private $_speed; ///< 変速を格納する
private $_alarm; ///< 警告音を格納する
/**
* setSpeedType - 引数で受け取った変速を格納する
* @param ITypeSpeed $speed
* @return void
*/
public function setSpeedType($speed)
{
$this->_speed = $speed;
}
/**
* setAlarmType - 引数で受け取った警告音を格納する
* @param ITypeAlarm $alarm
* @return void
*/
public function setAlarmType($alarm)
{
$this->_alarm = $alarm;
}
/**
* dispShift
*/
public function dispShift()
{
$this->_speed->dispShift();
}
/**
* shiftUp
*/
public function shiftUp()
{
$this->_speed->shiftUp();
}
/**
* shiftDown
*/
public function shiftDown()
{
$this->_speed->shiftDown();
}
/**
* alarm
*/
public function alarm()
{
$this->_alarm->alarm();
}
}
/**
* 変速インターフェース
*/
interface ITypeSpeed
{
public function dispShift();
public function shiftUp();
public function shiftDown();
}
/**
* 1段ギア(変則無し)
*/
class Speed_1 implements ITypeSpeed
{
public function dispShift()
{
print "ギアチェンジの機能はありません";
}
public function shiftUp()
{
print "できません\n";
}
public function shiftDown()
{
print "できません\n";
}
}
/**
* 3段ギア
*/
class Speed_3 implements ITypeSpeed
{
private $_max=3;
private $_current=1;
public function dispShift()
{
print "現在のギアは" . $this->_current . "に設定されています\n";
}
public function shiftUp()
{
if ($this->_max > $this->_current) $this->_current++;
else print "既に最大です\n";
}
public function shiftDown()
{
if (1 < $this->_current) $this->_current--;
else print "できません\n";
}
}
/**
* 5段ギア
*/
class Speed_5 implements ITypeSpeed
{
private $_max=5;
private $_current=1;
public function dispShift()
{
print "現在のギアは" . $this->_current . "に設定されています\n";
}
public function shiftUp()
{
if ($this->_max > $this->_current) $this->_current++;
else print "既に最大です\n";
}
public function shiftDown()
{
if (1 < $this->_current) $this->_current--;
else print "既に最小です\n";
}
}
/**
* 無限段ギア
*/
class Speed_Infinity implements ITypeSpeed
{
private $_current=1;
public function dispShift()
{
print "現在のギアは" . $this->_current . "に設定されています\n";
}
public function shiftUp()
{
$this->_current++;
}
public function shiftDown()
{
if (1 < $this->_current) $this->_current--;
else print "既に最小です\n";
}
}
/**
* 警告音インターフェース
*/
interface ITypeAlarm
{
public function alarm();
}
/**
* ベルアラーム
*/
class Alarm_Bell implements ITypeAlarm
{
public function alarm()
{
print "チリンチリン\n";
}
}
/**
* クラクション
*/
class Alarm_Horn implements ITypeAlarm
{
public function alarm()
{
print "プップー\n";
}
}
/**
* ホームラン
*/
class Alarm_BigSwat implements ITypeAlarm
{
public function alarm()
{
print "カキーン!\n";
}
}
/**
* Car - 乗物を継承する車サブクラス
*/
class Car extends Vehicle
{
function __construct()
{
$this->setSpeedType(new Speed_5());
$this->setAlarmType(new Alarm_Horn());
}
}
/**
* Bicycle - 自転車を継承するテレビサブクラス
*/
class Bicycle extends Vehicle
{
function __construct()
{
$this->setSpeedType(new Speed_3());
$this->setAlarmType(new Alarm_Bell());
}
}
/**
* 乗物をインスタンス化
*/
$kuruma = new Car();
$jitensya = new Bicycle();
/** 車の動作 */
print("車の動作\n");
$kuruma->dispShift();
$kuruma->shiftUp();
$kuruma->dispShift();
$kuruma->shiftDown();
$kuruma->shiftDown();
$kuruma->dispShift();
$kuruma->alarm();
/** 自転車の動作 */
print("自転車の動作\n");
$jitensya->shiftUp();
$jitensya->shiftUp();
$jitensya->dispShift();
$jitensya->shiftUp();
$jitensya->alarm();
/** 車のクラクションを改造 */
print("車のクラクションを改造\n");
$kuruma->setAlarmType(new Alarm_BigSwat());
/** 鳴らしてみる */
$kuruma->alarm();
/** 自転車のギアを近未来型に改造 */
print("自転車のギアを近未来型に\n");
$jitensya->setSpeedType(new Speed_Infinity());
/** ギアを100段上げてみる */
print("ギアを100段上げてみる\n");
for ($i=0; $i<100; $i++) $jitensya->shiftUp();
$jitensya->dispShift();
?>
謎の機能を示しますが一応動きます。
コメント
コメントを投稿