目录

前言

1.设计模式(Design pattern)定义

2.为什么要使用设计模式(使用设计模式的意义)

3.设计原则

a、单一职责原则

b、开放封闭原则

c、里氏代换原则

d、迪米特法则

e、依赖倒转原则

f、合成 /聚合复用原则

4.设计模式的分类

1.简单工厂模式

基本简介

实现方式

角色及其职能

工厂角色

抽象产品角色

具体产品角色

优点

缺点

使用场景

实例1

头文件

源文件

主函数

实例2

simpleFactory头文件

simpleFactory源文件

客户端代码


前言

1.设计模式(Design pattern)定义

一套被反复使用,多数人知晓的,代码设计经验的总结。使用设计模式的目的是为了可重用代码,让代码更容易被他人理解,保证代码的可靠性。

通俗的说,就是解决问题的方法,是前辈们归纳总结出来的便于人们理解使用,增加代码的可维护性、可复用性、可扩展性。

2.为什么要使用设计模式(使用设计模式的意义)

众所周知,一款软件是否优秀在它的设计阶段就已经决定了,软件设计的好坏,关系到最终的结果。所以开发经验是必不可少的,而设计模式恰恰是开发经验的传承于总结。

3.设计原则

设计模式的使用根本原因是为了实现代码的复用、增加可维护性。那么怎么才能实现代码复用呢?面向对象有六大原则是必不可少的。

a、单一职责原则

不要存在多于一个导致类更变的原因。通俗的说,即一个类只负责一项职责。

b、开放封闭原则

一个软件实体、类、模块或者函数就应该对扩展开放,就修改关闭。简单的就是说可以增加供能,而不允许修改功能。

c、里氏代换原则

子类型必须能够替换他们的父类型,简单就是说“父债子还”。

d、迪米特法则

一个对象应该对其他对象保持最少的了解。简单来说就是对象之间不依赖与关系来保证运行的。

e、依赖倒转原则

高层模块不应该依赖低层模块,二者都应该依赖于其抽象;抽象不应该依赖细节,细节依赖抽象。简单的说就是依赖接口编程,不要对实现编程。即只要结果不顾过程。

f、合成 /聚合复用原则

合成聚合复用原则,尽量使用合成/聚合,尽量不要使用类继承。

※耦合度:是指一程序中,模块与模块之间信息或参数依赖的程度。 低耦合度:松散耦合

        4.设计模式的分类

总体来说设计模式分为三大类:

创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、建造者模式、原型模式。

结构型模式,共七种:适配器模式、装饰模式​​​​​​​、代理模式、外观模式、桥接模式、组合模式、享元模式。

行为型模式,共十一种:策略模式、模板方法模式、观察者模式、迭代子模式、责任链模式、命令模式、备忘录模式、状态模式、访问者模式、中介者模式、解释器模式。

1.简单工厂模式

基本简介

从设计模式的类型上来说,简单工厂模式是属于创建型模式,又叫做静态工厂方法(Static Factory Method)模式,但不属于23种GOF设计模式之一。简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例。简单工厂模式是工厂模式家族中最简单实用的模式,可以理解为是不同工厂模式的一个特殊实现。

UML图

实现方式

简单工厂模式的实质是由一个工厂类根据传入的参数动态决定应该创建哪个产品类的实例(这些产品类继承自一个父类或接口)

角色及其职能

包括三种角色:工厂角色、抽象产品角色、具体产品角色

工厂角色

简单工厂模式的核心,它负责实现创建所有实例的内部逻辑。工厂类可以被外界直接调用,创建所需的产品对象。

抽象产品角色

简单工厂模式所创建的所有对象的父类,它负责描述所有实例所共有的公共接口。

具体产品角色

是简单工厂模式的创建目标,所有创建的对象都是充当这个角色的某个具体类的实例。

优点

    工厂类是整个模式的关键.包含了必要的逻辑判断,根据外界给定的信息,决定究竟应该创建哪个具体类的对象.通过使用工厂类,外界可以从直接创建具体产品对象的尴尬局面摆脱出来,仅仅需要负责“消费”对象就可以了。而不必管这些对象究竟如何创建及如何组织的.明确了各自的职责和权利,有利于整个软件体系结构的优化。

缺点

由于工厂类集中了所有实例的创建逻辑,违反了高内聚责任分配原则,将全部创建逻辑集中到了一个工厂类中;它所能创建的类只能是事先考虑到的,如果需要添加新的类,则就需要改变工厂类了。

