序文
モード紹介
シンプルなプラントモデルは、実際に工場モデルの変形に類似GoF23(23のデザインパターン)の一部ではありません。異なるクラスのインスタンスが異なるパラメータに従って返却することができるように定義されます。シンプルなファクトリパターンインスタンスを作成するための責任を他のクラスに特別なクラスを定義するには、インスタンスが正常に作成され、共通の親クラスを持っています。
それは、ビットレストランに行くようなものだドアのウェイターと言う:「!!ウェイターナマコ麺に」通常の状況下では、彼はあなたにナマコの麺を与えるだろう(関係なく、何のナマコはありません)。この第二の男が入って来た、また叫んだ:「ウェイターは、ホースラディッシュスープのボウルを来て!」この時点で、彼はあなたにホースラディッシュスープを提供します。あなたも、彼はあなたを与えた、ちょうど店を伝える必要があり、大きな音を揚げキュウリとホースラディッシュスープ麺を考えていません。
「サーバント」の上記の例は、単純な植物です。レストランのメニューは、工場内のクラスの単純なリストです。ウェイターがクラスに語っている時点では、ウェイターは、クラスのインスタンスになります最後は、料理の出てきますさ。私にとっては、このクライアントが懸念しているので、Houchuはちょうど料理のインスタンスを食べるのに十分得るために、何を知っている必要はありません。1日の場合はナマコのバーベキューレストランに麺が、私はHouchu文字列stringの子供たちは、また、唯一の腎臓OKにアテンダントを探しに行く必要がある方法を知っている必要はありませんでした。
UMLのクラス図
ここで私は①、二つのタイプが含まれます。クライアントは、ウェイター料理世代のバックエンドのインスタンスを呼び出すための責任があります。②ウェイター:ファクトリクラスは、バックエンドの料理を生成し、クライアントに返さする責任があります。料理③:の後に料理を生成する、後でカテゴリを果たします。特定の関係UMLのクラス図は次のとおりです。
コード例
次は食べるの機能を備え、抽象クラス、である、クライアントが食べるために用意されて麺クラスです。
#ifndef NOODLE_H
#define NOODLE_H
class noodle {
public:
noodle() {}
~noodle() {}
public:
virtual void eating() = 0;
};
#endif // NOODLE_H
次は食べる方法を実現する、ナマコ麺クラス、統合された自己麺カテゴリーであります:
#ifndef HAISHENNOODLE_H
#define HAISHENNOODLE_H
#include "noodle.h"
class haishennoodle : public noodle
{
public:
haishennoodle();
~haishennoodle();
public:
virtual void eating();
};
#endif // HAISHENNOODLE_H
#include <iostream>
#include "haishennoodle.h"
haishennoodle::haishennoodle()
{
}
haishennoodle::~haishennoodle()
{
}
void haishennoodle::eating()
{
std::cout << "我是海参炒面,里面没有海参哦!!吃的时候注意!" << std::endl;
}
ここではホースラディッシュスープのクラスである、方法を食べて書き換え、麺のカテゴリを継承しました。
#ifndef LAGENNOODLE_H
#define LAGENNOODLE_H
#include "noodle.h"
class lagennoodle : public noodle
{
public:
lagennoodle();
~lagennoodle();
public:
virtual void eating();
};
#endif // LAGENNOODLE_H
#include <iostream>
#include "lagennoodle.h"
lagennoodle::lagennoodle()
{
}
lagennoodle::~lagennoodle()
{
}
void lagennoodle::eating()
{
std::cout << "我是辣根汤面,吃完呛的哼啊!!!" << std::endl;
}
ここでは、バックエンドの麺を生成するための責任が親切なウェイターが、あります。インスタンス化された麺createnoodleを生成することにより、工場。
#ifndef WAITER_H
#define WAITER_H
class noodle;
class waiter
{
public:
waiter();
~waiter();
public:
noodle *createnoodle(int type);
};
#endif // WAITER_H
#include <iostream>
#include "waiter.h"
#include "haishennoodle.h"
#include "lagennoodle.h"
waiter::waiter()
{
}
waiter::~waiter()
{
}
noodle *waiter::createnoodle(int type)
{
noodle *n = NULL;
switch(type) {
case 0:
n = new haishennoodle();
break;
case 1:
n = new lagennoodle();
break;
default:
std::cout << "对不起,我们这没有这个菜,请您换一个!" << std::endl;
}
return n;
}
クライアントコードは、私が店の注文段階に入って来る、次のとおりです。
#include <iostream>
#include <string.h>
#include "haishennoodle.h"
#include "lagennoodle.h"
#include "waiter.h"
using namespace std;
char *product_list[] = {
"haishen-noodle",
"lagen-noodle",
NULL
};
int main()
{
char *p = NULL;
char *pd = "haishen-noodle";
int i = 0;
waiter *w = new waiter();
noodle *n = NULL;
for(p = product_list[i]; p != NULL; i++, p = product_list[i]) {
if(strncmp(pd, p, strlen(pd)) == 0) {
n = w->createnoodle(i);
if(n) {
cout << "开吃!!!" << endl;
n->eating();
}
}
}
if(n) {
delete n; n = NULL;
}
if(w) {
delete w; w = NULL;
}
return 0;
}
ボーナスCMakeList.txtコード:
cmake_minimum_required(VERSION 2.8)
project(noodle)
set(SRC_LIST main.cpp noodle.h lagennoodle.h lagennoodle.cpp haishennoodle.h haishennoodle.cpp waiter.h waiter.cpp)
add_executable(${PROJECT_NAME} ${SRC_LIST})
コンパイルと実行結果
ダウンロードリンクは次のとおりです。https://github.com/erguangqiang/freesir_headfirst/blob/master/noodle.tar.gz
使用cmakeのはMakefileを生成し、実行可能プログラムの麺をコンパイルします。結果は以下の通りであります:
erguangqiang@elab$./noodle
开吃!!!
我是海参炒面,里面没有海参哦!!吃的时候注意!
終了
利点は、単純なファクトリパターンを単離することができるであり、クライアントをインスタンス化するので、クライアントは、ロジックとクライアントのデカップリングの目的を達成するために、特定のプロセスのクラスのインスタンスを無視することができます。
しかし、単純なファクトリパターンがオープンのデザインパターンに応じて、また、非常に重大な欠点である-固有のコードを変更するのではなく、拡張のために、原則を閉じて、統合された拡張機能のクラスは開くことができます。新しい麺料理したら、私たちは、ファクトリクラスを変更する必要があります。この方法は、それが拡張の方法によって達成され、工場出荷時のモデルの使用を避けることです。