スキップしてメイン コンテンツに移動

Strategyパターン

アルゴリズムの実装を外部にカプセル化して交換できるようにするパターン
カプセル化するアルゴリズムに必要な動作をインターフェースに定義して各々実装させる。
型定義が必要な言語ではインターフェース型の変数で受ける。


/**
* 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();

?>


謎の機能を示しますが一応動きます。

コメント

このブログの人気の投稿

就職活動現況報告

今週若干余裕があるので少しネタの更新・・と思っていますが 研究も進めないといかんので保留。。 本を読む本 (講談社学術文庫) をほぼ読み終わったので 電車の中で次はviの本かWebプログラミング基本みたいな本を読もうと思います。 後は久々に漫画を衝動買い。 ぷりぞな6 1 (サンデーGXコミックス) これ。絵描いてる人が韓国の人らしい。 ブラックラグーンの作者が支持みたいなことが書いてあったので読んで見ました。 まー絵は萌え系みたいな感じだけどシリアス混じってて面白そうかな? Amazonでは絵が無いですが一応公式の紹介は GX作家&作品紹介 こんな感じです。 結構表紙飾っているようなので見たことある人も居るかもしれません。 で、タイトルの就活現況では、前回順調とか言ってましたが 志望していた6社のうちとうとう1社落ちました。 しかも結構でかいところです。 グループ面接の時点で落ちてしまったので、 もしかしたら表面の部分(礼儀とか仕草)で落とされたのかもしれないですが、 反省としては 内容が冗長で話す内容が長かった 何か反論された時に言い訳じみた答えを返してしまった 自分はエンジニア経験があるんだ的な内容を押しすぎた 辺りと考えています。 で、対策。 まず冗長分ですが、今のところ話す内容を完全に決めてしまわずに、 ある程度の枠を決めてその場で考えて話しているので もうちょっと 質問の後に結論を考えてから内容を話す ように気をつけようと思います。 反論じみた言い訳というのは、とっさに返してしまう対応策みたいなもので、 相手に この人は実務でミスしてもその場対応するんじゃないか という印象を与えてしまった気がしております。 ので、対策としては 一度相手の内容を肯定して、その上で簡潔にこうすればいいんじゃないかと思うと一言返す 位に留めようと思います。 最後にエンジニア押しは、一応自分の売りの一つではあるので止めることはせずに 事実だけをしっかり伝えて冗長分は省く というような感じにしようかと思います。 以上。 自分の反省なので発信するような内容じゃないんですが、 文に書かないとなかなか省みない性格なので文にして発信。 結論を言えば「もっと落ち着いて簡潔に」を心がけるといったところでしょう。 正直面接凄い苦手なのでなかなか落ち着くのはきついですが、 省みなずに 運...

日記をつけはじめて1年とちょっと経ったまとめ

日記をつけはじめて1年とちょっと経ったまとめ 去年(2017)の 1/11 から日記をつけ始め、気づくともう1年以上ほぼ毎日つけていました まさか習慣化するとは思っていなかったんですが、意外と続いたので一旦まとめておこうと思ってのエントリ このエントリでは どういう手法で続けてきたか や 続けてきた結果どうなったか などをまとめておいて、自分用の改善材料にすること、及び、このエントリを見た人の判断材料にすることを目的としています …ので、書き始めた主要因である書籍 日記の魔力 については、覚えている内容を参考にする程度で、本自体の紹介はほぼしないです(読み返すのが面倒だっただけじゃないです) まとめ 書いてみたら長くなったので、まとめから 自分用のフォーマットを整えれば意外と書くのは楽 愚痴も悩みもとりあえず文字に吐き出すと精神衛生上良い 忘れっぽいと思っていたら、思っていたより数倍物事を忘れていることに気づく 万が一興味を持ったら一度 日記の魔力 を読んでみては 今後は… これまで通り毎日ログを書く ふりかえりの意義を再考して、ちゃんと毎週&毎月ふりかえるようにする ふりかえりの中で、どういうログを書いておくと使いやすいか考えて、日記自体も改善する 以降、自分のふりかえりも兼ねているため長文ですが、つらつらと書きます きっかけ 最初のきっかけは、 Twitter のタイムラインに流れてきたブログのエントリ 思考や行動を改善できる「日記の魔力」とは の引用…だった気がする(この時はまだログをつけていなかったので記録も記憶も残っていない…) ここで紹介されている 日記の魔力 という本を一通り読み、本に書いてあるとおりに 騙されたと思って日記を書き始めてみよう と思ったのが最初の一歩 手法 記憶が朧げですが、確か本の著者の方の手法は ワープロかPCか何かで、毎日のログを隙間時間にファイルに記述する 10日に一度くらいのスパンでそれまで書いた日記をふりかえる ふりかえりの中で、自分が人生で追っていきたい主題みたいなものに関連する内容を別のファイルにコピペして貯めていく みたいな形だったはず。色々と細かいルール(天気などの後から調べれば分かることは書かない等)が少しあった気がするけれど、既に覚えて...

あけましておめでとうございます 2020

あけましておめでとうございます。 去年は1年通して仕事が忙しかったことを言い訳に、何も抱負を達成せずにのんべんだらりと過ごしてしまった一年でした。 去年一切達成できなかった抱負ですが、盛大にハードルを下げつつ、今年も書いておこうと思います。 - 英会話コースを受講する - 隔月で新しいことを体験する(間の月は次の月にやることを考える) - 個人でゲームを作成してプラットフォームへ上げる - 4半期ごとに達成状況を確認して、余裕があったら目標を追加する 以上です。 今年もよろしくお願いいたします。