当系统中的具体产品类不断增多时候,可能会出现要求工厂类根据不同条件创建不同实例的需求.这种对条件的判断和对具体产品类型的判断交错在一起,很难避免模块功能的蔓延,对系统的维护和扩展非常不利;

使用场景

工厂类负责创建的对象比较少;客户只知道传入工厂类的参数,对于如何创建对象(逻辑)不关心;由于简单工厂很容易违反高内聚责任分配原则,因此一般只在很简单的情况下应用。

实例1

头文件

#pragma once
#include<iostream>
#include<string>
using namespace std;
/// <summary>
/// 运算类
/// </summary>
class Operation {
public:Operation();Operation(double numA, double numB);double getNumberA() const;void setNumberA(double numA);double getNumberB() const;void setNumberB(double numB);/// <summary>/// 虚函数、运算函数/// </summary>/// <returns>运算后的值</returns>virtual double GetResult();
protected:double _numberA;double _numberB;
};/// <summary>
/// 加
/// </summary>
class OperationAdd:public Operation
{
public:OperationAdd();OperationAdd(double numA, double numB);/// <summary>/// 重写父类的虚函数/// </summary>/// <returns>运算后的值</returns>double GetResult();
};/// <summary>
/// 减
/// </summary>
class OperationSub :public Operation
{
public:OperationSub();OperationSub(double numA, double numB);/// <summary>/// 重写父类的虚函数/// </summary>/// <returns>运算后的值</returns>double GetResult();
};/// <summary>
/// 乘
/// </summary>
class OperationMul :public Operation
{
public:OperationMul();OperationMul(double numA, double numB);/// <summary>/// 重写父类的虚函数/// </summary>/// <returns>运算后的值</returns>double GetResult();
};/// <summary>
/// 除
/// </summary>
class OperationDiv :public Operation
{
public:OperationDiv();OperationDiv(double numA, double numB);/// <summary>/// 重写父类的虚函数/// </summary>/// <returns>运算后的值</returns>double GetResult();
};/// <summary>
/// 乘方
/// </summary>
class OperationM :public Operation
{
public:OperationM();OperationM(double numA, double numB);/// <summary>/// 重写父类的虚函数/// </summary>/// <returns>运算后的值</returns>double GetResult();};/// <summary>
/// 简单工厂模式:定义一个创建对象的接口、让子类自己决定实例化哪个工厂类
/// 简单运算工厂类
/// </summary>
class OperationFactory
{
public:static Operation* createOperate(char operate);
};

源文件

#include "OperationFactory.h"
Operation::Operation()
{this->_numberA = 0;this->_numberB = 0;
}Operation::Operation(double numA, double numB)
{this->_numberA = numA;this->_numberB = numB;
}double Operation::getNumberA() const
{return this->_numberA;
}void Operation::setNumberA(double numA)
{this->_numberA = numA;
}double Operation::getNumberB() const
{return this->_numberB;
}void Operation::setNumberB(double numB)
{this->_numberB = numB;
}double Operation::GetResult()
{double result = 0;return result;
}OperationAdd::OperationAdd() :Operation()
{
}OperationAdd::OperationAdd(double numA, double numB):Operation(numA,numB)
{
}double OperationAdd::GetResult()
{double result = 0;result = _numberA + _numberB;return result;
}OperationSub::OperationSub():Operation()
{
}OperationSub::OperationSub(double numA, double numB):Operation(numA,numB)
{
}double OperationSub::GetResult()
{double result=0;result = _numberA - _numberB;return result;
}OperationMul::OperationMul():Operation()
{
}OperationMul::OperationMul(double numA, double numB):Operation(numA,numB)
{
}double OperationMul::GetResult()
{return _numberA*_numberB;
}OperationDiv::OperationDiv():Operation()
{
}OperationDiv::OperationDiv(double numA, double numB):Operation(numA,numB)
{
}double OperationDiv::GetResult()
{if (_numberB == 0) {throw "被除数不能为0";}return _numberA/_numberB;
}Operation* OperationFactory::createOperate(char operate)
{Operation* oper = nullptr;switch (operate){case '+':oper = new OperationAdd;break;case '-':oper = new OperationSub;break;case '*':oper = new OperationMul;break;case '/':oper = new OperationDiv;break;case '^':oper = new OperationM;default:break;}return oper;
}OperationM::OperationM():Operation()
{
}OperationM::OperationM(double numA, double numB):Operation(numA,numB)
{
}double OperationM::GetResult()
{double res = 1;   for (int i = 0; i < _numberB; i++) {res *= _numberA;}return res;
}

主函数

#include<iostream>
using namespace std;
#include"OperationFactory.h"int main(int argc, char* argv[]) {Operation *oper= OperationFactory::createOperate('^');oper->setNumberA(2);oper->setNumberB(3);double res = oper->GetResult();cout << res << endl;system("pause");return 0;
}

