概述
文章目录
- 面向对象设计原则
- 创建型模型
- 简单工厂模式
- 工厂方法模式
- 抽象工厂模式
- 单例模式
- 结构型模型
- 代理模式
- 装饰模式
- 外观模式(facade)
- 适配器模式
- 行为型模式
- 模板方法
- 策略模式
- 命令模式
- 观察者模式
面向对象设计原则
- 依赖倒置原则(DIP)
1.高层模块(稳定)不应该依赖于低层模块(变化),二者都应该依赖于抽象(稳定)。
2.抽象(稳定)不应该依赖于实现细节(变化),实现细节应该于抽象(稳定)。 - 开发封闭原则(OCP)
1.对扩展开放,对更改封闭。
2.类模块应该是可扩展的,但是不可修改。 - 单一职责原则(SRP)
1.一个类应该仅有一个引起它变化的原因。
2.变化的方向隐含着类的责任。 - Liskov替换原则(LSP)
1.子类必须能够替换它们的基类(IS-A)。
2.继承表达类型抽象。 - 接口隔离原则(ISP)
1.不应该强迫客户程序依赖它们不用的方法。
2.接口应该小而完备。 - 合成复用原则(CRP)
优先使用对象组合,而不是类继承
1.类继承通常为“白箱复用”,对象组合通常为“黑箱复用”。
2.继承再某种程度破环了封装性,子类父类耦合度高。
3.而对象组合则只要求被组合的对象具有良好定义的接口。耦合度低。 - 迪米特法则(LoD)
一个对象应当对其他对象尽可能少的了解,从而降低各个对象之间的耦合,提高系统的可维护性。 - 封装变化点
1.使用封装来创建对象之间的分界层,让设计者可以分界层的一侧进行修改,而不会对另一侧产生不良的影响,从而实现层次间的松耦合。 - 针对接口编程,而不是针对实现编程
1.不将变量类型声明为某个特定的具体类,而且声明为某个接口。
2.客户程序无需获知对象的具体类型(业务类型),只需要知道对象所具有的接口。
3.减少系统中各部分的依赖关系,从而实现“高内聚,低耦合”的类型设计方案。
创建型模型
简单工厂模式
违反开闭原则
#include<iostream>
#include<string>
using namespace std;
//抽象水果
class AbstractFruit {
public:
virtual void ShowName() = 0;
};
//苹果
class Apple :public AbstractFruit {
public:
virtual void ShowName(){
cout << "苹果" << endl;
}
};
//香蕉
class Banana :public AbstractFruit {
public:
virtual void ShowName() {
cout << "香蕉" << endl;
}
};
//鸭梨
class Pear :public AbstractFruit {
public:
virtual void ShowName() {
cout << "鸭梨" << endl;
}
};
//水果工厂
class FruitFactory{
public:
static AbstractFruit* CreateFruit(string name) {
if (name == "apple") {
return new Apple;
}
else if (name == "banana") {
return new Banana;
}
else if (name == "pear") {
return new Pear;
}
else
{
return nullptr;
}
}
};
void test1(){
FruitFactory *factory = new FruitFactory;
AbstractFruit *apple = factory->CreateFruit("apple");
apple->ShowName();
delete apple;
}
int main(){
test1();
system("pause");
return 0;
}
工厂方法模式
符合开闭原则,但是类的个数成倍增加,导致类越来越多,增加维护成本
“简单工厂模式”+“开闭原则” = “工厂方法模式”
#include<iostream>
#include<string>
using namespace std;
//抽象水果
class AbstractFruit {
public:
virtual void ShowName() = 0;
};
//苹果
class Apple :public AbstractFruit {
public:
virtual void ShowName() {
cout << "苹果" << endl;
}
};
//香蕉
class Banana :public AbstractFruit {
public:
virtual void ShowName() {
cout << "香蕉" << endl;
}
};
//鸭梨
class Pear :public AbstractFruit {
public:
virtual void ShowName() {
cout << "鸭梨" << endl;
}
};
//抽象水果工厂
class AbstractFruitFactory {
public:
virtual AbstractFruit* CreateFruit() = 0;
};
//苹果工厂
class AppleFactory:public AbstractFruitFactory{
virtual AbstractFruit* CreateFruit() {
return new Apple;
}
};
//香蕉工厂
class BananaFactory :public AbstractFruitFactory {
virtual AbstractFruit* CreateFruit() {
return new Banana;
}
};
//鸭梨工厂
class PearFactory :public AbstractFruitFactory {
virtual AbstractFruit* CreateFruit() {
return new Pear;
}
};
void test1() {
AbstractFruitFactory *factory = new BananaFactory;
AbstractFruit* fruit = factory->CreateFruit();
fruit->ShowName();
delete fruit;
delete factory;
}
int main() {
test1();
system("pause");
return 0;
}
抽象工厂模式
抽象工厂针对的产品族,而不是产品等级结构
#include<iostream>
#include<string>
using namespace std;
//抽象苹果
class AbstractApple {
public:
virtual void ShowName() = 0;
};
//中国苹果
class ChinaApple :public AbstractApple {
public:
virtual void ShowName() {
cout << "中国苹果" << endl;
}
};
//美国苹果
class AmericaApple :public AbstractApple {
public:
virtual void ShowName() {
cout << "美国苹果" << endl;
}
};
//日本苹果
class JapanApple :public AbstractApple {
public:
virtual void ShowName() {
cout << "日本苹果" << endl;
}
};
//抽象香蕉
class AbstractBanana {
public:
virtual void ShowName() = 0;
};
//中国香蕉
class ChinaBanana :public AbstractBanana{
public:
virtual void ShowName(){
cout << "中国香蕉" << endl;
}
};
//美国香蕉
class AmericaBanana :public AbstractBanana {
public:
virtual void ShowName() {
cout << "美国香蕉" << endl;
}
};
//日本香蕉
class JapanBanana :public AbstractBanana {
public:
virtual void ShowName() {
cout << "日本香蕉" << endl;
}
};
//抽象鸭梨
class AbstractPear {
public:
virtual void ShowName() = 0;
};
class ChinaPear :public AbstractPear {
public:
virtual void ShowName() {
cout << "中国鸭梨" << endl;
}
};
class AmericaPear :public AbstractPear {
public:
virtual void ShowName() {
cout << "美国鸭梨" << endl;
}
};
class JapanPear :public AbstractPear {
public:
virtual void ShowName() {
cout << "日本鸭梨" << endl;
}
};
//抽象工厂 针对产品族
class AbstractFactory {
public:
virtual AbstractApple* CreateApple() = 0;
virtual AbstractBanana* CreateBanana() = 0;
virtual AbstractPear* CreatePear() = 0;
};
//中国工厂
class ChinaFactory :public AbstractFactory {
public:
virtual AbstractApple* CreateApple() {
return new ChinaApple;
}
virtual AbstractBanana* CreateBanana() {
return new ChinaBanana;
}
virtual AbstractPear* CreatePear() {
return new ChinaPear;
}
};
//美国工厂
class AmericaFactory :public AbstractFactory {
public:
virtual AbstractApple* CreateApple() {
return new AmericaApple;
}
virtual AbstractBanana* CreateBanana() {
return new AmericaBanana;
}
virtual AbstractPear* CreatePear() {
return new AmericaPear;
}
};
//日本工厂
class JapanFactory :public AbstractFactory {
public:
virtual AbstractApple* CreateApple() {
return new JapanApple;
}
virtual AbstractBanana* CreateBanana() {
return new JapanBanana;
}
virtual AbstractPear* CreatePear() {
return new JapanPear;
}
};
void test1() {
AbstractFactory * factory = nullptr;
AbstractApple *apple = nullptr;
AbstractBanana *banana = nullptr;
AbstractPear *pear = nullptr;
factory = new JapanFactory;
apple = factory->CreateApple();
banana = factory->CreateBanana();
pear = factory->CreatePear();
apple->ShowName();
banana->ShowName();
pear->ShowName();
}
int main() {
test1();
system("pause");
return 0;
}
单例模式
控制一个类的对象个数为1
- 单例实现步骤
1.构造函数私有化
2.增加静态私有的当前类的指针变量
3.提供静态对外接口,可以让用户获得单例对象 - 单例模式(懒汉式,饿汉式)
懒汉碰到多线程,是线程不安全的
饿汉是线程安全的,多线程使用饿汉式
- 概念理解demo
#include<iostream>
using namespace std;
//懒汉式
class Singleton_lazy {
private:
Singleton_lazy() {
}
public:
static Singleton_lazy * getInstance() {
if (psingleton == nullptr) {
psingleton = new Singleton_lazy;
}
return psingleton;
}
private:
static Singleton_lazy* psingleton;
};
Singleton_lazy* Singleton_lazy::psingleton = nullptr;
//饿汉
class Singleton_hungry {
private:
Singleton_hungry() {
}
public:
static Singleton_hungry * getInstance() {
return psingleton;
}
private:
static Singleton_hungry* psingleton;
};
Singleton_hungry* Singleton_hungry::psingleton = new Singleton_hungry;
int main() {
Singleton_lazy *p1 = Singleton_lazy::getInstance();
Singleton_lazy *p2 = Singleton_lazy::getInstance();
if (p1 == p2) {
cout << "是单例" << endl;
}
else
{
cout << "不是单例" << endl;
}
Singleton_hungry *p3 = Singleton_hungry::getInstance();
Singleton_hungry *p4 = Singleton_hungry::getInstance();
if (p3 == p4) {
cout << "是单例" << endl;
}
else
{
cout << "不是单例" << endl;
}
system("pause");
return 0;
}
结构型模型
代理模式
- 为其他对象提供一种代理以控制这个对象的访问。在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用。
#include<iostream>
#include<string>
using namespace std;
//公有接口
class AbstractSystem {
public:
virtual void run() = 0;
};
class MySystem :public AbstractSystem {
public:
virtual void run() {
cout << "系统启动" << endl;
}
};
class SystemProxy :public AbstractSystem {
public:
SystemProxy(string userName,string pwd){
this->userName = userName;
this->pwd = pwd;
pmysystem = new MySystem;
}
virtual void run() {
if (CheckUP()) {
cout << "密码验证成功" << endl;
pmysystem->run();
}
else {
cout<<"验证失败"<<endl;
}
}
bool CheckUP() {
if (this->userName == "admin"&&this->pwd == "admin") {
return true;
}
return false;
}
~SystemProxy() {
if (pmysystem !=nullptr) {
delete pmysystem;
}
}
public:
MySystem * pmysystem;
string userName;
string pwd;
};
int main() {
SystemProxy *sys = new SystemProxy("admin", "admin");
sys->run();
system("pause");
return 0;
}
装饰模式
装饰模式又叫包装模式,通过一种对客户端透明的方式来扩展对象功能,是一种继承关系的一种替代。它可以动态的给一个类增加功能。
#include<iostream>
using namespace std;
class AbstractHero{
public:
virtual void Show() = 0;
public:
int bloodVolume;
int spellPower;
int physicalDamage;
int defensivePower;
};
class HeroA :public AbstractHero {
public:
HeroA(){
bloodVolume = 500;
spellPower = 0;
physicalDamage = 0;
defensivePower = 0;
}
virtual void Show() {
cout << "血量:" << bloodVolume << endl;
cout << "法术强度:" << spellPower << endl;
cout << "物理攻击力:" << physicalDamage << endl;
cout << "防御力:" << defensivePower << endl;
}
};
class AbstractEquipment :public AbstractHero {
public:
AbstractEquipment(AbstractHero *pHero) {
this->pHero = pHero;
}
virtual void Show() {}
public:
AbstractHero * pHero;
};
class ManiacArmor :public AbstractEquipment {
public:
ManiacArmor(AbstractHero *pHero) :AbstractEquipment(pHero){}
//添加额外功能
void AddManiacArmor() {
this->bloodVolume = this->pHero->bloodVolume+1000;
this->spellPower = this->pHero->spellPower;
this->physicalDamage = this->pHero->physicalDamage;
this->defensivePower = this->pHero->defensivePower+30;
delete pHero;
}
virtual void Show() {
AddManiacArmor();
cout << "装上狂徒铠甲后:" << endl;
cout << "血量:" << bloodVolume << endl;
cout << "法术强度:" << spellPower << endl;
cout << "物理攻击力:" << physicalDamage << endl;
cout << "防御力:" << defensivePower << endl;
}
};
class InfinitySword :public AbstractEquipment {
public:
InfinitySword(AbstractHero *pHero) :AbstractEquipment(pHero) {}
void AddInfintiySword() {
this->bloodVolume = this->pHero->bloodVolume;
this->spellPower = this->pHero->spellPower;
this->physicalDamage = this->pHero->physicalDamage + 72;
this->defensivePower = this->pHero->defensivePower;
delete pHero;
}
virtual void Show() {
AddInfintiySword();
cout << "装上无尽之刃后:" << endl;
cout << "血量:" << bloodVolume << endl;
cout << "法术强度:" << spellPower << endl;
cout << "物理攻击力:" << physicalDamage << endl;
cout << "防御力:" << defensivePower << endl;
}
};
void test1() {
AbstractHero* hero = new HeroA();
hero->Show();
hero = new ManiacArmor(hero);
hero->Show();
hero = new InfinitySword(hero);
hero->Show();
}
int main() {
test1();
system("pause");
return 0;
}
外观模式(facade)
根据迪米特法则,如果两个类不必彼此直接通信,那么这两个类就不应当发生直接的相互作用。
- facade模式为一组具有类似功能的类群,比如类库,子系统库等等,提供一个一致的简单的界面。这个一致的简单的界面被称作facade.
外观模式就是将复杂的子类系统抽象到同一个接口进行管理,外界只需要通过次接口与子类系统进行交互而不必要直接与复杂的子类进行交互。 - 家庭影音外观模式应用demo
#include<iostream>
using namespace std;
//电视
class Television {
public:
void On() {
cout << "打开电视" << endl;
}
void Off() {
cout << "关闭电视" << endl;
}
};
//灯
class Light {
public:
void On() {
cout << "打开灯" << endl;
}
void Off() {
cout << "关闭灯" << endl;
}
};
//音响
class Aduio {
public:
void On() {
cout << "打开音响" << endl;
}
void Off() {
cout << "关闭音响" << endl;
}
};
//麦克风
class Mircophone {
public:
void On() {
cout << "打开麦克风" << endl;
}
void Off() {
cout << "关闭麦克风" << endl;
}
};
//DVD
class DVDPlayer {
public:
void On() {
cout << "打开DVD" << endl;
}
void Off() {
cout << "关闭DVD" << endl;
}
};
//游戏机
class GameMachine {
public:
void On() {
cout << "打开游戏机" << endl;
}
void Off() {
cout << "关闭游戏机" << endl;
}
};
class KTVMode {
public:
KTVMode() {
tv = new Television;
light = new Light;
audio = new Aduio;
mircophone = new Mircophone;
player = new DVDPlayer;
}
~KTVMode() {
delete tv;
delete light;
delete audio;
delete mircophone;
delete player;
}
void run() {
tv->On();
light->Off();
audio->On();
mircophone->On();
player->On();
}
public:
Television * tv;
Light *light;
Aduio *audio;
Mircophone *mircophone;
DVDPlayer *player;
};
void test1(){
KTVMode* ktv = new KTVMode;
ktv->run();
}
int main() {
test1();
system("pause");
return 0;
}
适配器模式
将一个类的接口转换成客户希望的另一个接口。使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。
适配器模式就是将已经写好的接口,但是这个接口不符合需求,将写好的接口转换成目标接口。
#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;
struct MyPrint {
void operator()(int v1,int v2) {
cout << v1 + v2 << endl;
}
};
//定义目标接口,适配成什么样子
class Target {
public:
virtual void operator()(int v) = 0;
};
//适配器
class Adapter :public Target {
public:
Adapter(int param) {
this->param = param;
}
virtual void operator()(int v) {
print(v, param);
}
public:
MyPrint print;
int param;
};
Adapter MyBind2nd(int v) {
return Adapter(v);
}
void test1() {
vector<int> v;
for (int i = 0; i < 10; i++) {
v.push_back(i);
}
for_each(v.begin(), v.end(), MyBind2nd(10));
}
int main() {
test1();
system("pause");
return 0;
}
行为型模式
模板方法
定义一个操作中的算法框架,而将一些步骤延迟到子类中。模板方法模式使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。
#include<iostream>
using namespace std;
class DrinkTemplate {
public:
//煮水
virtual void BoildWater() = 0;
//冲泡
virtual void Brew() = 0;
//倒入杯中
virtual void PourInCup() = 0;
//加料
virtual void AddSomething() = 0;
public:
void Make() {
BoildWater();
Brew();
PourInCup();
AddSomething();
}
};
class DrinkTea :public DrinkTemplate {
public:
//煮水
virtual void BoildWater() {
cout << "开始煮水" << endl;
}
//冲泡
virtual void Brew() {
cout << "开始冲茶" << endl;
}
//倒入杯中
virtual void PourInCup() {
cout << "导入杯中" << endl;
}
//加料
virtual void AddSomething() {
cout << "加入柠檬" << endl;
}
};
class DrinkCoffee :public DrinkTemplate {
public:
//煮水
virtual void BoildWater() {
cout << "开始煮水" << endl;
}
//冲泡
virtual void Brew() {
cout << "开始冲咖啡" << endl;
}
//倒入杯中
virtual void PourInCup() {
cout << "导入杯中" << endl;
}
//加料
virtual void AddSomething() {
cout << "加入糖和牛奶" << endl;
}
};
void test1() {
DrinkTea *tea = new DrinkTea;
tea->Make();
DrinkCoffee *coffee = new DrinkCoffee;
coffee->Make();
}
int main() {
test1();
system("pause");
return 0;
}
策略模式
策略模式定义了一系列的算法,并将每一个算法封装起来,而且它们还可以相互替换。策略模式让算法独立于是使用它的客户而独立变化。
#include<iostream>
using namespace std;
class AbstractWeaponStrategy {
public:
virtual void UseWeapon() = 0;
};
class Knife :public AbstractWeaponStrategy {
public:
virtual void UseWeapon() {
cout << "使用匕首" << endl;
}
};
class Ak47 :public AbstractWeaponStrategy {
public:
virtual void UseWeapon() {
cout<<"使用ak47"<<endl;
}
};
class Character {
public:
void SetWeapon(AbstractWeaponStrategy *pWeapon){
this->pWeapon = pWeapon;
}
void UseWeapon() {
this->pWeapon->UseWeapon();
}
private:
AbstractWeaponStrategy * pWeapon;
};
void test1() {
Character *character = new Character;
Knife *knife = new Knife;
character->SetWeapon(knife);
character->UseWeapon();
}
int main() {
test1();
system("pause");
return 0;
}
命令模式
将请求封装为一个对对象,从而让我们可用不同的请求对客户进行参数化,对请求排队或者记录请求日志以及支持可撤销的操作。命令模式可以将请求发送者和接收者完全解耦,发送者与接收者之间没有直接引用关系,发送请求的对象只需要知道如何发送请求,而不必知道如何完成请求。
#include<iostream>
#include<queue>
#include<Windows.h>
using namespace std;
class HandleClientProtocol {
public:
void AddMoney() {
cout << "给玩家增加金币" << endl;
}
void AddDiamond() {
cout << "给玩家增加砖石" << endl;
}
void AddEquipment(){
cout << "给玩家穿装备" << endl;
}
void AddLevel() {
cout << "给玩家升级" << endl;
}
};
class AbstractCommand {
public:
virtual void Handle() = 0;//处理客户端请求
};
class AddMoneyCommand :public AbstractCommand {
public:
AddMoneyCommand(HandleClientProtocol * protocol) {
this->protocol = protocol;
}
virtual void Handle() {
this->protocol->AddMoney();
}
public:
HandleClientProtocol * protocol;
};
class AddDiamondCommand :public AbstractCommand {
public:
AddDiamondCommand(HandleClientProtocol * protocol) {
this->protocol = protocol;
}
virtual void Handle() {
this->protocol->AddDiamond();
}
public:
HandleClientProtocol * protocol;
};
class AddEquipmentCommand :public AbstractCommand {
public:
AddEquipmentCommand(HandleClientProtocol * protocol) {
this->protocol = protocol;
}
virtual void Handle() {
this->protocol->AddEquipment();
}
public:
HandleClientProtocol * protocol;
};
class AddLevelCommand :public AbstractCommand {
public:
AddLevelCommand(HandleClientProtocol * protocol) {
this->protocol = protocol;
}
virtual void Handle() {
this->protocol->AddLevel();
}
public:
HandleClientProtocol * protocol;
};
class Server {
public:
void AddRequest(AbstractCommand* command) {
qCommands.push(command);
}
void StartHandle(){
while (!qCommands.empty()) {
AbstractCommand* concerteCommand = qCommands.front();
concerteCommand->Handle();
qCommands.pop();
Sleep(2000);
}
}
public:
queue<AbstractCommand*> qCommands;
};
void test1() {
HandleClientProtocol *protocol = new HandleClientProtocol;
AbstractCommand *addDiamond = new AddDiamondCommand(protocol);
AbstractCommand *addMoney = new AddMoneyCommand(protocol);
AbstractCommand *addEquipment = new AddEquipmentCommand(protocol);
AbstractCommand *addLevel = new AddLevelCommand(protocol);
Server *server = new Server;
server->AddRequest(addDiamond);
server->AddRequest(addMoney);
server->AddRequest(addEquipment);
server->AddRequest(addLevel);
server->StartHandle();
}
int main() {
test1();
system("pause");
return 0;
}
观察者模式
观察者模式是用于建立一种对象于对象之间的依赖关系,一个对象发生改变时将自动通知其他对象,其他对象将相应做出反应。在观察者模式中,发生改变的对象被称为观察目标,而被通知的对象成为观察者,一个观察目标可以对应多个观察者。
#include<iostream>
#include<list>
using namespace std;
//抽象观察者
class AbstractObserver {
public:
virtual void Update() = 0;
};
//具体观察者
class ObserverA :public AbstractObserver {
public:
ObserverA() {
cout << "车停止,正在等待红灯..." << endl;
}
virtual void Update() {
cout << "A开始启动" << endl;
}
};
class ObserverB :public AbstractObserver {
public:
ObserverB() {
cout << "车停止,正在等待红灯..." << endl;
}
virtual void Update() {
cout << "B开始启动" << endl;
}
};
class ObserverC :public AbstractObserver {
public:
ObserverC() {
cout << "车停止,正在等待红灯..." << endl;
}
virtual void Update() {
cout << "C开始启动" << endl;
}
};
//抽象观察目标
class AbstractObserverTarget {
public:
virtual void AddObserver(AbstractObserver* observer) = 0;
virtual void DelObserver(AbstractObserver* observer) = 0;
virtual void Notify() = 0;
};
//具体观察目标
class ObserverTarget:public AbstractObserverTarget {
public:
virtual void AddObserver(AbstractObserver* observer) {
observerList.push_back(observer);
}
virtual void DelObserver(AbstractObserver* observer) {
observerList.remove(observer);
}
virtual void Notify() {
for (list<AbstractObserver*>::iterator it = observerList.begin(); it != observerList.end(); it++) {
(*it)->Update();
}
}
private:
list<AbstractObserver*> observerList;
};
void test1() {
AbstractObserver *observerA = new ObserverA;
AbstractObserver *observerB = new ObserverB;
AbstractObserver *observerC = new ObserverC;
AbstractObserverTarget *light = new ObserverTarget;
light->AddObserver(observerA);
light->AddObserver(observerB);
light->AddObserver(observerC);
cout << "A车抛锚了" << endl;
light->DelObserver(observerA);
cout << "绿灯了" << endl;
light->Notify();
}
int main() {
test1();
system("pause");
return 0;
}
最后
以上就是魁梧口红为你收集整理的面向对象设计原则和常用设计模式简单案例面向对象设计原则创建型模型结构型模型行为型模式的全部内容,希望文章能够帮你解决面向对象设计原则和常用设计模式简单案例面向对象设计原则创建型模型结构型模型行为型模式所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复