少し前に、World of Warcraft を使用してデザイン パターンを説明している人を見かけました。非常に興味深い内容だったので、変更してデザイン パターンのコンテンツを追加しました。先人の内容を明示せずに借用している部分もありますので、先人の方は気分を害されないようお願いします。
ここでは、誰もが興味を持っている Warcraft 3 を使用して、PHP のいくつかの一般的な設計パターン (シングルトン モード、ストラテジー モード、ファクトリー モード、オブザーバー モード) について説明します。今日はこれら 4 つについて説明し、後で続けましょう。
これらの設計パターンはすべてオブジェクト指向のため、すべて PHP5 を使用しています。また、ここで言いたいのは、PHP4 は 2008 年 8 月 8 日に開始されたということです (北京オリンピックと同じ日だったと記憶しています)。しかし、私はそれを検証していません (笑)、公式は PHP4 の最後のパッチをリリースしました。これは、PHP4 の時代が終わったことを意味します。したがって、今は PHP4 を無視して、単に例として PHP5 を使用することをお勧めします。
1. 単体モード:
提起された質問:
このタイプのリソースは 1 つしかないため、一部のアプリケーション リソースは排他的です。たとえば、データベース ハンドルを介したデータベースへの接続は排他的です。アプリケーション全体でデータベース ハンドルを共有する必要があるのは、接続を開いたままにするか閉じたままにするときにオーバーヘッドが発生するためであり、単一ページをフェッチするプロセスではさらにオーバーヘッドがかかるからです。
問題の解決策:
それでは、World of Warcraft のプレイを始めましょう。まず、war3.exe をダブルクリックすると、Warcraft が実行を開始します。コードでやってみましょう。
クラス戦争3
{
パブリック関数 __construct()
{
echo "War3 が実行中です。","
";
}
}
$war = 新しい War3();
走れ!素晴らしい、成果
War3 が実行中です。
すでにゲームを開始できますが、コードの最後に別の
を追加すると$war2 = new War3();
$war3 = 新しい War3();
何が起こるでしょうか?試してみましょう。出力は次のとおりです:
War3 が実行中です。
War3 が実行中です。
War3 が実行中です。
それだけです。誤って 2 回ダブルクリックして 3 World of Warcraft を開いた場合、さらに数回ダブルクリックすると、間違いなくコンピューターが爆発します。 。 。解決策を考えてみましょう。
このクラスはそう気軽にインスタンス化できないため、コンストラクターをプライベート メソッドに変更します。
クラス戦争3
{
プライベート関数 __construct()
{
echo "War3 が実行中です。","
";
}
}
しかし、プライベート変数には外部からアクセスできないため、開くことさえできません。心配しないで、インスタンス化せずに外部からアクセスできる別の関数、つまり静的関数
を追加しましょう。
クラス戦争3
{
プライベート関数 __construct()
{
echo "War3 が実行中です。","
";
}
パブリック静的関数 runWar()
{
}
}
この静的メソッド runWar() を通じて、クラス War3 のインスタンス化を制御します。その後、まだ識別子が不足しているため、別の識別子を作成し、この識別子を使用してクラスがインスタンス化されているかどうかを示します。ハンドルを直接返します。
クラスを
に変更しますクラス戦争3
{
保護された静的 $_instance = null;
プライベート関数 __construct()
{
echo "War3 が実行中です。","
";
}
パブリック静的関数 runWar()
{
if (null === self::$_instance) {
self::$_instance = new self();
}
自分自身を返す::$_instance;
}
}
もちろん、World of Warcraft を実行するときにインスタンス化メソッドを変更する必要もあります。
を使用するだけです。
$war = War3::runWar();
World of Warcraft のプレイを開始できます。完全なコードは次のとおりです:
クラス戦争3
{
保護された静的 $_instance = null;
プライベート関数 __construct()
{
echo "War3 が実行中です。","
";
}
パブリック静的関数 runWar()
{
if (null === self::$_instance) {
self::$_instance = new self();
}
自分自身を返す::$_instance;
}
}
$war = War3::runWar();
$war2 = War3::runWar();
$war3 = War3::runWar();
実行すると結果は次のようになります:
War3 が実行中です。
すごいですね、何度ダブルクリックしても World of Warcraft を 1 つだけ実行しました。これで、どのように開いてもマシンは爆発しません。
これは伝説的な単価モデルで、主に多くのリソースを消費し、インスタンスが 1 つだけで十分な場合に使用されます。たとえば、zend フレームワークの Zend_Controller_Front フロントエンド コントローラーは単価モデルを使用して設計されています。ご興味があれば、ぜひご覧ください。
2. 戦略モード:
提起された質問:
このモードでは、アルゴリズムが複雑なクラスから抽出されるため、簡単に置き換えることができます。たとえば、検索エンジンでのページのランク付け方法を変更したい場合は、戦略モードが適しています。検索エンジンの各部分、つまりページを横断する部分、各ページをランク付けする部分、およびランキングに基づいて結果を並べ替える部分について考えてみましょう。複雑な例では、これらのパーツはすべて同じクラスに属します。 Strategy パターンを使用すると、配置部分を別のクラスに配置して、検索エンジンのコードの残りの部分に影響を与えることなく、ページの配置方法を変更できます。
問題の解決策:
ははは、それほど複雑ではありません。World of Warcraft をようやく開いたので、World of Warcraft をプレイしてみましょう。
次に戦闘を選択します。人間、オーク(ORC)、ナイトエルフ(ナイエルフ)、アンデッド(アンデッド)など、非常に多くの種族があります。私はナイ エルフを選択し、次にエルフ 1 人とオーク 2 人 (ORC) を選択します。1 人のオークは私と同じ家族の出身で、もう 1 人のエルフとオークは別の家族の出身です。
すべてのプレイヤーは、ゲームに入ると、ホール、5 つのエルフ (ピオン)、鉱山などのリソースを獲得します。これらは初期化のものと呼ぶことができ、ここでは戦略パターンを使用してこれらの初期化をカプセル化できます。
本題に入りますが、まずプレーヤー クラスを構築しましょう:
クラスプレイヤー
{
//プレイヤー名
保護された $_name;
//レース
保護された $_race;
//チーム
$army を保護しました;
//建物
保護された $building;
//人口
保護された $population;
//ゴールド
$gold を保護しました;
//木
$wood を保護しました;
//コンストラクター、レースを設定してください
パブリック関数 __construct($race)
{
$this->レース = $race;
}
//__get() メソッドは保護された属性を取得するために使用されます
プライベート関数 __get($property_name)
{
if(isset($this->$property_name)) {
return($this->$property_name);
}
else {
return(NULL);
}
}
//__set() メソッドは保護属性の設定に使用されます
プライベート関数__set($property_name,$value)
{
$this->$property_name=$value;
}
}
次に、プレーヤーの初期化用の別のインターフェイスを構築します。
インターフェースInitialPlayer
{
//初期化された軍隊を作成します
パブリック関数 giveArmy($player);
//初期化された建物を作成します
パブリック関数 giveBuilding($player);
//リソースを初期化します
パブリック関数 giveSource($player);
}
わかりました。ここではこのインターフェースを実装する必要があります。便宜上、2 つの種族のみを選択し、これら 2 つの種族の初期化のみを記述しました。
最初はエルフです:クラス NighyElfInitial は、initialPlayer
パブリック関数 giveArmy($player)
{
//5 人のエルフ
for($i=0; $i {
$creator = new CreatArms();//これは部隊クラスを作成するためのもので、後でファクトリー モードで使用されるため、ここではこれ以上は説明しません
$player->army[] = $creator->Creat('Wisp','./Arms/');
}
}
//初期化された建物を作成します
パブリック関数 giveBuilding($player)
{
$creator = new CreatBuildings();
//ベース
$player->building[] = $creator->Creat('TownHall','./Buildings/');
//鉱山
$player->building[] = $creator->Creat('Mine','./Buildings/');
}
//人口上限を初期化します
パブリック関数 giveSource($player)
{
$player->population= 10;
$player->ゴールド= 1000;
$player->wood= 100;
}
}
クラス ORCInitial は、initialPlayer
パブリック関数 giveArmy($player)
{
//5 つの牡丹
for($i=0; $i {
$creator = new CreatArms();//これは部隊クラスを作成するためのもので、後でファクトリー モードで使用されるため、ここではこれ以上は説明しません
$player->army[] = $creator->Creat('Peon','./Arms/');
}
}
//初期化された建物を作成します
パブリック関数 giveBuilding($player)
{
$creator = new CreatBuildings();
$player->building[] = $creator->Creat('TownHall','./Buildings/');
//鉱山
$player->building[] = $creator->Creat('Mine','./Buildings/');
}
//人口上限を初期化します
パブリック関数 giveSource($player)
{
$player->population= 10;
$player->ゴールド= 1000;
$player->wood= 100;
}
}