設計モード概要続き(構造型モード)


前回は作成モードについて説明しました
http://blog.csdn.net/songshimvp1/article/details/48786615——単例モード、単純ファクトリモード、多態ファクトリモード、抽象ファクトリモード、コンストラクタモード、プロトタイプモード(prototype)について、次に構造型モード——エージェントモード、装飾モード、アダプタモード(adapter)、組合せモード、ブリッジモード、外観モード(facade)、享元モード(flyweight)を紹介する.
設計パターンの詳細——構造型パターン
1、エージェントモード(Proxy)★Proxyモード、エージェントモードは、他のオブジェクトへのアクセスを制御するためのエージェント(Proxy)を提供する構造型の設計モードの1つです.エージェントとは、エージェントとの間に(エージェントされるオブジェクト)同じインタフェースを有するクラスでは、クライアントはエージェントを介してエージェントされるターゲットクラスと対話しなければならないが、エージェントは一般的に対話の過程(対話の前後)で特定の処理を行う.
≪適切|Adaptive|emdw≫:このオブジェクトへのアクセスを制御するために、他のオブジェクトにエージェントを提供します.実装:aにbクラスを含む;a、bクラスはプロトコルクラスprotocolを実現する.
リアルプレイヤー(李)、エージェントプレイヤー(趙)、エージェントプレイヤー(趙)、代わりにアップグレードを行います.
/*
   ,      ,   ;
  、   (    ),     ;
            ;
*/
#include<iostream>
using namespace std;

class Subject  //   ,      (RealSubject)     (Proxy)     
{
public:
	virtual void sailbook() = 0;
};

//      :               
class RealSubjectBook :public Subject   
{
public:
	virtual void sailbook()
	{
		cout << "     ..." << endl;
	}
};

//a   b ;a、b      protocol
//      :                                     ,            
class dangdangProxy : public Subject   
{
public:
	void SetRealSubject()
	{
		RealSubjectBook *rs = new RealSubjectBook;
		m_subject = rs;
	}

	virtual void sailbook()
	{
		SetRealSubject();
		dazhe();    //      
		m_subject->sailbook();
	}

	void dazhe()
	{
		cout << "          ..." << endl;
	}
private:
	RealSubjectBook *m_subject;
};

void main()
{
	Subject *s = new dangdangProxy;
	s->sailbook();
	delete s;
}

2、デコレーションモード★デコレーションモードはパッケージモードとも呼ばれます.クライアントに対して透明な方法でオブジェクトを拡張する機能で、関係を継承する代替案です.
装飾モードとは、追加する付加機能をそれぞれ別のクラスに配置し、このクラスに装飾するオブジェクトを含ませることであり、実行が必要な場合、クライアントは装飾機能を選択的に、順番に使用してオブジェクトを包装することができる.
適用:デコレーション・モード(Decorator Pattern)は、オブジェクトに動的に追加のロールを追加します.機能を追加すると、このモードはサブクラスを生成するよりも柔軟です.
#include<iostream>
using namespace std;

class Car
{
public:
	virtual void show() = 0;
};

class RunCar :public Car
{
public:
	virtual void show()
	{
		cout << "   !" << endl;
	}
};

class SwimCarDirector :public Car
{
public:
	SwimCarDirector(Car *car)
	{
		m_car = car;
	}
	void SwimCar()
	{
		cout << "   !" << endl;
	}
	virtual void show()
	{
		m_car->show();
		SwimCar();
	}
private:
	Car* m_car;
};

class FlyCarDirector :public Car
{
public:
	FlyCarDirector(Car *car)
	{
		mm_car = car;
	}
	void FlyCar()
	{
		cout << "   !" << endl;
	}
	virtual void show()
	{
		mm_car->show();
		FlyCar();
	}
private:
	Car* mm_car;
};

