C++设计模式

设计模式

一、概述

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;
}

结构型——代理模式

一、概述

  1. 代理模式通过创建一个代理对象来实现对原对象的访问。代理对象在客户端和目标对象之间起到中介作用

  2. 结构:抽象角色类,代理角色类,真实角色类

  3. 好处:代理模式保护了目标对象;将代理对象与目标对象分离,降低了系统耦合度,扩展性增强。

  4. 缺点:在目标对象和客户端直接增加代理,降低了运行效率;代理模式会造成系统类的数量很多,使系统更复杂。

二、代码示范

//代理模式
#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;
}

结构型——装饰模式(包装模式)

一、概述

  1. 装饰模式以透明动态的方式对类的功能进行扩展,是继承关系的一种可替代方案。

  2. 构成:被装饰对象的原始抽象类,具体被装饰对象类,抽象装饰类,具体装饰类

  3. 好处:装饰模式可以动态进行自由组合扩展,比继承更灵活

  4. 缺点:会产生很多小类,使程序变得复杂。

二、代码示例

/*
装饰模式:做奶茶
奶茶种类(具体被装饰对象):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;
}

行为型——观察者模式

一、概述

  1. 观察者模式定义一种一对多的依赖关系,多个观察者监听被观察者,当被观察者状态改变会停止观察者。实现了类与类之间的同步通讯。

  2. 结构:抽象被观察者->具体被观察者;抽象观察者->具体观察者

  3. 好处:符合开闭原则,模块之间界限清晰,增强了代码复用性和可维护性。

  4. 缺点:代码结构会变得复杂;小心循环依赖造成系统崩溃;只能接收到被观察者状态不能影响其状态

二、代码示范

 //观察者模式:主播,订阅者
#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;
}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
目 录 序言 前言 读者指南 第 1 章 引言 1 1.1 什么是设计模式 2 1.2 Smalltalk MVC 中的设计模式 3 1.3 描述设计模式 4 1.4 设计模式的编目 5 1.5 组织编目 7 1.6 设计模式怎样解决设计问题 8 1.6.1 寻找合适的对象 8 1.6.2 决定对象的粒度 9 1.6.3 指定对象接口 9 1.6.4 描述对象的实现 10 1.6.5 运用复用机制 13 1.6.6 关联运行时刻和编译时刻的结构 15 1.6.7 设计应支持变化 16 1.7 怎样选择设计模式 19 1.8 怎样使用设计模式 20 第 2 章 实例研究:设计一个文档编辑器 22 2.1 设计问题 23 2.2 文档结构 23 2.2.1 递归组合 24 2.2.2 图元 25 2.2.3 组合模式 272.3 格式化 27 2.3.1 封装格式化算法 27 2.3.2 Compositor 和 Composition 27 2.3.3 策略模式 29 2.4 修饰用户界面 29 2.4.1 透明围栏 29 2.4.2 Monoglyph 30 2.4.3 Decorator 模式 32 2.5 支持多种视感标准 32 2.5.1 对象创建的抽象 32 2.5.2 工厂类和产品类 33 2.5.3 Abstract Factory 模式 35 2.6 支持多种窗口系统 35 2.6.1 我们是否可以使用 Abstract Factory 模式 35 2.6.2 封装实现依赖关系 35 2.6.3 Window 和 WindowImp 37 2.6.4 Bridge 模式 40 2.7 用户操作 40 2.7.1 封装一个请求 41 2.7.2 Command 类及其子类 41 2.7.3 撤消和重做 42 2.7.4 命令历史记录 42 2.7.5 Command 模式 44 2.8 拼写检查和断字处理 44 2.8.1 访问分散的信息 44 2.8.2 封装访问和遍历 45 2.8.3 Iterator 类及其子类 46 2.8.4 Iterator 模式 48 2.8.5 遍历和遍历过程中的动作 48 2.8.6 封装分析 48 2.8.7 Visitor 类及其子类 51 2.8.8 Visitor 模式 52 2.9 小结 53 第 3 章 创建型模式 54 3.1 Abstract Factory(抽象工厂)—对象创建型模式 57 3.2 Builder(生成器)—对象创建型模式 633.3 Factory Method(工厂方法)—对象创建型模式 70 3.4 Prototype(原型)—对象创建型模式 87 3.5 Singleton(单件)—对象创建型模式 84 3.6 创建型模式的讨论 89 第 4 章 结构型模式 91 4.1 Adapter(适配器)—类对象结构型模式 92 4.2 Bridge(桥接)—对象结构型模式 100 4.3 Composite(组成)—对象结构型模式 107 4.4 Decorator(装饰)—对象结构型模式 115 4.5 FACADE(外观)—对象结构型模式 121 4.6 Flyweight(享元)—对象结构型模式 128 4.7 Proxy(代理)—对象结构型模式 137 4.8 结构型模式的讨论 144 4.8.1 Adapter 与 Bridge 144 4.8.2 Composite、 Decorator 与 Proxy 145 第 5 章 行为模式 147 5.1 CHAIN OF RESPONSIBIL ITY(职责链)—对象行为型模式 147 5.2 COMMAND(命令)—对象行为型模式 154 5.3 INTERPRETER(解释器)—类行为型模式 162 5.4 ITERATOR(迭代器)—对象行为型模式 171 5.5 MEDIATOR(中介者)—对象行为型模式 181 5.6 MEMENTO(备忘录)—对象行为型模式 188 5.7 OBSERVER(观察者)—对象行为型模式 194 5.8 STATE(状态)—对象行为型模式 201 5.9 STRATEGY(策略)—对象行为型模式 208 5.10 TEMPLATE METHOD(模板方法)—类行为型模式 214 5.11 VISITOR(访问者)—对象行为型模式 218 5.12 行为模式的讨论 228 5.12 1 封装变化 228 5.12.2 对象作为参数 228 5.12.3 通信应该被封装还是被分布 229 5.12.4 对发送者和接收者解耦 229 5.12.5 总结 231 第 6 章 结论 232 6.1 设计模式将带来什么 2326.2 一套通用的设计词汇 23

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

念念⁡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值