C++之设计模式

12 篇文章 3 订阅
7 篇文章 0 订阅

模式:
概述:在一定环境中解决问题的方案。包括三个基本元素,问题,解决方案,环境。
设计模式:
概述:一套被人反复使用,多人知晓,经过分类编目的,代码设计经验的总结。
设计模式的分类:
创建型,结构型,行为型
创建型模式:分5种:
工厂模式,抽象工厂模式,建造者模式,原型模式,单例模式。
结构型模式:分7种:
代理模式,装饰者模式,适配器模式,桥接模式,组合模式,桥接模式,外观模式,享元模式。
行为型模式:分11种:
模板模式,命令模式,责任链模式,策略模式,中介者模式,观察者模式,备忘录模式,访问者模式,状态模式,解释者模式,iterator pattern模式。

设计模式的基本原则:
开放封闭原则,依赖倒置原则,接口隔离原则,里氏替换原则,合成复用原则,迪米特法则。
开放封闭原则:类的改动是通过增加代码进行的,不是修改源代码。
依赖倒置原则:依赖于抽象(接口),不依赖于具体实现(类),针对接口编程。
接口隔离原则:一个接口只提供一种对外功能。

创建型模式的介绍:
为何使用单例模式?
比如多个线程之间,初始化一次socket资源,整个程序中间使用全局变量,共享资源。大规模系统中,为了性能考虑,节省了对象创造的时间。
实现单例模式的步骤:
构造函数私有化,提供一个全局的静态方法,在类中定义一个静态指针,指向本类的变量的静态变量指针。
单例模式分类及实现:
懒汉式和饿汉式。
懒汉式:
#include
#include <pthread.h>

using namespace std;

pthread_mutex_t mutex; //多线程中使用单例模式的懒汉式,要线程同步

class Singleton
{
private:
static Singleton *mInstance;
static int count;
private:
Singleton() //构造函数属性是私有,只能在类的内部创建对象
{
}
public:
static Singleton *GetInstance() //main函数只能通过GetInstance创建对象
{
if (NULL == mInstance)
{
usleep(10000);
mInstance = new Singleton;
}
count++;

	return mInstance;
}

int GetCount()
{
	return count;
}

void Release()
{
	count--;
	if (count == 0 && mInstance != NULL)   //最后一个对象释放,才会释放内存
	{
		delete mInstance;
	}
}

};

Singleton *Singleton::mInstance = NULL;
int Singleton::count = 0;

void *get_instance(void *arg)
{
pthread_mutex_lock(&mutex);
Singleton *s = Singleton::GetInstance();
pthread_mutex_unlock(&mutex);
cout << s << endl;
}

int main()
{
//Singleton s = new Singleton; //构造函数私有, 不能在外部创建对象
/

Singleton *s1 = Singleton::GetInstance();
Singleton *s2 = Singleton::GetInstance();
Singleton *s3 = Singleton::GetInstance();
Singleton *s4 = Singleton::GetInstance();

cout << s1->GetCount() << endl;

if (s1 == s2)
{
	cout << "对象相同" << endl;
}

s1->Release();

cout << s2->GetCount() << endl;

*/

pthread_mutex_init(&mutex, NULL);

pthread_t tid[5];
for (int i = 0; i < 5; i++)
{
	int ret = pthread_create(&tid[i], NULL, get_instance, NULL);
	if (ret != 0)
	{
		perror("pthread_create");
	}
}

for (int i = 0; i < 5; i++)
{
	void *status;
	pthread_join(tid[i], &status);
}

pthread_mutex_destroy(&mutex);

return 0;

}

饿汉式:
#include

using namespace std;

class Singleton
{
private:
static Singleton *mInstance;
static int count;
private:
Singleton()
{

}

public:
static Singleton *GetInstance()
{
count++;
return mInstance;
}
int GetCount()
{
return count;
}
void Release()
{
count–;
if (0 == count && mInstance != NULL)
{
delete mInstance;
}
}
};

Singleton *Singleton::mInstance = new Singleton; //先申请内存,恶汉式 不存在线程同步
int Singleton::count = 0;

int main()
{
Singleton *s1 = Singleton::GetInstance();
Singleton *s2 = Singleton::GetInstance();
Singleton *s3 = Singleton::GetInstance();
Singleton *s4 = Singleton::GetInstance();

cout << s1 << endl;
cout << s2 << endl;
cout << s3 << endl;
cout << s4 << endl;

return 0;

}