void main()
{
	Car *mycar = NULL;
	mycar = new RunCar;
	cout << "  :---" << endl;
	mycar->show();
	cout << endl;

	cout << "   :---" << endl;
	SwimCarDirector *myswimcar = new SwimCarDirector(mycar);   //       (          )
	myswimcar->show();
	cout << endl;

	cout << "   :---" << endl;
	FlyCarDirector *myflycar = new FlyCarDirector(myswimcar);   //       (          )
	myflycar->show();

	delete mycar;
	delete myflycar;
	delete myswimcar;
}

3、アダプターモード(adapter)★アダプターモードで既存のクラス(または外部クラス)のインタフェース形式を変更できます.
適用:クラスのインタフェースをお客様が望む別のインタフェースに変換します.インタフェースが互換性がないため、一緒に作業できないクラスが一緒に作業できるようにします.
class  Current18v   //      18V
{
public:
	virtual void useCurrent18v() = 0;
};

class  Current220v  //    220V
{
public:
	void useCurrent220v()
	{
		cout << "  220v,    ..." << endl;
	}
};

class Adapter : public Current18v  //   :    
{
public:
	Adapter(Current220v *current)
	{
		m_current = current;
	}
	virtual void useCurrent18v()
	{
		cout << "   ,   220v:——";
		m_current->useCurrent220v();
	}
private:
	Current220v *m_current;   //  
};

void main()
{
	Current220v		*current220v = NULL;
	Adapter			*adapter = NULL;

	current220v = new Current220v;
	adapter = new Adapter(current220v);
	adapter->useCurrent18v();//          18V,          220V

	delete current220v;
	delete adapter;
}

4、コンビネーションモード(composite)Componentositeモードはコンビネーションモードとも呼ばれ、構造型の設計モードの一つである.ツリーのオブジェクト構造を再帰的に構築し、1つのオブジェクトでオブジェクトツリー全体にアクセスできる.
適用:単一オブジェクトと組合せオブジェクトの使用に一貫性があります.オブジェクトをツリー構造に結合して、「部分-全体」を表します.
class IFile
{
public:
	virtual void display() = 0;
	virtual int add(IFile *ifile) = 0;
	virtual int remove(IFile *ifile) = 0;
	virtual list<IFile *> *getChild() = 0;
};

//      
class File : public IFile
{
public:
	File(string name)
	{
		m_name = name;
	}
	virtual void display()
	{
		cout << m_name << endl;
	}

	virtual int add(IFile *ifile)
	{
		return -1;
	}

	virtual int remove(IFile *ifile)
	{
		return -1;
	}

	virtual list<IFile *> *getChild()
	{
		return NULL;
	}
private:
	string m_name;
};

//      
class Dir : public IFile
{
public:
	Dir(string name)
	{
		m_name = name;
		m_list = new list<IFile *>;
		m_list->clear();
	}
	virtual void display()
	{
		cout << m_name << endl;
	}

	virtual int add(IFile *ifile)
	{
		m_list->push_back(ifile);
		return 0;
	}

	virtual int remove(IFile *ifile)
	{
		m_list->remove(ifile);
		return 0;
	}

	virtual list<IFile *> *getChild()
	{
		return m_list;
	}
private:
	string m_name;
	list<IFile *>  *m_list;
};

//      
void showTree(IFile *root, int level)
{
	int i = 0;
	if (root == NULL)
	{
		return;
	}
	for (i = 0; i<level; i++)
	{
		printf("\t");
	}

	//1       
	root->display();

	//2           
	//       ,     )
	//       ,showTree(   )
	list<IFile *>  *mylist = root->getChild();
	if (mylist != NULL)   //       
	{
		for (list<IFile *>::iterator it = mylist->begin(); it != mylist->end(); it++)
		{
			if ((*it)->getChild() == NULL)
			{
				for (i = 0; i <= level; i++)  //   <= 
				{
					printf("\t");
				}
				(*it)->display();   //      
			}
			else
			{
				showTree(*it, level + 1);   //     
			}
		}
	}
}

