设计模式概览续(结构型模式)

24 篇文章 7 订阅
4 篇文章 0 订阅
       上一篇介绍了创建型模式 http://blog.csdn.net/songshimvp1/article/details/48786615——单例模式、简单工厂模式,多态工厂模式、抽象工厂模式、建造者模式、原型模式(prototype),接下来介绍结构型模式——代理模式、装饰模式、适配器模式(adapter)、组合模式、桥接模式(bridge)、外观模式(facade)、享元模式(flyweight)。

设计模式详解之——结构型模式

1、代理模式(Proxy)★

Proxy模式,代理模式,是构造型的设计模式之一,它可以为其他对象提供一种代理(Proxy)以控制对这个对象的访问。所谓代理,是指具有与代理元(被代理的对象)具有 相同的接口 的类,客户端必须通过 代理与被代理的目标类 交互,而代理一般在交互的过程中(交互前后)进行某些特别的处理。 适合于:为其他对象提供一种代理以控制对这个对象的访问。实现: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)★

装饰( Decorator )模式又叫做包装模式。通过一种对客户端透明的方式来扩展对象的功能,是继承关系的一个替换方案。 装饰模式就是把要添加的附加功能分别放在单独的类中,并让这个类包含它要装饰的对象,当需要执行时,客户端就可以有选择地、按顺序地使用装饰功能包装对象。 适用于:装饰模式(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)★

通过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)

Composite模式也叫组合模式,是构造型的设计模式之一。通过递归手段来构造树形的对象结构,并可以通过一个对象来访问整个对象树。 适用于:单个对象和组合对象的使用具有一致性。将对象组合成树形结构以表示“部分--整体”    
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)★

       Bridge模式基于类的最小设计原则,通过使用封装、聚合以及继承等行为来让 不同的类 承担 不同的责任。它的主要特点是 把 抽象(abstraction) 与 行为实现(implementation)  分离开来,从而可以保持 各部分的独立性 以及 对应它们的功能扩展。 适用于:桥接模式(Bridge Pattern)是将抽象部分与实现部分分离(解耦合),使它们都可以独立的变化。车 安装 发动机 ;不同型号的车,安装不同型号的发动机,将“车 安装 发动机”这个抽象 和 实现进行分离,两个名字 就设计两个类!
       如果抽象出不同的车型、不同型号的发动机,然后不同类型的车去安装不同类型的发动机,但是事实上车和发动机之间的会有交叉(多对多),如果用继承的方式,会引起子类的泛滥。所以需要把“安装发动机”这个事,做很好的分解;把 抽象 和 行为实现 分开。
       再比如:图形的填充,图形有多个(矩形、正方形,圆、椭圆等),颜色也有很多种(红、橙、黄、绿等),不同的图形可以填充不同的颜色,如果用继承去实现“填充”这一动作,显然非常不合理。
  
//所以需要把“安装发动机”这个事,做很好的分解;把 抽象 和 行为实现 分开

//发动机
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 << "\n请输入老师name:";
			cin >> tmpname;

			cout << "\n请输入老师 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;
}

       上述介绍了结构型模式——代理模式、装饰模式、适配器模式(adapter)、组合模式、桥接模式(bridge)、外观模式(facade)、享元模式(flyweight)。接下来介绍行为型模式 http://blog.csdn.net/songshimvp1/article/details/48970017——模板模式(template)、命令模式(command)、责任链模式、策略模式、中介者模式(mediator)、观察者模式(observer)、备忘录模式(mememto)、访问者模式(visitor)、状态模式(state)、解释模式(interpreter)、迭代器模式(iterator)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值