懒汉式和饿汉式的线程安全:多线程会导致多个实例的产生,从而导致代码运行不正确以及内存的泄露。

简单工厂模式
包括三个角色,工厂角色,抽象角色,具体产品角色。
工厂角色:负责创建所有实例的内部逻辑,
抽象角色:简单工厂模式所产生所有对象的父类,负责描述所有实例的端口。
具体产品角色:所创建的具体实例对象。
缺点:“高内聚”做的不好。扩展性也做的不好。

代码部分:
#include

using namespace std;

class Fruit
{
protected:
int age;
public:
Fruit(int a)
{
age = a;
}
virtual void print() = 0;
};

class Apple : public Fruit
{
public:
Apple(int a) : Fruit(a)
{

}
void print()
{
	cout << "this is apple.." << endl;
}

};

class Banana : public Fruit
{
public:
Banana(int a) : Fruit(a)
{

}
void print()
{
	cout << "this is banana..." << endl;
}

};

class Factory
{
public:
Fruit *CreateApple()
{
return new Apple(7);
}

Fruit *CreateBanana()
{
	return new Banana(12);
}

};

int main()
{
/*Fruit f = new Apple(7);
f->print();
delete f;
/

Factory *fac = new Factory;
Fruit *f = fac->CreateApple();
f->print();
delete f;

f = fac->CreateBanana();
f->print();
delete f;

return 0;

}

工厂模式:(又叫多态工厂模式)
包括4个角色:抽象工厂角色,具体工厂角色,抽象角色,具体产品角色。
#include

//工厂模式解决了简单工厂模式不符合开放封闭原则的问题
//工厂如果再添加新的功能,是通过添加代码而不是修改代码实现

using namespace std;

class Fruit
{
protected:
int age;
public:
Fruit(int a)
{
age = a;
}
virtual void print() = 0;
};

class Apple : public Fruit
{
public:
Apple(int a) : Fruit(a)
{

}
void print()
{
	cout << "this is apple.." << endl;
}

};

class Banana : public Fruit
{
public:
Banana(int a) : Fruit(a)
{

}
void print()
{
	cout << "this is banana..." << endl;
}

};

class Factory
{
public:
virtual Fruit *Create() = 0;
};

class AppleFactory : public Factory
{
public:
Fruit *Create()
{
return new Apple(10);
}
};

class BananaFactory : public Factory
{
public:
Fruit *Create()
{
return new Banana(12);
}
};

//如果再生产新的水果,只需要添加代码,不需要修改源代码

int main()
{
Factory *fac;
Fruit *f;

fac = new AppleFactory;
f = fac->Create();
f->print();

return 0;

}

抽象工厂模式:(能够创建多个产品族的产品对象)
包含的角色:抽象工厂角色,具体工厂角色,抽象角色,具体产品角色。
代码如下:
#include

using namespace std;

class CPU
{
public:
virtual void print() = 0;
};

class IntelCPU : public CPU
{
public:
void print()
{
cout << “this is Intel CPU…” << endl;
}
};

class AMDCPU : public CPU
{
public:
void print()
{
cout << “this is AMD CPU…” << endl;
}
};

class HardDisk
{
public:
virtual void print() = 0;
};

class AHardDisk : public HardDisk
{
public:
void print()
{
cout << “this is A harddisk…” << endl;
}
};

class BHardDisk : public HardDisk
{
public:
void print()
{
cout << “this is B harddisk…” << endl;
}
};

class Factory //抽象工厂 可以生产一系列的产品
{
public:
virtual CPU *CreateCPU() = 0;
virtual HardDisk *CreateHardDisk() = 0;
};

class IBM : public Factory
{
public:
CPU *CreateCPU()
{
return new IntelCPU;
}
HardDisk *CreateHardDisk()
{
return new AHardDisk;
}
};

class Dell : public Factory
{
public:
CPU *CreateCPU()
{
return new AMDCPU;
}

HardDisk *CreateHardDisk()
{
	return new BHardDisk;
}

};

void CreatePC(Factory *f)
{
CPU *cpu = f->CreateCPU();
HardDisk *hard = f->CreateHardDisk();
cpu->print();
hard->print();

delete cpu;
delete hard;

}

int main()
{
cout << “生产IBM电脑” << endl;
Factory *f = new IBM;
CreatePC(f);
delete f;

cout << "生产Dell电脑" << endl;
f = new Dell;
CreatePC(f);
delete f;

return 0;

}

三种工厂模式的区别:
简单工厂模式:用来生产同一级别的任意产品。
工厂模式:用来生产同一级别的固定产品
抽象工厂模式:用来生产不同产品族的任意产品。

建造者模式:
功能;把复合对象创建过程加以抽象,通过子类继承和重载的方式,动态的创建具有复合属性的对象。
包含的角色:builder,concretebuilder,director,product。
builder;为创造产品各个部分,统一对象接口。
concretebuilder:具体创建产品各个部分。
director:构造 一个使用复杂builder的对象
product:表示被构造的复杂对象。
代码如下:

#include

using namespace std;

class House
{
private:
string window;
string door;
string wall;
public:
House()
{

}
void set_window(string win)
{
	window = win;
}
void set_door(string d)
{
	door = d;
}
void set_wall(string wa)
{
	wall = wa;
}

};

class Builder
{
private:
House *house;
public:
Builder(House *h)
{
house = h;
}
void constructor() //把构建对象的过程封装在类中
{
house->set_window(“WINDOW”);
house->set_door(“DOOR”);
house->set_wall(“WALL”);
}
};

int main()
{
#if 0
House *h = new House;
h->set_window(“WINODW”);
h->set_door(“DOOR”);
h->set_wall(“WALL”);
#endif

House *h = new House;
Builder *b = new Builder(h);
b->constructor();

return 0;

}

原型模式:
功能:通过一个已存在的对象进行新对象的创建接口。
代码如下:
#include

using namespace std;

//功能类似于C++中的拷贝构造函数

class Person
{
protected:
string name;
int age;
public:
Person(string n, int a)
{
name = n;
age = a;
}

virtual void print() = 0;
virtual Person *clone() = 0;

};

class Student : public Person
{
private:
int id;
public:
Student(string n, int a, int i) : Person(n, a)
{
id = i;
}

void print()
{
	cout << name << " "  << age << " " << id << endl;
}

Person *clone()
{
	Student *tmp = new Student("aaaa", 0, 0);
	*tmp = *this;
	return tmp;
}

};

int main()
{
Person *s1 = new Student(“jack”, 23, 1);
Person *s2 = s1->clone();
s2->print();

return 0;

}

结构型模式
代理模式:
功能:为其他对象提供一种代理,以控制这个对象的访问。
包含的角色:subject,realsubject,procxy.
subject:(抽象主题):真实主题与代理主题的共同接口。
realsubject:(真实主题):定义了代理角色所代表的真实对象。
procxy:(代理主题):含有对真实主题角色的使用,通常将客户端传递给真实主题之前或之后的操作。
代码如下:
#include

using namespace std;

class BookStore
{
private:
static int num;
public:
void SaleBook()
{
num++;
}

static int GetNum()
{
	return num;
}

};

int BookStore::num = 0;

class Net //代理
{
private:
BookStore *b;
public:
Net(BookStore *book)
{
b = book;
}
void SaleBook()
{
b->SaleBook();
}
};

int main()
{
BookStore *book = new BookStore;
Net *n = new Net(book);

book->SaleBook();
book->SaleBook();
book->SaleBook();
n->SaleBook();
n->SaleBook();
n->SaleBook();

cout << BookStore::GetNum() << endl;

return 0;

}

装饰模式:功能;把要添加的附加功能分别放在单独的类中,并让这个类包含它要包含的对象
包含的角色:component,concreatecomponent,decorator,
component:定义一个对象接口。
concreatecomponent:定义一个具体的对象
decorator:装饰抽象类,继承了component。
代码如下:
#include

using namespace std;

class Phone
{
public:
virtual void function() = 0;
};

class CallPhone : public Phone
{
public:
void function()
{
cout << “this is call phone…” << endl;
}
};

class MusicPhone : public Phone
{
private:
Phone *phone;
public:
MusicPhone(Phone *p)
{
phone = p;
}
void function()
{
phone->function();
cout << “this is music phone…” << endl;
}
};

class NetPhone : public Phone
{
private:
Phone *phone;
public:
NetPhone(Phone *p)
{
phone = p;
}
void function()
{
phone->function();
cout << “this is net phone…” << endl;
}
};

int main()
{
cout << “普通手机” << endl;
Phone *p1 = new CallPhone;
p1->function();

cout << "音乐手机" << endl;
Phone *p2 = new MusicPhone(p1);   //在已有对象的基础上添加新的功能
p2->function();

cout << "上网手机" << endl;
//Phone *p3 = new NetPhone(p2);
Phone *p3 = new NetPhone(p1);
p3->function();

return 0;

适配器模式:功能;改变接口形式。
包含的角色:
client,target,adapter,
target:客户所期待的接口。
adapter:通过内部包装,把源接口换成目标接口。
代码如下:
#include

using namespace std;

class Voltage
{
protected:
int vol;
public:
virtual int get_vol() = 0;
};

class Vol_220 : public Voltage
{
public:
Vol_220()
{
vol = 220;
}

int get_vol()
{
	return vol;
}

};

class Adapter : public Voltage //通过适配器,修改原有类的接口
{
private:
Voltage *vol;
public:
Adapter(Voltage *v)
{
vol = v;
}
int get_vol()
{
if (vol->get_vol() == 220)
{
return 5;
}
else
{
return 220;
}
}
};

class Phone
{
private:
Voltage *vol;
public:
Phone(Voltage *v)
{
vol = v;
}
void start()
{
if (vol->get_vol() > 5)
{
cout << “the phone die…” << endl;
}
else if (vol->get_vol() == 5)
{
cout << “the phone start…” << endl;
}
}
};

int main()
{
#if 0
Voltage *v = new Vol_220;
Phone *p = new Phone(v);
p->start();
#endif
Voltage *v = new Vol_220;
Voltage *a = new Adapter(v);
Phone *p = new Phone(a);
p->start();

return 0;

}

**组合模式:**功能:通过递归手段构造树形结构。
包含的角色:component,leaf,composite
component:为所有对象定义统一接口
leaf:component的实现子类
composite:component的实现子类
代码如下:#include
#include

using namespace std;

class BaseFile //抽象类 文件
{
protected:
string name;
list<BaseFile *> *l;
public:
BaseFile(string n)
{
name = n;
}
virtual int add(BaseFile *b) = 0;
virtual int remove(BaseFile *b) = 0;
virtual string get_name() = 0;
virtual list<BaseFile *> *get_child() = 0;
};

class iFile : public BaseFile
{
public:
iFile(string n) : BaseFile (n)
{
}

int add(BaseFile *b)
{
	return -1;
}

int remove(BaseFile *b)
{
	return -1;
}

string get_name()
{
	return name;
}

list<BaseFile *> *get_child()
{
	return NULL;
}

};

class Dir : public BaseFile
{
public:
Dir(string n) : BaseFile(n)
{
l = new list<BaseFile *>;
}

int add(BaseFile *b)
{
	l->push_back(b);
}

int remove(BaseFile *b)
{
	delete b;
	l->remove(b);   //存在内存泄漏
}

string get_name()
{
	return name;
}

list<BaseFile *> *get_child()
{
	return l;
}

};

void show(BaseFile *root, int gap)
{
if (root == NULL)
{
return;
}

for (int i = 0; i < gap; i++)
{
	cout << "-----";
}

cout << root->get_name() << endl;

list<BaseFile *> *l = root->get_child();
if (NULL != l)   //是文件夹
{
	for (list<BaseFile *>::iterator it = l->begin(); it != l->end(); it++)
	{
		show(*it, gap + 1);
	}
}

}

int main()
{
BaseFile *d1 = new Dir(“home”);
BaseFile *d2 = new Dir(“lesson1”);
BaseFile *d3 = new Dir(“lesson2”);
BaseFile *f1 = new iFile(“1.c”);
BaseFile *f2 = new iFile(“2.c”);
BaseFile *f3 = new iFile(“3.c”);
BaseFile *f4 = new iFile(“4.c”);

d1->add(f1);   //把f1对象添加到d1对象中   把文件1.c添加到文件夹home下
d1->add(f2);
d1->add(f3);
d1->add(f4);
d1->add(d2);
d1->add(d3);

d2->add(f1);
d2->add(f2);

d3->add(f3);
d3->add(f4);

/*
list<BaseFile *> *l = d1->get_child();
for (list<BaseFile *>::iterator it = l->begin(); it != l->end(); it++)
{
cout << (*it)->get_name() << endl;
}
*/

show(d1, 0);

return 0;

}

