设计模式--1(设计模式基础,设计模式基本原则,设计模式分类)

设计模式基础

模式

  1. 在一定环境中解决某一问题的方案,包括三个基本元素–问题,解决方案和环境。
  2. 大白话:在一定环境下,用固定套路解决问题。

设计模式

是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。使用设计 模式是为了可重用代码、让代码更容易被他人理解、保证代 码可靠性。 毫无疑问,设计模 式于己于他人于系统都是多赢的;设计模式使代码编制真正工程化;
设计模式是软件工程的基石脉络,如同大厦的结构一样。

设计模式分类

GangofFour 的“DesignPatterns:ElementsofResualbelSoftware”书将设计模式归纳为 三大类型,共 23 种。

  1. 创建型模式 : 通常和对象的创建有关,涉及到对象实例化的方式。(共 5 种模式)
  2. 结构型模式: 描述的是如何组合类和对象以获得更大的结构。(共 7 种模式)
  3. 行为型模式: 用来对类或对象怎样交互和怎样分配职责进行描述。(共 11 种模式)
    在这里插入图片描述
    在这里插入图片描述

创建型模式

用来处理对象的创建过程

工厂方法模式(FactoryMethodPattern)

定义一个创建产品对象的工厂接口, 将实际创建工作推迟到子类中。

抽象工厂模式(AbstractFactoryPattern)

提供一个创建一系列相关或者相互依 赖的接口,而无需指定它们具体的类。

建造者模式(BuilderPattern)

将一个复杂的构建与其表示相分离,使得同样的 构建过程可以创建不同的表示。