实例2

商场促销---商场收银软件 (基于qt实现)

simpleFactory头文件

/*** @brief 简单工厂实现* @param* @return
*/
#ifndef SIMPLEFACTORY_H
#define SIMPLEFACTORY_H
#include<QString>
/*** @brief 现金收费抽象类、抽象基类* @param* @return
*/
class CashSuper{
public:/*** @brief 现金收取类的纯虚函数,收取现金* @param 原价* @return 当前价
*/virtual double AcceptCash(double money)=0;
};/*** @brief 正常收费子类* @param* @return
*/
class CashNormal:public CashSuper{
public://正常收费,原价返回double AcceptCash(double money) override;
};/*** @brief 打折收费子类* @param* @return
*/
class CashRebate:public CashSuper{
public:CashRebate(double moneyRebate);//打折收费,初始化时输入折扣率double AcceptCash(double money) override;private:double moneyRate=1;
};
/*** @brief 返利收费子类,初始化时输入返利条件和返利值* @param 返利条件moneyCondition 返利值moneyReturn* @return
*/
class CashReturn:public CashSuper{
public:CashReturn(double moneyCondition,double moneyReturn);double AcceptCash(double money) override;
private:double moneyCondition=0.0;double moneyReturn=0.0;
};
/*** @brief 现金收费工厂类* @param* @return
*/
class CashFactory{
public:static CashSuper* CreateCashAccept(int type);
};#endif // SIMPLEFACTORY_H

simpleFactory源文件

#include "simplefactory.h"
double CashNormal::AcceptCash(double money)
{return money;
}
CashRebate::CashRebate(double moneyRebate)
{if(moneyRebate>1||moneyRebate<0){throw "rate error";}this->moneyRate=moneyRebate;
}
double CashRebate::AcceptCash(double money)
{return money*moneyRate;
}
CashReturn::CashReturn(double moneyCondition, double moneyReturn)
{this->moneyCondition=moneyCondition;this->moneyReturn=moneyReturn;
}
double CashReturn::AcceptCash(double money)
{double result=money;if(money>=moneyCondition){result=money-moneyReturn;}return result;
}
CashSuper* CashFactory::CreateCashAccept(int type)
{//type  现金收取工厂CashSuper *cs=nullptr;switch (type) {//根据条件返回相应的对象case 0:cs=new CashNormal();break;case 1:cs=new CashReturn(300,100);break;case 2:cs=new CashRebate(0.8);break;case 3:cs=new CashRebate(0.5);break;case 4:cs=new CashReturn (500,200);break;default:break;}return cs;
}

客户端代码

void Widget::on_btn_ok_clicked()//点击确定槽函数
{double total=0.00;//声明一个double变量total来计算总计double price=ui->line_Price->text().toDouble();//lineEdit获取pricedouble num=ui->line_Num->text().toDouble();//lineEdit获取numtotal=num*price;//获取合计CashSuper* csuper=CashFactory::CreateCashAccept(ui->comboBox->currentIndex());total=csuper->AcceptCash(total);ui->listWidget->addItem("单价:"+ui->line_Price->text()+" 数量:"+ui->line_Num->text()+" "+ui->comboBox->currentText()+" 合计:"+QString::number(total));//添加到啊listWidget中ui->labShowPrice->setText(QString::number(total));//显示到lab中。
}

