【设计模式】组合实体模式、享元模式、外观模式、代理模式

1、组合实体模式(Composite)

介绍

将对象组合成树形结构以表示“部分-整体”的层次结构。Composite 使得用户对单个对象和组合对象的使用具有一致性

举个例子,比如文件夹和文件的关系。一个文件夹里可能还有其他文件夹和文件,文件夹和文件都要提供一些共同的功能,比如查看大小和属性。这时,文件夹就属于组合类,文件属于叶子类。

角色

  • 一个抽象的内容类,提供组合和叶子一致使用的接口
  • 叶子类,继承内容类
  • 组合类,继承内容类,拥有一个内容类的集合的容器,这个容器可能有叶子或集合。
    请添加图片描述简单来说就是同样的对象,可能是单个的实例,也可能是实例的组合,用这种方法来使他们使用起来具有一致性。

代码实现

#include<iostream>
#include<vector>
using namespace std;

class Component{
public:
	Component(){}
	virtual ~Component(){}
	virtual void Operation()=0;
	virtual void Add(Component* pChild){

	}
	virtual void Remove(Component* pChild){

	}
	virtual Component *GetChild(int nIndex){
		return NULL;
	}
};

class Leaf:public Component{
public:
	Leaf(){}
	virtual ~Leaf(){}
	virtual void Operation(){
		cout<<"Operation by Leaf"<<endl;
	}
};

class Composite:public Component {
public:
	Composite(){}
	virtual ~Composite(){
		for(auto p:m_ListOfComponents){
			delete p;
		}
	}
	virtual void Operation(){
		cout<<"Operation by Composite"<<endl;
	}
	virtual void Add(Component *pChild){
		m_ListOfComponents.push_back(pChild);
	}
	virtual void Remove(Component* pChild){
		for(int i=0;i<m_ListOfComponents.size();i++){

			if(m_ListOfComponents[i]==pChild){
				m_ListOfComponents.erase(m_ListOfComponents.begin()+i);
			}
		}
	}
	virtual Component *GetChild(int nIndex){
		if(nIndex<=0||nIndex>=m_ListOfComponents.size()){
			return NULL;
		}
		return m_ListOfComponents[nIndex];
	}
private:
	vector <Component*> m_ListOfComponents;

};

int main(){
	Leaf* pLeaf1=new Leaf();
	Leaf* pLeaf2=new Leaf();
	Composite* pComposite=new Composite();
	pComposite->Add(pLeaf1);
	pComposite->Add(pLeaf2);
	pComposite->Operation();
	pComposite->GetChild(1)->Operation();
	delete pComposite;
}

2、享元模式

简介

为了避免程序中使用了过多重复的对象而造成过大的内存开销,让重复的对象共享一个对象。将对象的状态分为外部状态和内部状态,可以共享的状态作为内部状态存储在对象中。

角色

  • 一个享元工厂类,用于创建享元类,在使用它创建享元对象时,先检查是否已经创建过相同的对象,如有则返回,如没有则创建一个新的对象。
  • 抽象的享元类,提供统一的接口
  • 享元类(可共享类),继承抽象的享元类
  • 非享元类(不可共享类),继承抽象的享元类

请添加图片描述

代码实现

#include <string>
#include<list>
#include<iostream>
using namespace std;

class Flyweight{
public:
	virtual ~Flyweight(){}
	string GetIntrinsicState(){
		return m_state;
	}
	virtual void Operation(string& ExtrinsicState)=0;
protected:
	Flyweight(const string& state):m_state(state){}
private:
	string m_state;
} ;


class ConcreateFlyweight:public Flyweight{
public:
	ConcreateFlyweight(const string& state):Flyweight(state){}
	virtual ~ConcreateFlyweight(){}
	virtual void Operation(string& ExtrinsicState){
		cout<<GetIntrinsicState()<<" and "<<ExtrinsicState<<endl;
	}

};
class FlyweightFactory{
public:
	FlyweightFactory(){}
	~FlyweightFactory(){
		for(auto it1=m_list.begin(),tem=m_list.begin(), it2=m_list.end();it1!=it2;){
			tem=it1;
			++it1;
			delete(*tem);
		}
		m_list.clear();
	}

	Flyweight* GetFlyweight(const string& key){
		for(auto it1=m_list.begin(), it2=m_list.end();it1!=it2;++it1){
			if((*it1)->GetIntrinsicState()==key){
				cout<<"The Flyweight :"<<key<<"already exist"<<endl;
				return (*it1);
			}
		}
		cout<<"creating a new Flyweight: "<<key<<endl;
		Flyweight* fw=new ConcreateFlyweight(key);
		m_list.push_back(fw);
		return fw;
	}
private:
	list<Flyweight*> m_list;
};