void main()
{
	Dir *root = new Dir("C");
	//root->display();

	Dir *dir1 = new Dir("111dir");
	File *aaafile = new File("aaa.txt");

	//  root         
	list<IFile *>  *mylist = root->getChild();

	root->add(dir1);
	root->add(aaafile);

	//  (111dir)   (aaa.txt)
	//				▲
	for (list<IFile *>::iterator it = mylist->begin(); it != mylist->end(); it++)
	{
		(*it)->display();
	}

	Dir *dir222 = new Dir("222dir");
	File *bbbfile = new File("bbb.txt");
	dir1->add(dir222);
	dir1->add(bbbfile);

	cout << "   showTree       root           " << endl;
	showTree(root, 0);
}

5、ブリッジモード(bridge)★ブリッジモードはクラスの最小設計原則に基づいて、パッケージ、集約、継承などの行為を使用することで異なるクラスに異なる責任を負わせる.その主な特徴は抽象(abstraction)と行為を実現することである.(implementation)は分離され、各部分の独立性とそれらに対応する機能拡張を維持することができる.
適用:ブリッジモード(Bridge Pattern)は抽象部分と実装部分を分離(解結合)し、それらを独立に変化させる.車はエンジンを取り付ける.異なる型番の車は、異なる型番のエンジンを取り付け、「車はエンジンを取り付ける」という抽象と実現を分離し、2つの名前で2つのクラスを設計する.
異なる車種、異なる型番のエンジンを抽象化し、異なるタイプの車に異なるタイプのエンジンを取り付けると、しかし、事実上、車とエンジンの間には交差(多対多)があり、継承方式ではサブクラスの氾濫を引き起こすため、「エンジンを取り付ける」ことをよく分解し、抽象と行為を分離する必要がある.
例えば、図形の塗りつぶし、図形が複数(矩形、正方形、円、楕円など)あり、色も多く(赤、オレンジ、黄、緑など)あり、異なる図形は異なる色を塗りつぶすことができ、継承で「塗りつぶす」という動作を実現すれば、明らかに不合理である.
  
设计模式概览续(结构型模式)_第1张图片
//     “     ”   ,      ;              

//   
class Engine
{
public:
	virtual void InstallEngine() = 0;  //             ,       “ ”   
};
class Engine4400cc : public Engine
{
public:
	virtual void InstallEngine()
	{
		cout << "   4400cc          " << endl;
	}
};
class Engine4500cc : public Engine
{
public:
	virtual void InstallEngine()
	{
		cout << "   4500cc    ,     " << endl;
	}
};

// 
class Car
{
public:
	Car(Engine *engine)
	{
		this->m_engine = engine;
	}

	virtual void installEngine() = 0;   //           

protected:
	Engine *m_engine;                   //         
};
class BMW5 : public Car
{
public:
	BMW5(Engine *engine) : Car(engine)
	{
		;
	}
	virtual void installEngine()
	{
		m_engine->InstallEngine();      //           ——Engine
	}
};
class BMW6 : public Car
{
public:
	BMW6(Engine *engine) : Car(engine)
	{
		;
	}
	//                      
	virtual void installEngine()
	{
		cout << "   BMW6 " << endl;
		m_engine->InstallEngine();     //     
	}
};

//    car   engine  ,           
void main()
{
	Engine	*engine = NULL;
	BMW6	*bmw6 = NULL;

	engine = new Engine4400cc;
	bmw6 = new BMW6(engine);
	bmw6->installEngine();

	delete bmw6;
	delete engine;
}