23种设计模式 -----Day01:简单工厂模式相关推荐

  1. 23种设计模式之简单工厂模式,工厂方法模式,抽象工厂模式详解

    工厂模式详解 1. 简单工厂模式 1.1 需求分析 1.2 使用传统方式实现 1.2.1 类图 1.2.2 代码实现 1.2.2.1 新建pizza抽象类 1.2.2.2 希腊披萨实现类 1.2.2. ...

  2. 23种设计模式之抽象工厂模式(Abstract Factory Pattern)

    前言:大家好,我是小威,24届毕业生,在一家满意的公司实习.本篇文章将23种设计模式中的抽象工厂模式,此篇文章为一天学习一个设计模式系列文章,后面会分享其他模式知识. 如果文章有什么需要改进的地方还请 ...

  3. 23种设计模式之简单工厂

    简单工厂模式描述的是,通过类的继承关系,父类(工厂类)与子类(产品类),调用父类中的方法,实际干活儿的是子类中的方法:封装需求的不确定性,做出通用的编程,下面以常用的计算器为例: 最容易想到的写法是: ...

  4. 23种设计模式之-----简单工厂(静态工厂)模式(SimpleFactory Pattern)

    这里引用 https://www.kailing.pub/PdfReader/web/viewer.html?file=24DesignPattern 讲解设计模式一文中的例子. 这个例子很形象而且通 ...

  5. .NET设计模式(1): 简单工厂模式

    .NET设计模式(1): 简单工厂模式 最近一直在看设计模式,想把自己的学习笔记与大家分享一下,如果能帮助大家的话,我会非常高兴,同时也欢迎大家指出里面的不足.园子里其实关于此类文章已经很多了,如果d ...

  6. 备战面试日记(3.3) - (设计模式.23种设计模式之结构型模式)

    本人本科毕业,21届毕业生,一年工作经验,简历专业技能如下,现根据简历,并根据所学知识复习准备面试. 记录日期:2022.1.9 大部分知识点只做大致介绍,具体内容根据推荐博文链接进行详细复习. 文章 ...

  7. 备战面试日记(3.2) - (设计模式.23种设计模式之创建型模式)

    本人本科毕业,21届毕业生,一年工作经验,简历专业技能如下,现根据简历,并根据所学知识复习准备面试. 记录日期:2022.1.6 大部分知识点只做大致介绍,具体内容根据推荐博文链接进行详细复习. 文章 ...

  8. 备战面试日记(3.4) - (设计模式.23种设计模式之行为型模式)

    本人本科毕业,21届毕业生,一年工作经验,简历专业技能如下,现根据简历,并根据所学知识复习准备面试. 记录日期:2022.1.12 大部分知识点只做大致介绍,具体内容根据推荐博文链接进行详细复习. 文 ...

  9. 23种设计模式的简单介绍

    文章目录 23种设计模式 概要 0.简单工厂设计模式 多方法简单工厂 静态方法简单工厂 创造型 单例模式(**Singleton**) 懒汉模式:(以时间换空间) 饿汉模式 (以空间换时间) 工厂方法 ...

  10. php的类图怎么生成_PHP设计模式之简单工厂模式

    PHP设计模式之简单工厂模式 先从简单工厂入门,不管是面试还是被他人面试,在问到设计模式的时候,大多数人都会提到工厂模式.毫无疑问,工厂相关的几种模式在设计模式中是最出名的也是应用比较广泛的一种模式. ...

最新文章

  1. 【总结】sqli-labs Less(1-35) 小结
  2. P2924 [USACO08DEC]大栅栏Largest Fence
  3. python常用内置函数总结-python常用内置函数
  4. 2高并发服务器:多路IO之poll
  5. 炼数成金hadoop视频干货03
  6. 项目管理学习总结(4)——项目团队,如何展开有效沟通?
  7. 学习笔记1/5,操作系统之操作系统概念
  8. 测试用例管理工具-TestLink
  9. LFW数据集—人脸对齐
  10. 概率论与数理统计---------分布函数
  11. 木兰编程语言,当事人最新回复来了
  12. jquery AJAX清除IE缓存问题
  13. JAVA中Action层, Service层 ,modle层 和 Dao层的功能区分
  14. 系统试运行报告是谁写的_深圳个人信用报告查询系统入口https://ipcrs.pbccrc.org.cn/...
  15. 【笔记】取模运算的用法
  16. 电子调谐器的主要引脚及作用
  17. vue日历,阳历, 阴历,周,年,月,下拉选择,引用element组件,
  18. 只有我一个人对ChatGPT感到蕉绿吗?
  19. 苹果电脑怎么查看服务器信息,苹果电脑上如何查看BT种子文件的详细信息
  20. 词库列阵的作用与使用方法

热门文章

  1. 解决报错:org/springframework/util/backoff/BackOff
  2. SQL Cookbook 系列 - 若干另类目标
  3. NLP实战之textRNN中文文本分类
  4. 经典Java题目:输入一个数字,输出它的大写汉字(阿拉伯数字转汉字)
  5. .Net Core微服务化ABP之六——处理Authentication
  6. 《长安十二时辰》,作为程序员,看完我震惊了!涉及通信、云计算、大数据等!...
  7. AD7606数据转换
  8. linux开机引导界面美化,Ubuntu16.04引导界面美化(burg)
  9. ​DB-Engines 11月数据库排名:PostgreSQL坐稳同期涨幅榜冠军宝座
  10. HDU 5835 Danganronpa