原型模式(PrototypePattern

用原型实例指定创建对象的种类,并且通过拷贝这些原型创建新的对象。

单例模式(SingletonPattern)

是保证一个类仅有一个实例,并提供一个访问它的全局访问点。

结构型模式

处理类或者对象的组合

代理模式(ProxyPattern)

为其他对象提供一种代理以控制对这个对象的访问

装饰者模式(DecoratorPattern)

给一个对象添加一些额外的职责。就增加功能来 说,此模式比生成子类更为灵活。

适配器模式(AdapterPattern)

将一个类的接口转换成客户希望的另外一个接口。使得 原本由于接口不兼容而不能一起工作的那些类可以一起工作

桥接模式(BridgePattern)

将抽象部分与实际部分分离,使它们都可以独立的变化。

组合模式(CompositePattern)

将对象组合成树形结构以表示“部分–整体”的层次结 构。使得用户对单个对象和组合对象的使用具有一致性

外观模式(FacadePattern)

为子系统中的一组接口提供一个一致的界面,此模式定义 了一个高层接口,这个接口使得这一子系统更加容易使用

享元模式(FlyweightPattern)

以共享的方式高效的支持大量的细粒度的对象。

行为型模式

用来对类或对象怎样交互和怎样分配职责进行描述

模板方法模式(TemplateMethodPattern)

使得子类可以不改变一个算法的结构即可重 定义该算法的某些特定步骤。

命令模式(CommandPattern)

将一个请求封装为一个对象,从而使你可用不同的请 求对客户端进行参数化;对请求排队或记录请求日志,以及支持可撤销的操作

责任链模式(ChainofResponsibilityPattern)

在该模式里,很多对象由每一个对象对其 下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理 此请求,这使得系统可以在不影响客户端的情况下动态地重新组织链和分配责任

策略模式(StrategyPattern)

是准备一组算法,并将每一个算法封装起来,使得它们 可以互换。

中介者模式(MediatorPattern)

定义一个中介对象来封装系列对象之间的交互。终 结者使各个对象不需要显示的相互调用 ,从而使其耦合性松散,而且可以独立的改变他们 之间的交互。

观察者模式(ObserverPattern)

定义对象间的一种一对多的依赖关系,当一个对象的状 态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

备忘录模式(MementoPattern)

是在不破坏封装的前提下,捕获一个对象的内部状态, 并在该对象之外保存这个状态。

访问者模式(VisitorPattern)

就是表示一个作用于某对象结构中的各元素的操作,它使 你可以在不改变各元素的类的前提下定义作用于这些元素的新操作。

状态模式(StatePattern)

对象的行为,依赖于它所处的状态

解释器模式(InterpreterPattern)

描述了如何为简单的语言定义一个语法,如何在 该语言中表示一个句子,以及如何解释这些句子。

迭代器模式(IteratorPattern)

提供了一种方法顺序来访问一个聚合对象中的各个元 素,而又不需要暴露该对象的内部表示。

设计模式基本原则

最终目的:高内聚,低耦合

开放封闭原则 (OCP,OpenForExtension,ClosedForModificationPrinciple)

类的改动是通过增加代码进行的,而不是修改源代码。

#include<iostream>using namespace std;
//开闭原则//写一个抽象类
class AbstractCaculator
{
public:virtual int getResult() = 0;virtual void setOperatorNumber(int a, int b) = 0;};//加法计算器
class PlusCaculator :public AbstractCaculator{
public:virtual void setOperatorNumber(int a, int b){this->mA = a;this->mB = b;}virtual int getResult(){return mA + mB;}
private:int mA;int mB;
};//减法计算器
class MinuteCaculator :public AbstractCaculator{
public:virtual void setOperatorNumber(int a, int b){this->mA = a;this->mB = b;}virtual int getResult(){return mA - mB;}
private:int mA;int mB;
};//乘法计算器
class MultiplyCaculator :public AbstractCaculator{
public:virtual void setOperatorNumber(int a, int b){this->mA = a;this->mB = b;}virtual int getResult(){return mA * mB;}
private:int mA;int mB;
};void test01()
{//父类指针指向基类对象AbstractCaculator * caculator = new PlusCaculator;caculator->setOperatorNumber(10, 20);cout << "ret:" << caculator->getResult() << endl;caculator = new  MultiplyCaculator;caculator->setOperatorNumber(30,20);cout << "ret:" << caculator->getResult() << endl;
}int main(void)
{test01();system("pause");return 0;
}

我们如果想再次增加计算器类型,只用继承基类,重写方法就可以了。

单一职责原则 (SRP,SingleResponsibilityPrinciple)

类的职责要单一,对外只提供一种功能,而引起类变化的原因都应该只有一个。

依赖倒置原则 (DIP,DependenceInversionPrinciple)

依赖于抽象(接口),不要依赖具体的实现(类),也就是针对接口编程。
在这里插入图片描述

#include<iostream>
using namespace std;class BankWorker{
public:void SaveService(){cout << "办理存款业务..." << endl;}void payService(){cout << "办理支付业务.." << endl;}void tranferService(){cout << "办理转账业务..." << endl;}
};void doSaveBussiness(BankWorker *worker){worker->SaveService();
}
void doPayBussiness(BankWorker *worker){worker->payService();
}
void doTransferBussiness(BankWorker *worker){worker->tranferService();
}void test01(){BankWorker *worker = new BankWorker;doSaveBussiness(worker);//办理存款业务doPayBussiness(worker);//办理支付业务doTransferBussiness(worker);//办理转账业务
}int main(void)
{system("pause");return 0;
}

在这里插入图片描述

//银行工作人员
class AbstractWotker{
public:virtual void doBussiness() = 0;};//专门负责办理存款业务的工作人员
class doSaveBankWorker :public AbstractWotker{
public:virtual void doBussiness(){cout << "办理存款业务.." << endl;}
};class PaySaveBankWorker :public AbstractWotker{
public:virtual void doBussiness(){cout << "办理支付业务.." << endl;}
};class TransferSaveBankWorker :public AbstractWotker{
public:virtual void doBussiness(){cout << "办理转账业务.." << endl;}
};//中层业务,依赖于抽象层,bu
void doNewBusiness(AbstractWotker * worker){worker->doBussiness();delete worker;
}void test02()
{doNewBusiness(new TransferSaveBankWorker);doNewBusiness(new doSaveBankWorker);doNewBusiness(new PaySaveBankWorker);
}int main(void)
{//test01();system("pause");return 0;
}

接口隔离原则 (ISP,InterfaceSegegationPrinciple)

不应该强迫客户的程序依赖他们不需要的接口方法。一个接口应该只提供一种对外功能, 不应该把所有操作都封装到一个接口中去。

里氏替换原则 (LSP,LiskovSubstitutionPrinciple)

任何抽象类出现的地方都可以用他的实现类进行替换。实际就是虚拟机制,语言级别实 现面向对象功能。

合成复用原则(CARP,Composite/AggregateReusePrinciple)

优先使用组合而不是继承原则。如果使用继承,会导致父类的任何变换都可能影响到子类的行为。 如果使用对象组合,就降低了这种依赖关系。

#include<iostream>
using namespace std;class AbstractCar{
public:virtual void run() = 0;};class Dazhong :public AbstractCar{
public:virtual void run(){cout << "大众车启动..." << endl;}
};class Tuolaji :public AbstractCar{
public:virtual void run(){cout << "拖拉机启动.." << endl;}
};//针对具体类,不使用继承
#if 0
class Person :public Tuolaji{
public:void Doufeng(){run();}
};class PersonB :public Tuolaji{
public:void Doufeng(){run();}
};
#endif//用组合
class Person{
public:/*~Person(){if (this->car != NULL){delete this->car;}}*/void setCar(AbstractCar *car){this->car = car;}void Doufeng(){this->car->run();if (this->car != NULL){delete this->car;this->car = NULL;}}public:AbstractCar *car;
};void test02(){Person* p = new Person;p->setCar(new Dazhong);p->Doufeng();p->setCar(new Tuolaji);p->Doufeng();delete p;
}//继承和组合优先使用组合
int main()
{test02();system("pause");return 0;
}

迪米特法则(LOD,LawofDemeter)

一个对象应当对其他对象尽可能少的了解,从而降低各个对象之间的耦合,提高系统的 可维护性。例如在一个程序中,各个模块之间相互调用时,通常会提供一个统一的接口来实 现。这样其他模块不需要了解另外一个模块的内部实现细节,这样当一个模块内部的实现发 生改变时,不会影响其他模块的使用。

#include<iostream>
#include<string>
#include<vector>
using namespace std;
//迪米特原则,又叫最小知识原则,不要暴露内部结构,只提供接口class AbstractBuiding
{
public:virtual void sale() = 0;virtual string getQuality() = 0;
};//楼盘A
class BuildingA :public AbstractBuiding
{
public:BuildingA(){mQuity = "高品质";}virtual void sale(){cout << "楼盘A" << mQuity << "被售卖";}virtual string getQuality(){return mQuity;}
public:string mQuity;
};//楼盘B
class BuildingB :public AbstractBuiding
{
public:BuildingB(){mQuity = "低品质";}virtual void sale(){cout << "楼盘B" << mQuity << "被售卖";}virtual string getQuality(){return mQuity;}
public:string mQuity;
};
#if 0
void test01()
{BuildingA * ba = new BuildingA;if (ba->mQuity == "低品质"){ba->sale();}BuildingB *bb = new BuildingB;if (bb->mQuity == "低品质"){bb->sale();}
}
#endif//中介类
class Mediator{
public:Mediator(){AbstractBuiding * building = new BuildingA;vBuilding.push_back(building);building = new BuildingB;vBuilding.push_back(building);}~Mediator(){for (vector<AbstractBuiding*>::iterator it = vBuilding.begin(); it != vBuilding.end(); it++){if (*it != NULL){delete *it;}}}//对外提供接口AbstractBuiding *findMyBuilding(string qulity){for (vector<AbstractBuiding *>::iterator it = vBuilding.begin(); it != vBuilding.end(); it++){if ((*it)->getQuality() == qulity){return *it;}}return NULL;}
public:vector<AbstractBuiding*>vBuilding;
};void test02()
{Mediator *mediator = new Mediator;AbstractBuiding*building = mediator->findMyBuilding("高品质");if (building != NULL){building->sale();}else{cout << "没有符合您条件的楼盘!" << endl;}
}int main(void)
{//test01();test02();system("pause");return 0;
}

就是有个中间商。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/383215.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

设计模式----2(简单工厂模式的概念,简单工厂模式的实现,简单工厂模式的优缺点)

简单工厂模式 简单工厂模式的概念 简单工厂模式属于类的创建型模式,又叫做静态工厂方法模式。通过专门定义一个类来负 责创建其他类的实例&#xff0c;被创建的实例通常都具有共同的父类。 具体分类 工厂&#xff08;Creator&#xff09;角色 简单工厂模式的核心&#xff0…

设计模式---3(工厂方法模式的概念,工厂方法模式的实现,工厂方法模式和简单工厂模式比较)

工厂方法模式 概念 工厂方法模式同样属于类的创建型模式又被称为多态工厂模式 。 工厂方法模式的意义 定义一个创建产品对象的工厂接口&#xff0c;将实际创建工作推迟到子类当中。 核心工厂类不再负责产品的创建&#xff0c;这样核心类成为一个抽象工厂角色&#xff0c;仅…

设计模式---4(抽象工厂模式的概念,产品组和产品等级的概念,抽象工厂模式的实现)

抽象工厂模式 抽象工厂模式的概念 抽象工厂模式是所有形态的工厂模式中最为抽象和最其一般性的。抽象工厂模式可以向 客户端提供一个接口&#xff0c;使得客户端在不必指定产品的具体类型的情况下&#xff0c;能够创建多个产品 族的产品对象。 抽象工厂的角色及其职责 抽象工…

1.c++中初始化列表和构造函数初始化的区别是什么?2.类的成员变量的初始化顺序是按照声明顺序吗?

初始化列表和构造函数初始化的区别是什么&#xff1f; 初始化和赋值对内置类型的成员没有太大的区别&#xff0c;在成员初始化列表和构造函数体内进行&#xff0c;在性能和结果上都是一样的。只有一些需要注意的事项 初始化列表一般情况如下&#xff1a; Date(int year, int …

设计模式---5(建造者模式的概念及其实现,建造者模式的角色与职责,建造者模式和工厂模式的区别)

建造者模式 建造者模式的概念 Builder 模式也叫建造者模式或者生成器模式&#xff0c;是由 GoF 提出的 23 种设计模式中的一种。 Builder 模式是一种对象创建型模式之一&#xff0c;用来隐藏复合对象的创建过程&#xff0c;它把复合对象的 创建过程加以抽象&#xff0c;通过子…

system阻塞SIGCHLD信号原因

system阻塞SIGCHLD信号原因 标签&#xff1a; c 2014-11-08 11:58 198人阅读 评论(0) 收藏 举报 分类&#xff1a; linux编程&#xff08;1&#xff09; 代码1&#xff1a;APUE10.18节的system函数源代码 int system(const char *cmdstring) /* with appropriate signal ha…

设计模式6---(单例模式的概念及其实现(懒汉式和饿汉式),线程安全)

单例模式 单例模式的概念 单例模式是一种对象创建型模式&#xff0c;使用单例模式&#xff0c;可以保证为一个类只生成唯一的实例对象。也就是说&#xff0c;在整个程序空间中&#xff0c;该类只存在一个实例对象。 GoF 对单例模式的定义是&#xff1a;保证一个类、只有一个实…

套接字编程---2(TCP套接字编程的流程,TCP套接字编程中的接口函数,TCP套接字的实现,TCP套接字出现的问题,TCP套接字多进程版本,TCP套接字多线程版本)

TCP模型创建流程图 TCP套接字编程中的接口 socket 函数 #include <sys/types.h> /* See NOTES */ #include <sys/socket.h> int socket(int domain, int type, int protocol); domain: AF_INET 这是大多数用来产生socket的协议&#xff0c;使用TCP或UDP来传输&…

Linux中netstat工具详解

简介 Netstat 命令用于显示各种网络相关信息&#xff0c;如网络连接&#xff0c;路由表&#xff0c;接口状态 (Interface Statistics)&#xff0c;masquerade 连接&#xff0c;多播成员 (Multicast Memberships) 等等。 常见参数 -a (all)显示所有选项&#xff0c;默认不显示…

网络基础 2-1(应用层,HTTP三点注意,HTTP协议格式, 最简单的HTTP服务器)

应用层 应用层 负责应用程序之间的数据沟通-----协议都是用户自己定的 自定制协议&#xff1a; 结构化数据传输 序列化&#xff1a; 将数据对象以指定的协议&#xff08;数据格式&#xff09;进行可用于持久化存储或者数据传输时的数据组织 例如在分布式的系统中&#xf…

网络基础2-2(传输层,端口,详谈UDP)

传输层 负责数据能够从发送端传输接收端. 端口号 端口号(Port)标识了一个主机上进行通信的不同的应用程序;在TCP/IP协议中, 用 “源IP”, “源端口号”, “目的IP”, “目的端口号”, “协议号” 这样一个五元组来标识一个通信(可以通过 netstat -n查看);一个端口只能被一个…

网络基础2-3(TCP协议,三次握手,四次挥手,TIME_WAIT状态的作用,TCP如何保证可靠传输,TCP连接中状态转化,滑动窗口,流量控制,快速重传,拥塞窗口,延迟应答,捎带应答,粘包问题)

TCP协议 TCP协议概念 TCP全称为 “传输控制协议(Transmission Control Protocol”). 人如其名, 要对数据的传输进行一个详细的控制 TCP协议格式 1. 源/目的端口号: 表示数据是从哪个进程来, 到哪个进程去; 2. 32位序号/32位确认号: 后面详细讲; 3. 4位TCP报头长度: 表示该…

字符串题目 1 --------判断两个字符串是否为旋转词

题目描述 如果一个字符串为str&#xff0c;把字符串的前面任意部分挪到后面形成的字符串交str的旋转词。比如str“12345”&#xff0c;str的旋转串有“12345”、“45123”等等。给定两个字符串&#xff0c;判断是否为旋转词。 输入描述: 输出包含三行&#xff0c;第一个两个…

字符串题目---2判断两个字符串是否为变形词

题目描述 给定两个字符串str1和str2&#xff0c;如果str1和str2中出现的字符种类出现的一样且每种字符出现的次数也一样&#xff0c;那么str1和str2互为变形词。请判断str1和str2是否为变形词 输入描述: 输入包括3行&#xff0c;第一行包含两个整数n&#xff0c;m(1 \leq n,…

设计模式7----代理模式

代理模式 概念 Proxy 模式又叫做代理模式&#xff0c;是结构型的设计模式之一&#xff0c;它可以为其他对象提供一 种代理&#xff08;Proxy&#xff09;以控制对这个对象的访问。 所谓代理&#xff0c;是指具有与代理元&#xff08;被代理的对象&#xff09;具有相同的接口的…

网络基础3-1(细谈IP协议头, 网络层,子网划分,路由选择,数据链路层,以太网帧格式,MAC地址,再谈ARP协议)

IP协议 IP协议头格式 4位版本号(version): 指定IP协议的版本, 对于IPv4来说, 就是44位头部长度(header length): IP头部的长度是多少个。32bit, 也就是 length * 4 的字节数. 4bit表示大 的数字是15, 因此IP头部大长度是60字节8位服务类型(Type Of Service): 3位优先权字段(已…

网络中典型协议--(DNS,输入url后, 发生的事情. ,ICMP,NAT)

DNS&#xff08;Domain Name System&#xff09; DNS是一整套从域名映射到IP的系统 域名服务器发展背景 TCP/IP中使用IP地址和端口号来确定网络上的一台主机的一个程序. 但是IP地址不方便记忆. 于是人们发明了一种叫主机名的东西, 是一个字符串, 并且使用hosts文件来描述主机…

高级IO--1 ---(五种典型IO,阻塞IO,非阻塞IO,信号驱动IO,异步IO, IO多路转接)

高级IO&#xff1a; 五种典型IO&#xff1a; 阻塞IO/非阻塞IO/信号驱动IO/异步IO/IO多路转接 IO多路转接模型&#xff1a;select/poll/epoll 五种典型IO 阻塞IO IO操作的流程&#xff1a;等待IO操作条件具备&#xff0c;然后进行数据拷贝 为了完成IO操作发起调用&#xff…

IO多路转接模型----(select的模型,select的优缺点,poll的模型,poll的优缺点)

IO多路转接模型&#xff1a;select/poll/epoll 对大量描述符进行事件监控(可读/可写/异常) select模型 用户定义描述符的事件监控集合 fd_set&#xff08;这是一个位图&#xff0c;用于存储要监控的描述符&#xff09;; 用户将需要监控的描述符添加到集合中&#xff0c;这个描…

IO多路转接模型-----epoll

epoll&#xff1a; Linux下性能最高的多路转接模型 epoll 有3个相关的系统调用. epoll_create 功能&#xff1a;创建epoll&#xff0c;在内核中创建eventpoll结构体&#xff0c;size决定了epoll最多监控多少个描述符&#xff0c;在Linux2.6.8之后被忽略&#xff0c;但是必须…