持续更新, 欢迎关注.......
前言
设计目的
高内聚,低耦合
设计原则
1、开放封闭原则
类的改动是通过增加代码进行,而不是修改源代码。
2、单一职责原则
职责单一,对外只提供一种功能,引起类变化的原因都应该只有一个。
3、依赖倒置原则
依赖于抽象,不要依赖于具体实现,也就是针对接口编程。
4、接口隔离原则
一个接口应该只提供一种对外功能,不应该把所有操作都封装到一个接口中。
5、里氏替换原则
任何抽象类出现的地方都可以用他的实现类进行替换。实际就是虚拟机制,语言级别实现面向对象功能。
6、优先使用组合而不是继承
7、迪米特法则
一个对象应该对其他对象尽可能少的了解,从而降低各个对象之间的耦合。
UML类图
参考UML类图几种关系的总结_在类图中,类与类-CSDN博客
创建型模式
单例模式
场景
- 在多个线程之间, 比如初始化一次 socket 资源; 比如 servlet 环境, 共享同一个资源或者
操作同一个对象
在整个程序空间使用全局变量, 共享资源
大规模系统中, 为了性能的考虑, 需要节省对象的创建时间等等。
核心要点
a) 构造函数私有化
b) 提供一个全局的静态方法(全局访问点)
c) 在类中定义一个静态指针, 指向本类的变量的静态变量指针
示例
懒汉式
构造延时到使用Instance时
cpp
#include <iostream>
using namespace std;
//懒汉式
class Singelton {
private:
Singelton()
{
m_singer = NULL;
m_count = 0;
cout << "构造函数 Singelton ... do" << endl;
}
public:
static Singelton *getInstance()
{
if (m_singer == NULL ) //懒汉式: 1 每次获取实例都要判断 2 多线程会有问题
{
m_singer = new Singelton;
}
return m_singer;
}
static void printT()
{
cout << "m_count: " << m_count << endl;
}
private:
static Singelton *m_singer;
static int m_count;
};
Singelton *Singelton::m_singer = NULL; //懒汉式 并没有创建单例对象
int Singelton::m_count = 0;
int main()
{
cout << "演示 懒汉式" << endl;
Singelton *p1 = Singelton::getInstance(); //只有在使用的时候, 才去创建对象。
Singelton *p2 = Singelton::getInstance();
if (p1 != p2) {
cout << "不是同一个对象" << endl;
} else {
cout << "是同一个对象" << endl;
}
p1->printT();
p2->printT();
return 0;
}
运行结果:
bash
演示 懒汉式
构造函数 Singelton ... do
是同一个对象
m_count: 0
m_count: 0
饿汉式
直接编译时就构造
cpp
#include <iostream>
using namespace std;
class Singelton2
{
private:
Singelton2()
{
m_singer = NULL;
m_count = 0;
cout << "构造函数 Singelton ... do" << endl;
}
public:
static Singelton2 *getInstance()
{
// if (m_singer == NULL )
// {
// m_singer = new Singelton2;
// }
return m_singer;
}
static void FreeInstance()
{
if (m_singer != NULL)
{
delete m_singer;
m_singer = NULL;
m_count = 0;
}
}
static void printT()
{
cout << "m_count: " << m_count << endl;
}
private:
static Singelton2 *m_singer;
static int m_count;
};
Singelton2 *Singelton2::m_singer = new Singelton2; //不管你创建不创建实例, 均把实例 new出来
int Singelton2::m_count = 0;
int main()
{
cout << "演示 饿汉式" << endl;
Singelton2 *p1 = Singelton2::getInstance(); //只有在使用的时候, 才去创建对象。
Singelton2 *p2 = Singelton2::getInstance();
if (p1 != p2) {
cout << "不是同一个对象" << endl;
} else {
cout << "是同一个对象" << endl;
}
p1->printT();
p2->printT();
Singelton2::FreeInstance();
Singelton2::FreeInstance();
return 0;
}
运行结果:
bash
构造函数 Singelton ... do
演示 饿汉式
是同一个对象
m_count: 0
m_count: 0
简单工厂模式
场景
核心
1、工厂角色 --负责创建所有实例
工厂类是整个模式的关键,需要包含判断逻辑,能够根据外界给定的信息,决定创建哪个具体类的对象
2、抽象角色 --创建的所有对象的父类
3、具体产品角色 --具体实例对象
示例
工厂类里一定有选择逻辑
cpp
#include <iostream>
#include <cstring>
using namespace std;
//思想: 核心思想是用一个工厂, 来根据输入的条件产生不同的类, 然后根据不同类的 virtual函数得到不同的结果。
//元素分析:
//抽象产品类: 水果类
//具体的水果类: 香蕉类、 苹果类、 梨子
//优点 适用于不同情况创建不同的类时
//缺点 客户端必须要知道基类和工厂类, 耦合性差 增加一个产品, 需要修改工厂类
class Fruit {
public:
virtual void getFruit() = 0;
protected:
private:
};
class Banana : public Fruit {
public:
virtual void getFruit()
{
cout<<"香蕉"<<endl;
}
protected:
private:
};
class Pear : public Fruit {
public:
virtual void getFruit()
{
cout<<"梨子"<<endl;
}
protected:
private:
};
class Factory
{
public:
static Fruit* Create(char *name)
{
Fruit *tmp = NULL;
if (strcmp(name, "pear") == 0)
{
tmp = new Pear();
} else if (strcmp(name, "banana") == 0) {
tmp = new Banana();
} else {
return NULL;
}
return tmp;
}
protected:
private:
};
int main() {
Fruit *pear = Factory::Create("pear");
if (pear == NULL) {
cout << "创建 pear 失败\n";
}
pear->getFruit();
Fruit *banana = Factory::Create("banana");
banana->getFruit();
return 0;
}
运行结果
bash
梨子
香蕉
工厂模式
场景
核心
1、抽象工厂(Creator) 角色 ---工厂方法模式的核心, 任何工厂类都必须实现这个接口。
2、具体工厂( Concrete Creator) 角色
---具体工厂类是抽象工厂的一个实现, 负责实例化产品对象。
3、抽象(Product) 角色
---工厂方法模式所创建的所有对象的父类, 它负责描述所有实例所共有的公共接口。
4、具体产品(Concrete Product) 角色
---工厂方法模式所创建的具体实例对象
和简单工厂模式不同:
a) 多了个抽象工厂类,每个具体工厂类统一来自抽象工厂
b) 添加新的产品对象时,只需添加一个具体对象和一个具体工厂
示例
1、抽象工厂:FruitFactory,具体工厂:BananaFactory、AppleFactory
2、抽象产品:Fruit,具体产品:Banana、Apple
3、main函数调用具体工厂时只是先把具体工厂创建出来,然后通过工厂的GetFruit创建具体对象
cpp
#include "iostream"
using namespace std;
class Fruit
{
public:
virtual void sayname()
{
cout<<"fruit\n";
}
};
class FruitFactory
{
public:
virtual Fruit* getFruit()
{
return new Fruit();
}
};
//香蕉
class Banana : public Fruit
{
public:
virtual void sayname()
{
cout<<"Banana \n"<<endl;
}
};
//香蕉工厂
class BananaFactory : public FruitFactory
{
public:
virtual Fruit* getFruit()
{
return new Banana;
}
};
//苹果
class Apple : public Fruit
{
public:
virtual void sayname()
{
cout<<"Apple \n"<<endl;
}
};
//苹果工厂
class AppleFactory : public FruitFactory
{
public:
virtual Fruit* getFruit()
{
return new Apple;
}
};
int main()
{
FruitFactory * ff = NULL;
Fruit *fruit = NULL;
//1 香蕉
ff = new BananaFactory(); // 1、先创建具体工厂
fruit = ff->getFruit(); // 2、通过具体工厂创建具体对象
fruit->sayname();
delete fruit;
delete ff;
//2 苹果
ff = new AppleFactory();
fruit = ff->getFruit();
fruit->sayname();
delete fruit;
delete ff;
cout<<"hello....\n";
return 0;
}
运行结果:
bash
Banana
Apple
hello....
抽象工厂模式
场景
可以一下生产一个产品族
核心
注意:上图的ConcreteFactory存在漏画问题,应该是CreateProductA(): AbStractProductA 和 CreateProductB(): AbStractProductB
1、抽象工厂角色
2、具体工厂角色
3、抽象产品角色
4、具体产品角色
示例
抽象工厂类:FruitFactory,具体工厂类:NorthFruitFactory、SourthFruitFactory;
抽象产品类:Fruit,具体产品类:SouthBanana/SouthApple/NorthBanana/NorthApple。
GetFruit切换成了GetApple、GetBanana,所以可以建立产品族。
cpp
#include "iostream"
using namespace std;
class Fruit
{
public:
virtual void sayname()
{
cout<<"fruit\n";
}
};
class FruitFactory
{
public:
virtual Fruit* getApple()
{
return new Fruit();
}
virtual Fruit* getBanana()
{
return new Fruit();
}
};
//南方香蕉
class SouthBanana : public Fruit
{
public:
virtual void sayname()
{
cout<<"South Banana \n"<<endl;
}
};
//南方苹果
class SouthApple : public Fruit
{
public:
virtual void sayname() {
cout << "South Apple \n" << endl;
}
};
//北方香蕉
class NorthBanana : public Fruit
{
public:
virtual void sayname()
{
cout<<"North Banana \n"<<endl;
}
};
//北方苹果
class NorthApple : public Fruit
{
public:
virtual void sayname()
{
cout<<"North Apple \n"<<endl;
}
};
class SourthFruitFactory : public FruitFactory
{
public:
virtual Fruit* getApple()
{
return new SouthApple();
}
virtual Fruit* getBanana()
{
return new SouthBanana();
}
};
class NorthFruitFactory : public FruitFactory
{
public:
virtual Fruit* getApple()
{
return new NorthApple();
}
virtual Fruit* getBanana()
{
return new NorthBanana();
}
};
int main()
{
FruitFactory * ff = NULL;
Fruit *fruit = NULL;
ff = new SourthFruitFactory(); // 1、建个南方工厂
fruit = ff->getApple(); // 2、建立南方苹果
fruit->sayname();
fruit = ff->getBanana(); // 3、建立南方香蕉
fruit->sayname();
delete fruit;
delete ff;
ff = new NorthFruitFactory();
fruit = ff->getApple();
fruit->sayname();
fruit = ff->getBanana();
fruit->sayname();
delete fruit;
delete ff;
cout<<"hello....\n";
return 0;
}
运行结果
bash
South Apple
South Banana
North Apple
North Banana
hello....