**桥接模式:**功能:使用封装继承等行为使不同的类承担不同的责任。把抽象与行为实现分开来。
包含的角色:client,abstraction,refineabstration,implementor,concreateplementor。
client:桥接模式的使用者。
abstraction:抽象类接口对行为实现的引用
代码如下:
#include

using namespace std;

class Phone
{
public:
virtual void name() = 0;
};

class Huawei : public Phone
{
public:
void name()
{
cout << “this is huawei…” << endl;
}
};

class iPhone : public Phone
{
public:
void name()
{
cout << “this is iphone…” << endl;
}
};

class Xiaomi : public Phone
{
public:
void name()
{
cout << “this is xiaomi…” << endl;
}
};

class Soft
{
protected:
Phone *phone;
public:
virtual void work() = 0;
};

class QQ : public Soft
{
public:
QQ(Phone *p)
{
phone = p;
}
void work()
{
phone->name();
cout << “this is qq…” << endl;
}
};

class vChat : public Soft
{
public:
vChat(Phone *p)
{
phone = p;
}
void work()
{
phone->name();
cout << “this is vChat…” << endl;
}
};

int main()
{
Phone *p1 = new iPhone;
Soft *s1 = new QQ(p1);
s1->work();
delete s1;
delete p1;

p1 = new Huawei;
s1 = new vChat(p1);
s1->work();
delete s1;
delete p1;

return 0;

}