int main(){
	FlyweightFactory ff;
	auto fw1=ff.GetFlyweight("hello");
	string str="okok";
	fw1->Operation(str);
	auto fw2=ff.GetFlyweight("world");
	auto fw3=ff.GetFlyweight("world");
	fw3->Operation(str);
	return 0;
}

3.外观模式

简介

有一些接口,分散在不同的独立模块中,客户不需要知道它们具体都是在哪里实现的,需要将这些接口组合在一起。

比如说KTV中有电视、音响、灯光等设备,都有各自的开关,就可以实现一个总开关的功能。

代码实现

#include<iostream>
using namespace std;

class TV{
public:
	void on(){
		cout<<"TV on"<<endl;
	}
	void off(){
		cout<<"TV off"<<endl;
	}
};


class Light{
public:
	void on(){
		cout<<"Light on"<<endl;
	}
	void off(){
		cout<<"Light off"<<endl;
	}
};


class AU{
public:
	void on(){
		cout<<"AU on"<<endl;
	}
	void off(){
		cout<<"AU off"<<endl;
	}
};

class KTV{
public:
	KTV(){
		pTV=new TV;
		pLT=new Light;
		pAU=new AU;
	}
	void on(){
		pTV->on();
		pLT->on();
		pAU->on();
	}
	void off(){
		pTV->off();
		pLT->off();
		pAU->off();
	}
	~KTV(){
		delete pTV;
		delete pAU;
		delete pLT;
	}

private:
	TV* pTV;
	Light* pLT;
	AU* pAU;
};



int main(){
	KTV* k=new KTV;
	k->on();
}

3、代理模式

简介

指为其他对象提供一种代理,以控制对这个对象的访问。 代理对象在客服端和目标对象之间起到中介作用。

比如一个操作系统,提供运行的接口,我可以实现一个用户登录功能,登录成功之后再运行,这就是一个代理模式。

1、和适配器模式的区别:适配器模式主要改变所考虑对象的接口,而代理模式不能改变所代理类的接口。

2、和装饰器模式的区别:装饰器模式为了增强功能,而代理模式是为了加以控制。

代码实现

#include<iostream>

using namespace std;
class AbstractCommonInterface{
public:
	virtual void run()=0;
};

class MySystem:public AbstractCommonInterface{
public:
	virtual void run(){
		cout<<"Operation run..."<<endl;
	}
};

class MySystemProxy:public AbstractCommonInterface{
public:
	MySystemProxy(string name,string pass):name(name),pass(pass){
		psys=new MySystem;
	}
	bool check(){
		if(name=="admin"&&pass=="admin"){
			return true;
		}
		return false;
	}
	virtual void run(){
		if(check()==true){
			cout<<"check pass"<<endl;
			psys->run();
		}else{
			cout<<"wrong pass"<<endl;
		}
	}
	~MySystemProxy(){
		if(psys!=NULL){
			delete psys;
		}
	}
private:
	string name;
	string pass;
	MySystem *psys;
};

int main(){
	MySystemProxy* pro=new MySystemProxy("admin","admin");
	pro->run();
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
享元设计模式(Flyweight Design Pattern)是一种用于优化大量对象创建和使用的设计模式。在Android开发中,使用享元模式可以有效地减少内存消耗和提高性能。 在享元模式中,对象被分为两种状态:内部状态和外部状态。内部状态是不变的,可以被多个对象共享,而外部状态是可变的,每个对象都有自己的外部状态。 在Android中,典型的例子是使用Bitmap对象来显示图片。当需要显示多个相同的图片时,可以使用享元模式来共享已加载的Bitmap对象,而不是每次都创建新的Bitmap对象。 以下是一个简单的示例代码: ```java public class BitmapFactory { private Map<String, Bitmap> bitmapCache = new HashMap<>(); public Bitmap getBitmap(String path) { Bitmap bitmap = bitmapCache.get(path); if (bitmap == null) { // 如果缓存中没有该Bitmap对象,则创建新的Bitmap对象 bitmap = BitmapFactory.decodeFile(path); bitmapCache.put(path, bitmap); } return bitmap; } } ``` 在上面的示例中,`BitmapFactory` 类使用一个 `bitmapCache` Map 来缓存已加载的 Bitmap 对象。当需要获取 Bitmap 对象时,首先从缓存中查找,如果找到则返回缓存的对象,否则创建新的 Bitmap 对象并存入缓存。 通过使用享元模式,可以避免重复创建相同的 Bitmap 对象,从而减少内存消耗。这在需要频繁加载和显示大量图片的应用中非常有用。 需要注意的是,享元模式适用于有大量相似对象的情况,并且需要权衡共享对象和创建对象的开销。在某些情况下,过度使用享元模式可能会导致代码复杂化,降低可读性和可维护性。因此,在使用享元模式时应根据实际情况进行评估和折衷。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值