6、外観モード(facade)Facadeモードは、クラスライブラリ、サブシステムなど、類似の機能を有するクラスのセットであり、一貫した簡単なインタフェースを提供する.この一貫した簡単なインタフェースはfacadeと呼ばれる.
適用:サブシステムにインタフェースを統合し、サブシステムをより使いやすくします.
class SubSystemA
{
public:
	void doThing()
	{
		cout << "SubSystemA run" << endl;
	}
};
class SubSystemB
{
public:
	void doThing()
	{
		cout << "SubSystemB run" << endl;
	}
};
class SubSystemC
{
public:
	void doThing()
	{
		cout << "SubSystemC run" << endl;
	}
};

class Facade
{
public:
	Facade()
	{
		sysA = new SubSystemA;
		sysB = new SubSystemB;
		sysC = new SubSystemC;
	}
	~Facade()
	{
		delete sysA;
		delete sysB;
		delete sysC;
	}
public:
	void doThing()
	{
		sysA->doThing();
		sysB->doThing();
		sysC->doThing();
	}
private:
	SubSystemA *sysA;
	SubSystemB *sysB;
	SubSystemC *sysC;
};

void main001()    //    
{
	SubSystemA *sysA = new SubSystemA;
	SubSystemB *sysB = new SubSystemB;
	SubSystemC *sysC = new SubSystemC;

	sysA->doThing();
	sysB->doThing();
	sysC->doThing();

	delete sysA;
	delete sysB;
	delete sysC;
}

void main08()   //    ——      
{
	Facade *f = new Facade;
	f->doThing();
	delete f;
}

7.享元モード(flyweight)Flyweightモードは享元モードとも呼ばれ、構造型モードの一つであり、他の類似のオブジェクトとデータを共有することによってメモリ占有量を減少させる.使用シーン:共有の方式で、大量の細粒度のオブジェクトを効率的にサポートする.
class Person
{
public:
	Person(string name, int age)
	{
		this->m_name = name;
		this->age = age;
	}
	virtual void printT() = 0;

protected:
	string	m_name;
	int		age;
};

class Teacher : public Person
{
public:
	Teacher(string name, int age, string id) : Person(name, age)
	{
		this->m_id = id;
	}
	void printT()
	{
		cout << "name:" << m_name << " age:" << age << " m_id:" << m_id << endl;
	}
private:
	string	m_id;
};

//          
class FlyWeightTeacherFactory
{
public:
	FlyWeightTeacherFactory()
	{
		map1.clear();
	}

	~FlyWeightTeacherFactory()  //      ,    Teacher  new   
	{
		while (!map1.empty())
		{
			Person *tmp = NULL;
			map<string, Person *>::iterator it = map1.begin();
			tmp = it->second;
			map1.erase(it);     //             
			delete tmp;
		}
	}

	Person* GetTeacher(string id)
	{
		Person *tmp = NULL;
		map<string, Person *>::iterator it;
		it = map1.find(id);
		if (it == map1.end())  //    
		{
			string	tmpname;
			int		tmpage;
			cout << "
name:"; cin >> tmpname; cout << "
age:"; cin >> tmpage; tmp = new Teacher(tmpname, tmpage, id); map1.insert(pair<string, Person*>(id, tmp)); } else { tmp = it->second; //Person* } return tmp; } private: map<string, Person*> map1; }; void main009() { Person *p1 = NULL; Person *p2 = NULL; FlyWeightTeacherFactory *fwtf = new FlyWeightTeacherFactory; p1 = fwtf->GetTeacher("001"); // p1->printT(); p2 = fwtf->GetTeacher("001"); // p2->printT(); delete fwtf; }

以上、エージェントモード、装飾モード、アダプタモード、コンビネーションモード、ブリッジモード、外観モード、メタモードについて説明した.次に、動作モードについて説明する.
http://blog.csdn.net/songshimvp1/article/details/48970017-テンプレートモード(template)、コマンドモード(command)、責任チェーンモード、ポリシーモード、仲介者モード(mediator)、オブザーバーモード(observer)、メモモード(mememto)、ビジターモード(visitor)、ステータスモード(state)、解釈モード(interpreter)、反復器モード(iterator).