设计模式
文章目录
一、概述
1.定义:一套被人广泛知晓,广泛使用,经过分类编目的可靠模板代码设计经验总结。
2.特点:高内聚,低耦合(也是最终目的)
3.核心思想:隔离变化,封装变化
4.意义:使用设计模式可以增强代码的复用性,让代码可读性更好,更可靠。学习设计模式有助于提高职业素养,更好的理解软件结构
二、设计模式的分类:
1.创建型模式:new的解耦(5种)
特点:关注对象的创建,着重对象实例化的方式。创建对象的时候隐藏创建的逻辑过程,而不是直接用new实例化一个对象。
2.结构性:对象的解耦(7种)
特点:关注类和对象的组合,继承的概念被用来组合接口和定义组合对象获得新功能的方式,以形成更大的结构
3.行为型:(11种)
特点:用来对类和对象怎样交互和怎样分配职责进行描述。
三、设计原则
1.开放封闭原则:宁加勿该
一个软件应该对扩展开放,不对修改开放(类的改动通过增加代码实现,而不是改动代码。)
2.依赖倒置原则:面向接口
面向接口(抽象类)编程,不要面向实现编程(将变量和方法抽象在抽象类中);依赖抽象接口而不是具体的实现类。
3.接口隔离原则:一个接口一个功能
一个接口只提供一个功能,不把多个操作都封装到同一个接口(客户程序无需依赖不需要的接口);类之间的依赖关系应当建立在最小的接口上。
好处:接口设计是有限度的,接口设计粒度越小,系统越灵活
缺点:结构变得复杂,导致开发难度增加,可维护性降低
4.里氏替换原则:实现类替换抽象类
任何可以调用父类的情况都可以用子类替代。
里氏替换原则四层含义:
①子类必须实现父类的抽象方法,但不得重写已实现方法
②子类可以扩展自己特有的方法
③子类覆盖或实现父类方法时,参数应更加宽松,否则会调用父类的方法
④子类实现父类的抽象方法时,后置参数(返回值)要比父类严格,否则会调用父类方法
补充:继承的优缺点?
优点:提高代码复用性和可扩展性;提高项目的开放性
缺点:耦合性提高,牵一发而动全身;直接继承父类的属性和方法,灵活性降低
5.合成复用原则:
新对象里面使用已有对象,使其成为已有对象的一部分。优先使用组合的方式而不是继承,如果使用继承,会导致父类的任何变化都可能影响到子类,而组合会降低这种依赖关系。
好处:组合使得系统更加灵活,降低了类之间的耦合度
缺点:一旦类进行修改,需要维护的类很多。
6.迪米特原则:
类要尽量独立,以降低各对象之间的耦合,提高系统的可维护性
好处:类相互解耦,耦合性很低
缺点:产生很多中转类,使系统结构变得很复杂。
创建型——单例模式
一、概述
1.单例模式要保证一个类仅有一个实例化对象,要提供一个全局访问方法。
2.实现思路:
①构造函数私有化;
②提供全局静态方法;
③在类中定义一个指向本类变量的静态指针。
3. 实现:
单例模式的实现方法大概有七种,这里以其中的懒汉式和饿汉式理解分析。
①饿汉式和懒汉式的实现方法,区别在于创建的时机。
②饿汉式在初始化就创建对象,其使用多线程不会创建多个对象,如果对象不用会浪费空间。
③懒汉式在使用时才创建(判断是否存在,不存在才创建),多线程可能会产生多个对象,可以通过加锁解决(代码示例)。单例模式的意义在于资源共享,减少运行所需要的内存性能开销,常用在线程池的实现。
二、代码示例
1.单例模式的简单理解
#include <iostream>
using namespace std;
class Singleton
{
public:
static Singleton *getinstance() //提供给外部创建对象的接口
{
static Singleton *instance = NULL;
//指向本类对象的静态指针指针,唯一
//static修饰类成员变量,表示这个变量被所有实例化对象共享
if(instance == NULL) //被创建一次后则不为空,不再创建
{
objcount++;
instance = new Singleton;
}
return instance;
}
static int getObjcount()
{
return objcount;
}
static void release(Singleton *instance)
{
objcount--;
if(objcount == 1 && instance != NULL)
{
delete instance;
instance = NULL;
}
}
private:
static int objcount;
};
int Singleton::objcount = 0;
int main()
{
Singleton *s1 = Singleton::getinstance();
Singleton *s2 = Singleton::getinstance();
Singleton *s3 = Singleton::getinstance();
cout << Singleton::getObjcount() << endl;
//打印结果为1,说明创建了三个对象后objcount只++了一次,
//只创建了一个对象
cout << s1 << endl;
cout << s2 << endl;
cout << s3 << endl;
//s1,s2,s3打印的地址是相同的,进一步验证了以上说法
Singleton::release(s1);
return 0;
}
2.懒汉式单例模式
//懒汉型单例:在对象被创建前使用多线程,可能会创建多个对象
//本例通过加锁互斥解决该缺陷
#include <iostream>
#include <pthread.h>
using namespace std;
pthread_mutex_t mutex;
class Singleton
{
public:
static Singleton *getinstance() //提供给外部创建对象的接口
{
if(instance == NULL) //创建对象前判断是否为空
{
objcount++;
instance = new Singleton;
}
return instance;
}
static int getObjcount()
{
return objcount;
}
static void release(Singleton *instance)
{
objcount--;
if(objcount == 1 && instance != NULL)
{
delete instance;
instance = NULL;
}
}
private:
Singleton()//构造函数私有化
{
cout << "Singleton" << endl; //打印了一次
}
//补充:构造函数私有化的意义
//构造函数私有化后,只能通过static静态成员函数(本例的getinstance)创建,
//而不能在类的外部构造该类及其子类的对象
private:
static int objcount;
static Singleton *instance; //内部创建对象
};
int Singleton::objcount = 0;
Singleton *Singleton::instance = NULL;
void *thread(void *arg)
{
pthread_mutex_lock(&mutex);
Singleton *s = Singleton::getinstance();
cout << s << endl; //多个线程打印的是同一个地址
pthread_mutex_unlock(&mutex);
return NULL;
}
int main()
{
void *status;
pthread_t pid[10];
for(int i = 0; i < 10; i++)
{
pthread_create(&pid[i], NULL, thread, NULL );
}
for(int i = 0; i < 10; i++)
{
pthread_join(pid[i],&status);
}
return 0;
}
3.饿汉式单例模式
//饿汉型单例:不会有线程同步问题
#include <iostream>
#include <pthread.h>
using namespace std;
pthread_mutex_t mutex;
class Singleton
{
public:
static Singleton *getinstance() //提供给外部创建对象的接口
{
objcount++;
return instance;
}
static int getObjcount()
{
return objcount;
}
static void release(Singleton *instance)
{
objcount--;
if(objcount == 0 && instance != NULL)
{
delete instance;
instance = NULL;
}
}
private:
Singleton()//构造函数私有化
{
cout << "Singleton" << endl; //打印了一次
}
private:
static int objcount;
static Singleton *instance;
};
int Singleton::objcount = 0;
Singleton *Singleton::instance = new Singleton; //直接初始化创建
void *thread(void *arg)
{
// pthread_mutex_lock(&mutex);//无需加锁
Singleton *s = Singleton::getinstance();
cout << s << endl; //不加锁打印的也是同一个地址
//pthread_mutex_unlock(&mutex);
return NULL;
}
int main()
{
void *status;
pthread_t pid[10];
for(int i = 0; i < 10; i++)
{
pthread_create(&pid[i], NULL, thread, NULL);
}
for(int i = 0; i < 10; i++)
{
pthread_join(pid[i],&status);
}
return 0;
}
创建型——工厂模式
一、概述
1.工厂模式对new创建对象的过程进行解耦,以降低其耦合度。
2.分类:
①简单工厂模式: 又称为静态工厂方法,一个核心工厂负责了所有产品的创建
构成:抽象产品类 -> 具体产品类,工厂类(生产不同的具体产品)
好处:将产品指针与具体产品分离,实现了new的解耦
缺点:增加产品需要改动工厂类,不符合开闭原则
②工厂方法模式:又称为多态性工厂模式,不同的产品通过抽象工厂类分配给不同的子类去生产。
构成:抽象产品类 -> 具体产品类,抽象工厂类 -> 具体工厂类
好处:满足了开闭原则,新增产品不需要改动原有的工厂类
③抽象工厂模式
构成:基本与工厂方法模式一样,区别在于可以生产不同的产品族类。
④好处及优缺点:在代码示例中理解。
二、代码示例
1.简单工厂模式
//简单工厂模式:
//汽车->宝马/奔驰/奥迪(三个不同的子类)
//工厂->可以生产宝马/奔驰/奥迪
#include <iostream>
using namespace std;
class Car
{
public:
virtual void construct() = 0; //抽象一个创建产品函数
};
class BMW : public Car
{
public:
void construct()
{
cout << "BMW" << endl;
}
};
class BENZ : public Car
{
public:
void construct()
{
cout << "BENZ" << endl;
}
};
class AUDI : public Car
{
public:
void construct()
{
cout << "AUDI" << endl;
}
};
class Factory //工厂:负责创建对象
{
public:
Car *createBMW()
{
return new BMW;
}
Car *createBENZ()
{
return new BENZ;
}
Car *createAUDI()
{
return new AUDI;
}
};
int main()
{
//Car *bmw = new BMW //直接创建汽车对象
Car * c = NULL; //汽车指针不直接指向汽车对象
Factory *f = new Factory; //创建一个汽车工厂
c = f->createBMW(); //对象的创建交给工厂负责
c->construct();
c = f->createBENZ();
c->construct();
return 0;
}
2.工厂方法模式
//工厂方法模式:
//汽车->宝马/奔驰/奥迪(三个不同的子类)
//工厂->宝马/奔驰/奥迪(三个不同的子类)
#include <iostream>
using namespace std;
class Car
{
public:
virtual void construct() = 0; //创建产品函数
};
class BMW : public Car
{
public:
void construct()
{
cout << "BMW" << endl;
}
};
class BENZ : public Car
{
public:
void construct()
{
cout << "BENZ" << endl;
}
};
class AUDI : public Car
{
public:
void construct()
{
cout << "AUDI" << endl;
}
};
class BIEKE : public Car
{
public:
void construct()
{
cout << "BIEKE" << endl;
}
};
class Factory //抽象工厂
{
public:
virtual Car *create() = 0;
};
class BMWf : public Factory //宝马工厂
{
public:
Car *create()
{
return new BMW;
}
};
class BENZf : public Factory//奔驰工厂
{
public:
Car *create()
{
return new BENZ;
}
};
class AUDIf : public Factory //奥迪工厂
{
public:
Car *create()
{
return new AUDI;
}
};
class BIEKEf : public Factory //别克工厂
{
public:
Car *create()
{
return new BIEKE;
}
};
int main()
{
//Car *bmw = new BMW //直接创建汽车对象
Car * c = NULL; //汽车指针不直接指向汽车对象
Factory *f = new BMWf; //创建一个汽车工厂
c = f->create(); //对象的创建交给工厂负责
c->construct();
return 0;
}
3.抽象工厂模式
//抽象工厂模式:
//水果有梨子苹果之分,也有南北之分,南方苹果和北方苹果是同一个族类
//某种程度讲抽象工厂符合开闭原则,比如在原有北方工厂后添加一个南方工厂
//但它又不符合开闭原则,比如我增加一种新的水果桃子,就需要改动工厂类
#include <iostream>
using namespace std;
class Fruit
{
public:
virtual void show() = 0;
};
class NorthPear :public Fruit
{
public:
void show()
{
cout << "北方梨子" << endl;
}
};
class SouthPear :public Fruit
{
public:
void show()
{
cout << "南方梨子" << endl;
}
};
class NorthApple :public Fruit
{
public:
void show()
{
cout << "北方苹果" << endl;
}
};
class SouthApple :public Fruit
{
public:
void show()
{
cout << "南方苹果" << endl;
}
};
class Factory
{
public:
virtual Fruit *createPear() = 0; //生产梨子
virtual Fruit *createApple() = 0; //生产苹果
};
class Northf : public Factory
{
public:
Fruit *createPear()
{
return new NorthPear;
}
Fruit *createApple()
{
return new NorthApple;
}
};
class Southf : public Factory
{
public:
Fruit *createPear()
{
return new SouthPear;
}
Fruit *createApple()
{
return new SouthApple;
}
};
void create(Factory *f)
{
Fruit *fr = NULL;
fr = f->createApple();
fr->show();
fr = f->createPear();
fr->show();
}
int main()
{
Factory *f = new Northf; //创建一个北方工厂
create(f);
delete f;
f = new Southf; //创建南方工厂
create(f);
delete f;
return 0;
}
创建型——建造者模式
一、概述
1.建造者模式将复杂的对象和部件的创建分离开来,通过建造者去选择部件构造对象。
2.构成:具体产品类,抽象建造者类->具体建造者类,指挥类
3.好处:具有良好的封装性
4.缺陷:如果生产流程发生改变,那么要修改很多类
5.与工厂模式的区别:相对于工厂模式,建造者模式考虑了产品的具体组装过程,而工厂模式只关心产品类别。
二、代码示范
1.汽车生产
//建造者模式
//车->需要组装引擎,轮胎,车身等,可以搭配出不同的型号
#include <iostream>
#include <string>
using namespace std;
class Car
{
public:
virtual void setEngine(string engine){m_engine = engine;} //引擎
virtual void setWheel(string wheel){m_wheel = wheel;} //轮胎
virtual void setBody(string body){m_body = body;} //车身
void display()
{
cout << "这辆车的配置是:" << m_engine << ","
<< m_wheel << "," << m_body << endl;
}
private:
string m_engine; //引擎
string m_wheel; //轮胎
string m_body; //车身
};
class Assemble //组装汽车的抽象类
{
public:
virtual void assembleEngine() = 0; //组装引擎
virtual void assembleWheel() = 0; //组装轮胎
virtual void assembleBody() = 0; //组装车身
virtual Car *getCar() = 0;
};
class AssembleA : public Assemble
{
public:
AssembleA(){carA = new Car;} //创建车对象
void assembleEngine(){carA->setEngine("引擎A");}
void assembleWheel(){carA->setWheel("轮胎A");}
void assembleBody(){carA->setBody("车身A");}
Car *getCar(){return carA;}
private:
Car *carA;
};
class AssembleB : public Assemble
{
public:
AssembleB() {carB = new Car;} //创建车对象
void assembleEngine(){carB->setEngine("引擎B");}
void assembleWheel(){carB->setWheel("轮胎B");}
void assembleBody(){carB->setBody("车身B");}
Car *getCar(){return carB;}
private:
Car *carB;
};
class Constructor
{
public:
Constructor(Assemble *assemble){m_Assemble = assemble;}
void assembleCar()
{
m_Assemble->assembleEngine();
m_Assemble->assembleWheel();
m_Assemble->assembleBody();
}
Car *getCar(){return m_Assemble->getCar();}
private:
Assemble *m_Assemble;
};
int main()
{
Assemble *m = new AssembleA(); //A型车订单
Constructor *f = new Constructor(m); //指示建造一辆A型车
f->assembleCar();//建造->getCar()
f->getCar()->display();
delete f;
delete m;
m = new AssembleB(); //B型车订单
f = new Constructor(m); //指示建造
f->assembleCar();//建造->getCar()
f->getCar()->display();
delete f;
delete m;
return 0;
}
2.房屋建造
/*
建造者模式:造房子
房子属性:窗户,门,墙
房子种类:普通,高档,建造者
*/
#include <iostream>
#include <string>
using namespace std;
class House
{
public:
virtual void setDoor(string door){m_door = door;};
virtual void setWindow(string window){m_window = window;};
virtual void setWall(string wall){m_wall = wall;} ;
void display()
{
cout << "房子配置:" << m_door << " ,"
<< m_window << " ," << m_wall << endl;
}
private:
string m_door;
string m_window;
string m_wall;
};
class Assemble : public House
{
public:
virtual void assembleDoor() = 0;
virtual void assembleWindow() = 0;
virtual void assembleWall() = 0;
virtual House* getHouse() = 0;
};
class AssembleA : public Assemble
{
public:
AssembleA(){houseA = new House;}
void assembleDoor(){houseA->setDoor("高端门");}
void assembleWindow(){houseA->setWindow("高端窗");}
void assembleWall(){houseA->setWall("高端墙");}
House* getHouse(){return houseA;}
private:
House *houseA;
};
class AssembleB : public Assemble
{
public:
AssembleB(){houseB = new House;}
void assembleDoor(){houseB->setDoor("低端门");}
void assembleWindow(){houseB->setWindow("低端窗");}
void assembleWall(){houseB->setWall("低端墙");}
House* getHouse(){return houseB;}
private:
House *houseB;
};
class AssembleC : public Assemble
{
public:
AssembleC(){houseC = new House;}
void assembleDoor(){houseC->setDoor("没有门");}
void assembleWindow(){houseC->setWindow("没有窗");}
void assembleWall(){houseC->setWall("低端墙");}
House* getHouse(){return houseC;}
private:
House *houseC;
};
class Constructor
{
public:
Constructor(Assemble *as){a = as;}
void assembleHouse()
{
a->assembleDoor();
a->assembleWindow();
a->assembleWall();
}
House * getHouse()
{
return a->getHouse();
}
private:
Assemble *a;
};
int main()
{
Assemble *a1 = new AssembleA();
Constructor *h1 = new Constructor(a1);
h1->assembleHouse();
h1->getHouse()->display();
delete a1,h1;
a1 = new AssembleB();
h1 = new Constructor(a1);
h1->assembleHouse();
h1->getHouse()->display();
delete a1,h1;
a1 = new AssembleC();
h1 = new Constructor(a1);
h1->assembleHouse();
h1->getHouse()->display();
delete a1,h1;
a1 = NULL;
h1 = NULL;
return 0;
}
创建型——原型模式(克隆模式)
一、概述
1.原型模式用拷贝对象的方式创建新的对象。简化new创建对象的过程。
2.实现方式:在类的内部写一个克隆函数
二、代码示范
//克隆模式
#include <iostream>
using namespace std;
class Person
{
public:
Person(){}
Person(string n):name(n){}
string getName()
{
return name;
}
virtual void show() = 0;
virtual void setId(int i) = 0;
virtual Person *clone() = 0; //克隆函数,克隆模式
protected:
string name;
};
class Student : public Person
{
public:
Student(){}
Student(string n,int i):Person(n),id(i){}
void show()
{
cout << "学生名字:" << name << ", id:" << id << endl;
}
void setId(int i)
{
id = i;
}
Person *clone()
{
Student *temp = new Student;
*temp = *this;
return temp;
}
private:
int id;
};
int main()
{
Person *s1 = new Student("张三",1);
s1->show();
Person *s2 = s1->clone();
s2->show();
s2->setId(2);
s1->show();
s2->show();
return 0;
}
结构型——适配器模式
一、概述
1.适配器模式:给类增加或删减功能能够适配其他本不兼容的类。
2.分类:
①类适配器:多继承实现,并提供适配后的接口
②对象适配器:单继承,将适配的对象进行包装然后提供适配后的接口
3.区别:
类适配器是根据整个类适配,无法选择对象,即本例中将所有USB都转化为typeC;而对象适配器适配的是具体传入的对象。
二、代码示范
1.类适配器
//类适配器
#include <iostream>
using namespace std;
class USB
{
public:
virtual void isUSB()
{
cout << "USB接口" << endl;
}
};
class TypeC
{
public:
void isTypeC()
{
cout << "TypeC接口" << endl;
}
};
class adapter : public USB,public TypeC //多继承
{
public:
void isUSB()
{
isTypeC(); //用TypeC的方法替代USB的方法
}
};
int main()
{
USB *usb = new adapter;
usb->isUSB();
return 0;
}
2.对象适配器
//对象适配器
#include <iostream>
using namespace std;
class USB
{
public:
virtual void isUSB()
{
cout << "USB接口" << endl;
}
};
class TypeC
{
public:
void isTypeC()
{
cout << "TypeC接口" << endl;
}
};
class adapter : public USB //单继承
{
public:
void isUSB()
{
p->isTypeC();//通过对象调用成员方法
}
private:
TypeC *p = new TypeC;
};
int main()
{
USB *usb = new adapter;
usb->isUSB();
return 0;
}
结构型——外观模式
一、概述
1.外观模式是对接口的集成化,通过一个统一的接口用来访问子系统的一群接口。通过简化类的接口,将复杂的过程封装到内部,对外只提供简单的接口。
2.构成:外观类,子系统类
3.优点:减少类之间相互依赖;对用户隐藏子系统的实现,减少了用户与子系统的耦合;子系统方法相对封闭,比较安全。
4.缺点:业务变更则不得不修改外观类,不符合开闭原则
二、代码示范
//智能家居系统
//灯,电视,音响是子系统,各种模式是外观
#include <iostream>
using namespace std;
class LightSystem
{
public:
void on()
{
cout << "开灯" << endl;
}
void off()
{
cout << "关灯" << endl;
}
};
class MovieSystem
{
public:
void on()
{
cout << "开电视" << endl;
}
void off()
{
cout << "关电视" << endl;
}
};
class SoundSystem
{
public:
void on()
{
cout << "开音响" << endl;
}
void off()
{
cout << "关音响" << endl;
}
};
class HomeSystem //家居系统:面向用户,最简单的接口
{
public:
void openKTV()
{
cout << "进入KTV模式:" << endl;
l.off();
m.off();
s.on();
}
void openMV()
{
cout << "观影模式" << endl;
l.off();
m.on();
s.off();
}
void sleep()
{
cout << "睡眠模式" << endl;
l.off();
m.off();
s.off();
}
private:
LightSystem l;
MovieSystem m;
SoundSystem s;
};
int main()
{
HomeSystem home;
home.openKTV();
return 0;
}
结构型——代理模式
一、概述
-
代理模式通过创建一个代理对象来实现对原对象的访问。代理对象在客户端和目标对象之间起到中介作用
-
结构:抽象角色类,代理角色类,真实角色类
-
好处:代理模式保护了目标对象;将代理对象与目标对象分离,降低了系统耦合度,扩展性增强。
-
缺点:在目标对象和客户端直接增加代理,降低了运行效率;代理模式会造成系统类的数量很多,使系统更复杂。
二、代码示范
//代理模式
#include <iostream>
#include <string>
using namespace std;
class Person
{
public:
virtual void renthouse() = 0;
};
class Renter : public Person //租客
{
public:
void renthouse()
{
cout << "想要一套房子" << endl;
}
};
class Intermediary : public Person //代理
{
public:
Intermediary(Person *p):m_person(p){}
void renthouse()
{
m_person->renthouse();
cout << "你好,我是代理,我帮你找房子" << endl;
}
private:
Person *m_person; //真实对象的引用
};
int main()
{
Person *p = new Renter; //租客p
Person *intermediary = new Intermediary(p); //租客代理,绑定租客p
intermediary->renthouse(); //代理去找房子
return 0;
}
结构型——装饰模式(包装模式)
一、概述
-
装饰模式以透明动态的方式对类的功能进行扩展,是继承关系的一种可替代方案。
-
构成:被装饰对象的原始抽象类,具体被装饰对象类,抽象装饰类,具体装饰类
-
好处:装饰模式可以动态进行自由组合扩展,比继承更灵活
-
缺点:会产生很多小类,使程序变得复杂。
二、代码示例
/*
装饰模式:做奶茶
奶茶种类(具体被装饰对象):coco:6,茶百道:5.5,一点点:5
加佐料(装饰):冰:0.5,珍珠:2,布丁:2.5,芋圆:3,糖:1
显示:例:半糖去冰芋圆一点点奶茶,显示价格
*/
#include <iostream>
#include <string>
using namespace std;
class MilkTea //奶茶基类
{
public:
virtual void show() = 0;
virtual double getPrice() = 0;
};
class CoCo : public MilkTea //CoCo奶茶
{
public:
CoCo(){}
CoCo(string name):m_name(name){}
void show()
{
cout << endl << m_name << "(6元)" ;
}
double getPrice()
{
return 6;
}
private:
string m_name;
};
class ChaBaiDao : public MilkTea //茶百道奶茶
{
public:
ChaBaiDao(){}
ChaBaiDao(string name):m_name(name){}
void show()
{
cout << endl << m_name << "(5.5元)" ;
}
double getPrice()
{
return 5.5;
}
private:
string m_name;
};
class OnePoint : public MilkTea // 一点点奶茶
{
public:
OnePoint(){}
OnePoint(string name):m_name(name){}
void show()
{
cout << endl << m_name << "(5元)" ;
}
double getPrice()
{
return 5;
}
private:
string m_name;
};
class Decorator : public MilkTea //装饰的基类
{
public:
void decorator(MilkTea *mt)
{
this->mt = mt;
}
void show()
{
if(mt != NULL)
{
mt->show();
}
}
protected:
MilkTea *mt;
};
class Ice : public Decorator
{
public:
void show()
{
Decorator::show();
cout << " + 冰(0.5元)" ;
}
double getPrice()
{
return mt->getPrice() + 0.5;
}
};
class Pearl: public Decorator
{
public:
void show()
{
Decorator::show();
cout << " + 珍珠(2元)" ;
}
double getPrice()
{
return mt->getPrice() + 2;
}
};
class Sugar : public Decorator
{
public:
void show()
{
Decorator::show();
cout << " + 糖(1元)" ;
}
double getPrice()
{
return mt->getPrice() + 1;
}
};
class Pudding : public Decorator
{
public:
void show()
{
Decorator::show();
cout << " + 布丁(2.5元)" ;
}
double getPrice()
{
return mt->getPrice() + 2.5;
}
};
int main()
{
MilkTea *mt = new CoCo("CoCo奶茶");
Ice *ic = new Ice;
Sugar *sg = new Sugar;
Pearl *pl = new Pearl;
ic->decorator(mt);
sg->decorator(ic);
pl->decorator(sg);
pl->show();
cout << endl << "总价是:" << pl->getPrice() << endl;
//CoCo奶茶(6元) + 冰(0.5元) + 糖(1元) + 珍珠(2元)
//总价是:9.5
delete mt,ic,sg,pl;
mt = new OnePoint("一点点奶茶");
ic = new Ice;
sg = new Sugar;
pl = new Pearl;
Pudding *pd = new Pudding;
ic->decorator(mt);
sg->decorator(ic);
pl->decorator(sg);
pd->decorator(pl);
pd->show();
cout << endl << "总价是:" << pd->getPrice() << "元" << endl;
//一点点奶茶(5元) + 冰(0.5元) + 糖(1元) + 珍珠(2元) + 布丁(2.5元)
//总价是:11元
delete mt,ic,sg,pl;
return 0;
}
结构型——桥接模式
一、概述
1.桥接模式在具体中抽离出抽象对象,通过具体类连接,使他们可以独立变化。
2.构成:抽象部分,抽象部分的实现,具体部分,具体部分的实现。
3.优点:细节对外透明,可扩展性好
4.缺点:系统理解和设计的难度较高,难以理解。
二、代码示范
//桥接模式
//颜色:红色,绿色等; 铅笔:大号,小号等
#include <iostream>
#include <string>
using namespace std;
class Color //抽象颜色类
{
public:
virtual void paint(const string &pentype,const string &name) = 0;
};
class Red : public Color
{
public:
void paint(const string &pentype,const string &name)
{
cout << pentype << "红色的" << name << endl;
}
};
class Green : public Color
{
public:
void paint(const string &pentype,const string &name)
{
cout << pentype << "绿色的" << name << endl;
}
};
class Pen //抽象笔类
{
public:
virtual void draw(const string &name) = 0;
void setColor(Color *c)
{
this->c = c;
}
protected:
Color *c;
};
class smallPencil :public Pen
{
public:
void draw(const string &name)
{
string pentype = "小号铅笔画";
this->c->paint(pentype,name);
}
};
class Pencil :public Pen
{
public:
void draw(const string &name)
{
string pentype = "铅笔画";
this->c->paint(pentype,name);
}
};
int main()
{
Color *c = new Red;
Pen *p = new Pencil;
//定义一个笔对象,一个红色对象;把红色对象给笔对象,调用笔对象画太阳
p->setColor(c);
p->draw("太阳");
delete c;
delete p;
return 0;
}
结构型——享元模式
一、概述
1.享元模式是一种对象池的实现,可以避免反复多次创建和销毁对象。只需创建一个享元池,需要对象的时候去池子里获取,如果不存在再创建。享元模式将可共享的属性状态分离出来,变成享元对象,不可共享的单独处理。
2.构成:抽象享元类,具体享元类,享元工厂类,不可共享类
3.好处:减少对象的数量,降低内存开销,增强系统性能;外部状态相对独立,不会影响内部状态,则享元对象可以在不同的环境被共享。
4.缺点:使系统逻辑复杂化
二、代码示范
#include <iostream>
#include <string>
#include <vector>
using namespace std;
enum pieceColor
{
black,
white
};
class Piece //抽象棋子类
{
public:
Piece(pieceColor color):m_color(color){}
virtual void draw() = 0; //落子
private:
pieceColor m_color;
};
class BlackPiece : public Piece
{
public:
BlackPiece(pieceColor color) : Piece(color){}
void draw()
{
cout << "落下一颗黑色棋子" << endl;
}
};
class WhitePiece : public Piece
{
public:
WhitePiece(pieceColor color) : Piece(color){}
void draw()
{
cout << "落下一颗白色棋子" << endl;
}
};
class PiecePos //坐标类
{
public:
PiecePos(int a,int b):x(a),y(b){}
public:
int x; //横坐标
int y; //纵坐标
};
class PieceBoard //棋盘类
{
public:
PieceBoard(string bname,string wname)
: m_blackName(bname),m_whiteName(wname)
{
m_black = NULL;
m_white = NULL;
}
~PieceBoard()
{
delete m_black;
delete m_white;
}
void setPiece(pieceColor color,PiecePos pos)
{
if(color == black)
{
if(m_black == NULL) //判断是否有棋子的对象
{
m_black = new BlackPiece(color); //创建黑
}
cout << m_blackName << "在位置("
<< pos.x << "," << pos.y << ")" ;
m_black->draw();
m_pos.emplace_back(pos);
}
else
{
if(m_white == NULL) //判断是否有棋子的对象
{
m_white = new WhitePiece(color); //创建黑
}
cout << m_whiteName << "在位置("
<< pos.x << "," << pos.y << ")" ;
m_white->draw();
m_pos.emplace_back(pos);
}
}
private:
vector<PiecePos> m_pos; //落子位置序列
Piece *m_black; //黑子
Piece *m_white; //白字
string m_blackName; //下黑子的人
string m_whiteName; //下白子的人
};
int main()
{
PieceBoard p("A","B");
p.setPiece(black,PiecePos(8,8));
p.setPiece(white,PiecePos(9,9));
p.setPiece(black,PiecePos(9,8));
p.setPiece(white,PiecePos(10,9));
return 0;
}
行为型——模板方法模式
一、概述
1.模板方法模式在一个类中定义一个算法骨架,而将细节交给子类中处理,提高代码复用性。
2.结构:抽象类,具体子类。
二、代码示范
//模板方法模式
#include <iostream>
using namespace std;
class TestPaper
{
public:
void doPaper()
{
studentName();
titleOne(); //题目组成:问题 + 答案
titleTwo();
}
void titleOne()
{
cout << "1 + 1 = ?" << endl;
answerOne();
}
void titleTwo()
{
cout << "1 X 1 = ?" << endl;
answerTwo();
}
virtual void studentName() = 0;
virtual void answerOne() = 0;
virtual void answerTwo() = 0;
};
class NolStudent1 : public TestPaper
{
public:
void studentName()
{
cout << "姓名:张三" << endl;
}
void answerOne()
{
cout << "答案:2" << endl;
}
void answerTwo()
{
cout << "答案:1" << endl;
}
};
class NolStudent2 : public TestPaper
{
public:
void studentName()
{
cout << "姓名:李四" << endl;
}
void answerOne()
{
cout << "答案:3" << endl;
}
void answerTwo()
{
cout << "答案:1" << endl;
}
};
int main()
{
NolStudent1 p1;
p1.doPaper();
cout << endl;
NolStudent2 p2;
p2.doPaper();
return 0;
}
行为型——观察者模式
一、概述
-
观察者模式定义一种一对多的依赖关系,多个观察者监听被观察者,当被观察者状态改变会停止观察者。实现了类与类之间的同步通讯。
-
结构:抽象被观察者->具体被观察者;抽象观察者->具体观察者
-
好处:符合开闭原则,模块之间界限清晰,增强了代码复用性和可维护性。
-
缺点:代码结构会变得复杂;小心循环依赖造成系统崩溃;只能接收到被观察者状态不能影响其状态
二、代码示范
//观察者模式:主播,订阅者
#include <iostream>
#include <string>
#include <set>
using namespace std;
class ObserveBase //观察者基类
{
public:
virtual const string getName() const = 0; //显示姓名
virtual void update(const string &words) = 0; //更新状态
virtual bool operator==(const ObserveBase *outer) const = 0;
};
class TargetBase //被观察者基类
{
public:
virtual void addOneFollower(ObserveBase *outer) = 0; //添加订阅者
virtual void rmOneFollower(ObserveBase *outer) = 0; //删除订阅者
virtual void sendMessage(const string &words) = 0; //发布消息
};
class ObserveFan : public ObserveBase
{
public:
ObserveFan(const string &name) : m_name(name){}
void update(const string &words)
{
this->news = words;
cout << "我是" << m_name << ", 主播告诉我:" << news << endl;
}
const string getName() const
{
return m_name;
}
bool operator==(const ObserveBase *outer) const
{
cout << "重载!" << endl;
return outer->getName() == this->m_name;
}
private:
string m_name;
string news;
};
class TargetHost : public TargetBase //被观察者,主播
{
public:
void addOneFollower(ObserveBase *outer)
{
fans.insert(outer);
cout << outer->getName() << "订阅了" << endl;
}
void rmOneFollower(ObserveBase *outer)
{
for(auto it = fans.begin(); it != fans.end(); it++)
{
if( **it == outer)
{
fans.erase(it);
cout << outer->getName() << "删除成功" << endl;
break;
}
}
}
void sendMessage(const string &words)
{
this->words = words;
cout << "主播发布消息:" << this->words << endl;
for(auto it = fans.begin(); it != fans.end(); it++)
{
(*it)->update(this->words);
}
}
private:
set<ObserveBase *> fans; //粉丝
string words; //主播状态
};
int main()
{
TargetHost *lbw = new TargetHost;
ObserveBase *fan1 = new ObserveFan("张三");
ObserveBase *fan2 = new ObserveFan("李四");
lbw->addOneFollower(fan1);
lbw->addOneFollower(fan2);
lbw->sendMessage("今晚八点直播!");
return 0;
}
行为型——责任链模式
一、概述
1.责任链模式是对一个请求的不同等级的处理。
2.结构:抽象处理者,具体处理者
3.注意事项:
①责任链本身不创建责任链
②有效的降低了请求发送端和请求接收端的耦合度,易扩展,易修改
③责任链可以是一条线,一棵树,一个环
④避免循环依赖,一定要能处理所有请求
二、代码示范
//责任链模式,加薪请求
#include <iostream>
#include <string>
using namespace std;
class Request
{
public:
int salary;
};
class Manager
{
public:
Manager(string name):name(name){}
void setRequest(Manager *tem){manager = tem;}
virtual void solveRequest(Request *r) = 0;
protected:
Manager *manager;
string name;
};
class commonManager:public Manager //部门领导
{
public:
commonManager(string name):Manager(name){}
void solveRequest(Request *r)
{
if(r->salary <= 500)
{
cout << name << "通过了加薪" << r->salary << "的请求!" << endl;
}
else
{
manager->solveRequest(r);
}
}
};
class Major:public Manager //主管领导
{
public:
Major(string name):Manager(name){}
void solveRequest(Request *r)
{
if(r->salary <= 1000 && r->salary > 500)
{
cout << name << "通过了加薪" << r->salary
<< "的请求!" << endl;
}
else
{
manager->solveRequest(r);
}
}
};
class generalManager:public Manager //主管领导
{
public:
generalManager(string name):Manager(name){}
void solveRequest(Request *r)
{
if(r->salary > 1000)
{
cout << name << "通过了加薪" << r->salary << "的请求!" << endl;
}
else
{
manager->solveRequest(r);
}
}
};
int main()
{
Manager *common = new commonManager("张经理");
Manager *major = new Major("李主管");
Manager *general = new generalManager("赵总");
common->setRequest(major);
major->setRequest(general);
Request *r = new Request;
r->salary = 800;
common->solveRequest(r);
return 0;
}
行为型——中介者模式
一、概述
1.中介者模式是用一个中介者对象实现对一系列封装的类进行交互,降低他们之间的耦合度,使其更松散。
2.结构:抽象中介者->具体中介者;抽象同事类->具体同事类
3.优点:减少了类之间的依赖程度,降低耦合。
4.缺点:中介者会变得很复杂很臃肿。
二、代码示范
//中介者模式:中介购房
#include <iostream>
#include <string>
using namespace std;
class HousePerson;
class Mediator
{
public:
virtual void sendMessage(string msg,HousePerson *p) = 0;
};
class HousePerson
{
public:
HousePerson(Mediator *m)
{
m_me = m;
}
protected:
Mediator *m_me;
};
class BuyHousePerson : public HousePerson
{
public:
BuyHousePerson(Mediator *m):HousePerson(m){}
void sendMessage(string msg)
{
m_me->sendMessage(msg,this);
}
void notify(string msg)
{
cout << "买房者收到消息:" << msg << endl;
}
};
class SellHousePerson : public HousePerson
{
public:
SellHousePerson(Mediator *m):HousePerson(m) {}
void sendMessage(string msg)
{
m_me->sendMessage(msg,this);
}
void notify(string msg)
{
cout << "卖房者收到消息:" << msg << endl;
}
};
class ConcreteMediator : public Mediator
{
public:
void sendMessage(string msg,HousePerson *p)
{
if(p == b)
{
s->notify(msg);
}
else
{
b->notify(msg);
}
}
public:
BuyHousePerson *b;
SellHousePerson *s;
};
int main()
{
ConcreteMediator *c = new ConcreteMediator;
BuyHousePerson *b = new BuyHousePerson(c);
SellHousePerson *s = new SellHousePerson(c);
c->b = b;
c->s = s;
b->sendMessage("300万买不买?");
s->sendMessage("不讲价,400万拿去!");
return 0;
}
行为型——备忘录模式
一、概述
1.备忘录模式在不破坏封装的前提下,捕获一个对象的内部状态,并将状态保存在对象之外,使得改状态可以被恢复。
2.结构:备份对象,属性对象,备忘录对象,管理对象
3.优点:
①完善了备忘场景,给程序吃了后悔药
②备份的数据由额外的备忘录对象管理,备忘录由管理者管理,符合单一职责原则
4.缺点:
保存全部或部分状态,会造成大量的内存资源消耗
二、代码示范
//游戏读档
#include <iostream>
#include <vector>
using namespace std;
class Memnto
{
public:
Memnto(int vitality,int attack, int defense)
{
m_vitality = vitality;
m_attack = attack;
m_defense = defense;
}
Memnto& operator=(const Memnto &m)
{
m_vitality = m.m_vitality;
m_attack = m.m_attack;
m_defense = m.m_defense;
return *this;
}
public:
int m_vitality; //血量
int m_attack; //攻击力
int m_defense; //防御力
};
class GameRole
{
public:
GameRole()
{
m_vitality = 100;
m_attack= 10;
m_defense = 10;
}
Memnto save() //保存当前信息
{
Memnto m(m_vitality,m_attack,m_defense);
return m;
}
void load(Memnto m)
{
m_vitality = m.m_vitality;
m_attack = m.m_attack;
m_defense = m.m_defense;
}
void show()
{
cout << "当前状态:" << endl;
cout << "血量:" << m_vitality << endl;
cout << "攻击力" << m_attack << endl;
cout << "防御力" << m_defense << endl << endl;
}
void attack()
{
m_vitality -= 10;
m_defense -= 3;
m_attack -= 2;
}
private:
int m_vitality; //血量
int m_attack; //攻击力
int m_defense; //防御力
};
class Caretaker
{
public:
void save(Memnto m)
{
v.emplace_back(m);
}
Memnto load(int state)
{
return v[state];
}
private:
vector<Memnto> v;
};
int main()
{
Caretaker ct; //创建进度库
GameRole gr; //创建角色
gr.show();//角色数据初值
ct.save(gr.save()); //保存状态值
gr.attack();
cout << "战斗后:" << endl;
gr.show(); //攻击后的状态
cout << "读档..." << endl;
gr.load(ct.load(0));
gr.show();
return 0;
}
行为型——命令模式
一、概述
1.命令模式将请求封装成对象,以便使用不同的请求参数化其他对象,也可搭配备忘录模式支持撤销操作。
2.结构:抽象命令接口->具体命令接口,执行者,调用者
3.优点:
①实现了客户端与服务器的解耦;
②可以动态增加删除命令,比较灵活;
③只需要一个调用方法调用不同的功能命令。
4.缺点:
一个完善的命令系统需要创建很多独立的命令对象
5.命令模式适合搭配其他模式使用,如责任链模式,模板方法模式
二、代码示范
#include <iostream>
#include <list>
#include <algorithm>
using namespace std;
class Cooker //厨师,执行者
{
public:
void cookeRice()
{
cout << "厨师做了一碗米饭!" << endl;
}
void cookeChicken()
{
cout << "厨师做了一碗鸡汤!" << endl;
}
};
class Consumer //请求
{
public:
virtual void commond() = 0;
};
class Rice : public Consumer //米饭
{
public:
Rice(Cooker *ck):c(ck){}
void commond()
{
c->cookeRice();
}
private:
Cooker *c; //命令厨师
};
class Chicken : public Consumer //鸡汤
{
public:
Chicken(Cooker *ck):c(ck){}
void commond()
{
c->cookeChicken();
}
private:
Cooker *c; //命令厨师
};
class Waiter //服务员,调用者
{
public:
void addCmd(Consumer *pc) //添加命令
{
l.emplace_back(pc);
}
void delCmd(Consumer *pc) //撤销命令
{
auto it = find(l.begin(),l.end(),pc);
l.erase(it);
}
void sendCmd()
{
auto it_s = l.begin();
auto it_e = l.end();
while(it_s != it_e)
{
(*it_s)->commond();
it_s++;
}
}
private:
list<Consumer *> l;
};
int main()
{
Cooker *ck = new Cooker;
Consumer *cm = new Rice(ck);
Consumer *cm1 = new Chicken(ck);
Waiter *w = new Waiter; //服务员
w->addCmd(cm);
w->addCmd(cm1);
w->sendCmd();
w->delCmd(cm1);
cout << endl;
w->sendCmd();
return 0;
}
行为型——状态模式
一、概述
1.状态模式允许一个对象状态改变时改变他的行为。
2.角色:抽象状态类、具体状态类、状态维护类
3.优点:
①结构清晰,提高了维护性
②体现开闭原则和单一职责原则
4.缺点:如果状态很多则需要创建过的的状态类
二、代码示范
#include <iostream>
#include <string>
using namespace std;
class state;
class primarystate;
class Highstate;
class Account //账号
{
public:
Account(string name);
string getname() const { return name; }
void setstate(state *s)
{
this->st = s;
}
void loadfile(int point);
private:
string name; //用户名
state *st; //状态:论坛等级和论坛积分
};
class state //状态的抽象类
{
public:
virtual void showstate(int point) = 0;
virtual void setstate(int point) = 0;
virtual void downfile(int point)
{
cout << a->getname() << "下载文件,扣除" << point << endl;
this->m_point -= point;
setstate(point);
showstate(point);
}
void setpoint(int point)
{
this->m_point = point;
}
int getpoint()
{
return m_point;
}
Account *getacc()
{
return a;
}
int getlevel()
{
return level;
}
protected:
Account *a; //状态是谁的
int level; //等级
int m_point; //积分
};
class primarystate : public state //新手账户
{
public:
primarystate(state *s)
{
this->a = s->getacc();
this->m_point = s->getpoint();
this->level = 1;
}
void showstate(int point)
{
cout << "当前积分被扣除" << point << "分" << endl;
this->m_point -= point;
}
void setstate(int point);
primarystate(Account *a)
{
this->a = a;
this->m_point = 0;
this->level = 1;
}
};
class Highstate : public state //高手账户
{
public:
Highstate(state *s)
{
this->a = s->getacc();
this->m_point = s->getpoint();
this->level = 2;
}
void showstate(int point)
{
cout << "当前积分被扣除" << point * 0.8 << "分" << endl;
this->m_point -= point * 0, 8;
}
void setstate(int point);
};
int main()
{
Account a("张三");
a.loadfile(100);
a.setState();
return 0;
}
行为型——策略模式(排序算法)
一、概述
1.策略模式抽象一个父类(算法接口),具体由子类实现算法并封装,这些算法都是同一类算法。
2.结构:抽象策略类,具体策略类,环境角色。
3.好处:可以动态的改变行为,修改策略,比较灵活。
4.缺点:每一个策略都是一个类,类过多;客户有必要知道所有策略才能进行选择。
二、代码示范
//1.策略模式:六大排序(冒泡,选择,插入,快速,归并,希尔)
#include <iostream>
#include <vector>
using namespace std;
void print(vector<int> result)
{
for(auto i : result)
{
cout << i << " " ;
}
cout << endl;
}
class Sort
{
public:
virtual vector<int> mySort(vector<int> a) = 0;
};
class BubbleSort : public Sort //冒泡排序
{
public:
vector<int> mySort(vector<int> a)
{
int step = 1;
cout << "冒泡排序:" << endl;
int len = a.size();
for(int i = 0; i < len; i++)
{
for(int j = 0; j < len - i - 1; j++)
{
if(a[j] > a[j + 1])
{
auto temp = a[j];
a[j] = a[j + 1];
a[j + 1] = temp;
cout << "第" << step++ << "步:";
print(a);
}
}
}
return a;
}
};
class SelectSort : public Sort //选择排序
{
public:
vector<int> mySort(vector<int> a)
{
int step = 1;
cout << "选择排序:" << endl;
int len = a.size();
int i;
for(i = 0; i < len; i++)
{
int temp = a[i];
int min = i;
for(int j = i +1; j < len; j++)
{
if(a[j] < temp)
{
temp = a[j];
min = j;
cout << "第" << step++ << "步:";
print(a);
}
}
temp = a[i];
a[i] = a[min];
a[min] = temp;
}
return a;
}
};
class InsertSort : public Sort //插入排序
{
public:
vector<int> mySort(vector<int> a)
{
int step = 1;
cout << "插入排序:" << endl;
int len = a.size();
for (int i = 0; i < len; i++)
{
int j;
int temp = a[i];
for(j = i; j > 0; j--)
{
if(a[j-1] > temp)
{
a[j] = a[j -1];
a[j - 1] = temp;
cout << "第" << step++ << "步:";
print(a);
}
else
{
break;
}
}
}
return a;
}
};
class Quicksort : public Sort
{
int step = 0;
vector<int> mySort(vector<int> a)
{
if(step == 0){cout << "快速排序:" << endl;step++;}
if(a.size()<=2)
{
if(a[1]<a[0]&&a.size()==2)
{
int temp=a[1];
a[1]=a[0];
a[0]=temp;
cout << "第" << step++ << "步:";
print(a);
}
return a;
}
int i=1;
int j=a.size()-1;
while(i!=j)
{
while(a[j]>=a[0]&&j>i)
{
j--;
}
while(a[i]<=a[0]&&j>i)
{
i++;
}
if(j>i)
{
int temp=a[i];
a[i]=a[j];
a[j]=temp;
cout << "第" << step++ << "步:";
print(a);
}
}
if(a[i]<a[0])
{
int temp=a[i];
a[i]=a[0];
a[0]=temp;
cout << "第" << step++ << "步:";
print(a);
}
if(a.size()>=3)
{
vector<int> temp;
vector<int> a2(a.begin(),a.begin()+i);
vector<int> a3;
temp=mySort(a2);
if(a.begin()+i+1!=a.end())
{
a3.assign(a.begin()+i+1,a.end());
a3=mySort(a3);
}
temp.emplace_back(a[i]);
temp.insert(temp.end(),a3.begin(),a3.end());
a=temp;
cout << "第" << step++ << "步:";
print(a);
}
return a;
}
};
class ShellSort:public Sort
{
vector<int> mySort(vector<int> a)
{
cout << "希尔排序:"<< endl;
int step = 1;
int len=a.size();
int gap=len/2;
while(gap>=1)
{
for(int i=0;i+gap<=len-1;i++)
{
if(a[i]>a[i+gap])
{
int temp=a[i];
a[i]=a[i+gap];
a[i+gap]=temp;
cout << "第" << step++ << "步:";
print(a);
}
}
gap=gap/2;
}
return a;
}
};
class MergeSort : public Sort
{
int step = 0;
vector<int> mySort(vector<int> a)
{
if(step == 0){cout << "归并排序:" << endl;step++;}
cout << "第" << step++ << "步(拆):";
print(a);
int len=a.size();
if(len<=2)
{
if(a[0]>a[1]&&len==2)
{
int temp=a[0];
a[0]=a[1];
a[1]=temp;
cout << "第" << step++ << "步(合):";
print(a);
}
return a;
}
if(len>2)
{
vector<int> a1(a.begin(),a.begin()+(len+1)/2);
vector<int> a2(a.begin()+(len+1)/2,a.end());
a1=mySort(a1);
a2=mySort(a2);
print(a1);
print(a2);
int i=0,j=0;
while(i<a1.size()&&j<a2.size())
{
if(a1[i]>=a2[j])
{
a1.insert(a1.begin()+i,a2[j]);
a2.erase(a2.begin()+j,a2.begin()+j+1);
i++;
}
else
{
i++;
}
}
a=a1;
a.insert(a.end(),a2.begin(),a2.end());
cout << "第" << step++ << "步:(合)";
print(a);
return a;
}
return a;
}
};
class Handler //策略处理类
{
public:
vector<int> mySort(vector<int> a)
{
return s->mySort(a);
}
void setSort(Sort *s)
{
this->s = s;
}
private:
Sort *s;
};
int main()
{
vector<int> a = {122,32,453,534,57,57,24,97,979,23,2,77,90};
cout << "传入序列:" << endl;
print(a);
Handler h;
h.setSort(new BubbleSort());
h.mySort(a);
h.setSort(new SelectSort());
h.mySort(a);
h.setSort(new InsertSort());
h.mySort(a);
h.setSort(new ShellSort());
h.mySort(a);
h.setSort(new MergeSort());
h.mySort(a);
h.setSort(new Quicksort());
h.mySort(a);
return 0;
}