**外观模式:**功能:提供一个一致的简单的界面。
包含的角色:facade,clients,packages
facade:为调用方调用一个简单的接口。
clients:调用者
packages;功能提供者。
#include

using namespace std;

class SystemA
{
public:
SystemA()
{
cout << “构造系统A” << endl;
}
void work()
{
cout << “systemA woring…” << endl;
}
~SystemA()
{
cout << “析构系统A” << endl;
}
};

class SystemB
{
public:
SystemB()
{
cout << “构造系统B” << endl;
}
void work()
{
cout << “systemB woring…” << endl;
}
~SystemB()
{
cout << “析构系统B” << endl;
}
};

class SystemC
{
public:
SystemC()
{
cout << “构造系统C” << endl;
}
void work()
{
cout << “systemC woring…” << endl;
}
~SystemC()
{
cout << “析构系统C” << endl;
}
};

class Facade
{
private:
SystemA *sa;
SystemB *sb;
SystemC *sc;
public:
Facade()
{
sa = new SystemA;
sb = new SystemB;
sc = new SystemC;
}

void work()
{
	sa->work();
	sb->work();
	sc->work();
}

~Facade()
{
	delete sa;
	delete sb;
	delete sc;
}

};

int main()
{
#if 0
SystemA *sa = new SystemA;
SystemB *sb = new SystemB;
SystemC *sc = new SystemC;

sa->work();
sb->work();
sc->work();

delete sa;
delete sb;
delete sc;

#endif

Facade *f = new Facade;
f->work();
delete f;

return 0;

}

