一、软件设计模式的种类
1.创建型模式
如何创建对象
2.结构型模式
如何实现类和对象的组合
3.行为型模式
类和对象怎么样交互以及怎么样分配职责
二、设计模式的原则
高内聚、低耦合
1.单一职责原则
类的职责比较单一,对外只提供一种功能,引起类变化的原因应该只有一个
2.开闭原则
添加新的功能时,是通过添加代码实现的,而不是去修改源码
3.里氏替换原则
任何抽象类出现的地方都可以用他的实现类来进行替换,实际就是虚拟机制,语言级别实现面向对象的功能
4.依赖倒转原则
依赖于抽象接口,不要依赖具体的实现类,也就是针对接口编程
5.接口隔离原则
不要强迫用户的程序依赖他们不需要的接口方法,一个接口只提供一种对外的功能,不应该把所有操作都封装到一个接口中去
6.合成复用原则
如果使用继承,会导致父类的任何变换都可能影响到子类的行为,如果使用对象组合,就降低了这种依赖关系,对于继承和组合,优先使用组合
7.迪米特法则
一个对象应该对其他对象尽可能少地了解,从而降低各个对象之间的耦合,提高系统的可维护性
三、创建型模型
1.简单工厂设计模式
简单工厂设计模式并不属于Gof23中设计模式之一。
1)简单工厂设计模式的案例代码:
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string>
using namespace std;
class GameRole
{
public:
virtual void roleMove() = 0;
};
//向左移动
class LeftMoveRole : public GameRole
{
public:
virtual void roleMove()
{
cout << "向左移动" << endl;
}
};
//向右移动
class RightMoveRole : public GameRole
{
public:
virtual void roleMove()
{
cout << "向右移动" << endl;
}
};
//向左快速移动
class LeftSpeedMoveRole : public GameRole
{
public:
virtual void roleMove()
{
cout << "向左快速移动" << endl;
}
};
//向右快速移动
class RightSpeedMoveRole : public GameRole
{
public:
virtual void roleMove()
{
cout << "向右快速移动" << endl;
}
};
//移动的动作工厂
class MoveFactory
{
public:
static GameRole* CreateRoleMove(string name)
{
if (name.compare("left") == 0)
{
return new LeftMoveRole;
}
else if (name.compare("right") == 0)
{
return new RightMoveRole;
}
else if (name.compare("leftspeed") == 0)
{
return new LeftSpeedMoveRole;
}
else if (name.compare("rightspeed") == 0)
{
return new RightSpeedMoveRole;
}
}
};
int main()
{
GameRole *role = NULL;
role = MoveFactory::CreateRoleMove("left");
role->roleMove();
delete role;
role = MoveFactory::CreateRoleMove("right");
role->roleMove();
delete role;
role = MoveFactory::CreateRoleMove("leftspeed");
role->roleMove();
delete role;
role = MoveFactory::CreateRoleMove("rightspeed");
role->roleMove();
delete role;
system("pause");
return 0;
}
2).简单工厂设计模式的优缺点以及适用场景
优点:
对象创建和使用的分离
不需要记住类名,只需要记住参数就可以,可以减少开发者的记忆的使用
缺点:
工厂类负责的定西太多,一旦受到影响,系统会不能够工作
增加了系统中类的个数,对开发产生一些复杂度和理解度的问题
违反了“开闭原则”,添加新产品需要修改代码逻辑,工厂类会变得更复杂
适用场景:
工厂类创建对象比较少的情况
客户端只知道传入参数,具体怎么实现并不关心的情况
2.工厂方法设计模式
工厂方法模式 = 简单工厂模式 + 开闭原则
1).工厂方法模式案例代码
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <string>
using namespace std;
class GameRole
{
public:
virtual void roleMove() = 0;
};
//向左移动
class LeftMoveRole : public GameRole
{
public:
virtual void roleMove()
{
cout << "向左移动" << endl;
}
};
//向右移动
class RightMoveRole : public GameRole
{
public:
virtual void roleMove()
{
cout << "向右移动" << endl;
}
};
//向左快速移动
class LeftSpeedMoveRole : public GameRole
{
public:
virtual void roleMove()
{
cout << "向左快速移动" << endl;
}
};
//向右快速移动
class RightSpeedMoveRole : public GameRole
{
public:
virtual void roleMove()
{
cout << "向右快速移动" << endl;
}
};
class AbstractFactory
{
public:
virtual GameRole* CreateGameRole() = 0;
};
class LeftRoleFactory : public AbstractFactory
{
public:
virtual GameRole* CreateGameRole()
{
return new LeftMoveRole;
}
};
class RightRoleFactory : public AbstractFactory
{
public:
virtual GameRole* CreateGameRole()
{
return new RightMoveRole;
}
};
class LeftSpeedRoleFactory : public AbstractFactory
{
public:
virtual GameRole* CreateGameRole()
{
return new LeftSpeedMoveRole;
}
};
class RightSpeedRoleFactory : public AbstractFactory
{
public:
virtual GameRole* CreateGameRole()
{
return new RightSpeedMoveRole;
}
};
int main()
{
GameRole *role = NULL;
AbstractFactory *factory = NULL;
factory = new LeftRoleFactory;
role = factory->CreateGameRole();
role->roleMove();
factory = new RightRoleFactory;
role = factory->CreateGameRole();
role->roleMove();
factory = new LeftSpeedRoleFactory;
role = factory->CreateGameRole();
role->roleMove();
factory = new RightSpeedRoleFactory;
role = factory->CreateGameRole();
role->roleMove();
system("pause");
return 0;
}
2).工厂方法模式的优缺点以及适用场景
优点:
不需要记住具体的类名和具体的参数
对象创建和使用的分离
添加新功能时,无需修改源代码,只需要添加新的代码即可实现
缺点:
类的个数比较多,对开发者的理解度要求高
系统的复杂度比较高
增加了系统的抽象性和理解度
适用场景:
客户端不需要知道它所需要的对象和类
抽象工厂类通过其子类来指定创建那个对象
2.抽象工厂模式
抽象工厂角色:它声明了一组用于创建一族产品的方法,每个方法对应一种产品。
具体工厂角色:实现了在抽象工厂中声明的创建产品的方法,生成一组具体的产品,这些产品构成了一个产品族,每一个产品都位于某个产品等级结构中。
1).抽象工厂模式案例代码
#define _CRT_SECURE_NO_WARNINGS
#include
#include
using namespace std;
//抽象的王者荣耀程咬金角色
class AbstractRoleCYJ
{
public:
virtual void RoleName() = 0;
};
//抽象的王者荣耀后羿角色
class AbstractRoleHY
{
public:
virtual void RoleName() = 0;
};
//抽象的王者荣耀曹操角色
class AbstractRoleCC
{
public:
virtual void RoleName() = 0;
};
//我方的程咬金
class MyCYJ : public AbstractRoleCYJ
{
public:
virtual void RoleName()
{
cout << "我方的程咬金" << endl;
}
};
//敌方的程咬金
class AnotherCYJ : public AbstractRoleCYJ
{
public:
virtual void RoleName()
{
cout << "敌方的程咬金" << endl;
}
};
//我方的后羿
class MyHY : public AbstractRoleHY
{
public:
virtual void RoleName()
{
cout << "我方的后羿" << endl;
}
};
//敌方的后羿
class AnotherHY : public AbstractRoleHY
{
public:
virtual void RoleName()
{
cout << "敌方的后羿" << endl;
}
};
//我方的曹操
class MyCC : public AbstractRoleCC
{
public:
virtual void RoleName()
{
cout << "我方的曹操" << endl;
}
};
//敌方的曹操
class AnotherCC : public AbstractRoleCC
{
public:
virtual void RoleName()
{
cout << "敌方的曹操" << endl;
}
};
//抽象工厂
class AbstractFactory
{
public:
virtual AbstractRoleCYJ* CreateCYJ() = 0;
virtual AbstractRoleHY* CreateHY() = 0;
virtual AbstractRoleCC* CreateCC() = 0;
};
//我方的工厂
class MYFactory : public AbstractFactory
{
public:
virtual AbstractRoleCYJ* CreateCYJ()
{
return new MyCYJ;
}
virtual AbstractRoleHY* CreateHY()
{
return new MyHY;
}
virtual AbstractRoleCC* CreateCC()
{
return new MyCC;
}
};
//敌方的工厂
class AnotherFactory : public AbstractFactory
{
public:
virtual AbstractRoleCYJ* CreateCYJ()
{
return new AnotherCYJ;
}
virtual AbstractRoleHY* CreateHY()
{
return new AnotherHY;
}
virtual AbstractRoleCC* CreateCC()
{
return new AnotherCC;
}
};
int main()
{
AbstractFactory *f = NULL;
AbstractRoleCYJ *cyj = NULL;
AbstractRoleHY *hy = NULL;
AbstractRoleCC *cc = NULL;
f = new MYFactory();
cyj = f->CreateCYJ();
hy = f->CreateHY();
cc = f->CreateCC();
cyj->RoleName();
hy->RoleName();
cc->RoleName();
delete cyj;
delete hy;
delete cc;
f = new AnotherFactory();
cyj = f->CreateCYJ();
hy = f->CreateHY();
cc = f->CreateCC();
cyj->RoleName();
hy->RoleName();
cc->RoleName();
delete cyj;
delete hy;
delete cc;
delete f;
system("pause");
return 0;
}
2).抽象工厂模式的优缺点以及适用场景
优点:
拥有工厂模式方法的优点
当一个产品族中的多个对象被设计成一起工作的时候,能够保证客户端始终只使用一个产品族中的对象
符合开闭原则
缺点:
增加新产品等级结构时,需要改源码,违反开闭原则
适用场景:
拥有等级结构设计的系统