享元模式:功能:通过与其他类似对象共享数据来减小内存占用。
包含的角色:抽象享元角色,具体享元角色,享元工厂角色。
抽象享元角色:所有具体享元类的父类,规定一些需要实现的公共接口。
具体享元角色:实现了抽象享元规定的方法。
享元工厂角色:负责创建和管理享元角色。
代码如下:
#include
#include

using namespace std;

class Student
{
private:
int id;
string name;
int age;
public:
Student(int i, string n, int a)
{
id = i;
name = n;
age = a;
}
void print()
{
cout << id << " " << name << " " << age << endl;
}
};

class FWFactory
{
private:
map<int, Student *> *m; //映射对象指针
public:
FWFactory()
{
m = new map<int, Student *>; //创建映射对象
}

void insert_info(int id)
{
	map<int, Student *>::iterator it = m->find(id);
	if (it == m->end())   //对象不存在
	{
		cout << "输入学生的名字和年龄..." << endl;

		string n;
		int age;

		cin >> n >> age;

		Student *s = new Student(id, n, age);
		m->insert(make_pair(id, s));
	}
	else
	{
		cout << "学生已经存在,信息如下..." << endl;
		it->second->print();
	}
}

};

int main()
{
int id;
FWFactory *f = new FWFactory;

for (int i = 0; i < 5; i++)
{	
	cin >> id;
	f->insert_info(id);
}
return 0;

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值