关于工厂方法的补充
产品接口 logger.h 在产品接口中将方法封装到模块中,外面看不到Logger的具体细节。
1234567891011#ifndef LOGGER_H#define LOGGER_Htypedef struct Logger Logger;void logger_log(Logger *logger, const char *message);void logger_destroy(Logger *logger);#endif //LOGGER_H
产品中间层 logger_internal.h 内部对象模型,Logger的真实定义在这里,这个文件不对外提供。
123456789101112131415161718#ifndef LOGGER_INTERNAL_H#define LOGGER_INTERNAL_H#include "logger.h"/* 内部虚函数表 */typedef struct LoggerVTable { void (*log)(Logger *, const char *) ...
大话设计模式C语言之原型模式
大话设计模式C语言之原型模式原型模式
原型(Prototype)模式是一种创建型设计模式,使你能够复制已有对象,而又无需使代码依赖它们所属的类。
案例代码 这里会举了两个简单例子来帮助理解原型模式,第一个例子帮助我们理解原型模式的基本结构,具体原型如何深拷贝实现clone接口来实现原型模式的,以及在符合开闭原则下通过函数指针的多态性对新原型的拓展。第二个例子主要是带我们了解原型注册表这一概念,注册表提供了一种访问常用原型的简单方法,其中存储了一系列可供随时复制的预生成对象,我们可以提供过注册表集中管理对象模板,这样我们就可以根据字符串、配置、网络消息等方式动态创建对象。
案例代码一原型接口 prototype.h
原型 (Prototype)接口将对克隆方法进行声明。在绝大多数情况下,其中只会有一个名为 clone克隆的方法。
原型模式需要注意的是在实现克隆接口的时候要注意浅拷贝问题,这里使用结构体指针作为参数,返回值也是结构体指针,这样就可以实现深拷贝。
12345678910111213#ifndef PROTOTYPE_H#def ...
大话设计模式C语言之工厂方法
大话设计模式C语言之工厂方法工厂方法
工厂方法(Factory Method)模式是一种创建型设计模式,定义一个用于创建对象的接口,让子类决定实例化哪一个类。工厂方法使一个类的实例化延迟到其子类。
第一篇学习的简单工厂模式虽然简单但缺点也很明显,当需要新增产品时就需要修改工厂类在switch中增加新的分支,这违背了开闭原则。工厂方法模式则解决了这个问题,将工厂类抽象出来,当需要新增产品时,只需要新增一个工厂类即可,不需要修改原有的工厂类。但是具体应用时要选用什么简单工厂或是工厂方法还是取决于实际情况,比如产品类型固定(或极少变化)的场合且创建逻辑简单的小型项目,选择使用简单工厂即可,不用为了所谓的优雅而生搬硬套某种模式,合适的才是最好的。
案例代码 这里与原书不同举了一个简单日志系统的例子,LoggerFactory包含通用的Logger接口,后通过console_logger_factory和FileLoggerFactory实现具体两个日志产品实现从控制台或从文件输出日志的功能,如果要新增其他Logger只需要增加其他Logger类的 ...
大话设计模式C语言之代理模式
大话设计模式C语言之代理模式代理模式
代理模式是一种结构型设计模式, 让你能够提供对象的替代品或其占位符。 代理控制着对于原对象的访问, 并允许在将请求提交给对象前后进行一些处理。
代理模式和上篇提到的同为结构型设计模式的装饰模式很像,尤其是用C实现结构几乎一致,但语义完全不同,这也是 C 里最容易被滥用的地方。为了阅读下面具体例子时不会混淆,这里先说下两者的本质区别,就是两者的核心目的不同:
上篇学习的装饰模式主要是为了给对象增加职责。在不改变接口的前提下叠加功能。
而代理模式主要是为了控制对对象的访问,决定能不能/何时/是否调用真实对象,下面结合具体例子很容易就可以理解。
案例代码 这里与原书不同举了一个简单的下载的例子,以便更好的体现代理可以控制对真实对象的访问,结合书中例子可以更好理解代理模式。
服务接口 download_service.h
服务接口(Service Interface)声明了服务接口。代理必须遵循该接口才能伪装成服务对象。
该类定义了真实对象类和代理类的公用接口,这样就可以在任何使用真实对象的地方使用代 ...
大话设计模式C语言之装饰模式
大话设计模式C语言之装饰模式装饰模式 装饰模式可以动态地给给对象添加额外的功能,而不改变其原有的结构或接口。所以目的上装饰器模式属于结构型模式,这类模式介绍如何将对象和类组装成较大的结构,并同时保持结构的灵活和高效。
案例代码 这里与原书不同举了一个简单的咖啡点单例子,点咖啡时可以选择加牛奶、加糖、全加或者全不加等,这里就是通过装饰模式实现动态地给咖啡添加职责,结合书中例子可以更好理解装饰模式。
部件接口 component.h
部件(Component)声明封装器和被封装对象的公用接口。
Component是定义一个对象接口,可以给这些对象动态地添加职责。在C中也就是结构体加函数指针的形式。这里定义了一个咖啡组件,具有显示价格,描述自己和销毁三个方法。
12345678910111213#ifndef COMPONENT_H#define COMPONENT_Htypedef struct Coffee Coffee;struct Coffee { double (*cost)(Coffee *se ...
大话设计模式C语言之策略模式
大话设计模式C语言之策略模式策略模式 根据上篇提到的分类,策略模式(Strategy Pattern)属于对象行为模式,它通过对算法进行封装,把使用算法的责任和算法的实现分割开来,并委派给不同的对象对这些算法进行管理。策略模式定义了一系列算法,并将每一个算法封装起来,使它们可以互相替换,且算法的变化不会影响到使用算法的客户。
案例代码策略接口 payment_strategy.h
策略模式建议找出负责用许多不同方式完成特定任务的类,然后将其中的算法抽取到一组被称为策略的独立类中。
根据大话设计模式书中举的例子,商场搞活动,有打折、满减、返利等不同策略,都可以抽象为付款行为中的计算折扣动作于是付款策略接口这里需要定义一个计算折扣的算法,最后通过简单工厂来在创建时动态注入不同的算法。
1234567891011#ifndef PAYMENT_STRATEGY_H#define PAYMENT_STRATEGY_H/* 策略接口 */typedef struct PaymentStrategy{ double (*cal ...
大话设计模式C语言之简单工厂
大话设计模式C语言之简单工厂关于设计模式是什么 设计模式简单来说就是软件开发人员通过在软件开发过程中对常见问题的解决方案总结出来的组织代码方式的抽象。
做什么 设计模式目的就是为了是实现代码设计的高内聚,低耦合思想,实现可复用,可维护,可扩展,灵活性好,易于理解,易于协作,易于测试等特点。
怎么用 大话设计模式这本书较好的总结了23种设计模式的具体使用方法,但原书例子是C#编写的,这里一边重读下这本书一边用C语言实现一遍,加深理解。
简单工厂模式 简单工厂模式主要是解决对象的创建问题,将对象的创建过程封装在一个工厂类中,通过调用工厂类的方法来创建对象,从而实现对象创建的解耦,并可以根据提供不同参数创建不同对象。
案例代码简单工厂接口 simplefactory.h 关于接口的定义有两种方法,第一种是行为在对象中,另一种是行为在模块中,这里采用的是将行为放在模块中的方法,因为这样可以真正做到不暴露结构体,更好的封装模块的功能。但是在需要运行期多态的情况下,像后面马上要介绍的策略、 ...
几种常用按键驱动
几种常用按键驱动前言 几种单片机常用的按键驱动模块,小巧简单易用方便拓展,实用按键业务逻辑轮子。
STM32使用DWT实现微秒延时
STM32使用DWT实现微秒延时前言 在使用Cortex-M内核单片机开发驱动时总是需要延时函数做超时判断,这时想实现微秒级延时,不想让CPU干等时间,又不想浪费硬件定时器资源,这时候可以使用DWT(Data Watchpoint and Trace )数据观察点与跟踪组件来实现延时功能。
DWT数据观察点与跟踪组件介绍 DWT挂载在AHB私有外设总线上,是一个处理数据观察点功能的模块。通过 DWT,可以设置数据观察点。当一个数据地址或数据的值匹配了观察点时,就说产生了一次匹配命中事件。匹配命中事件可以用于产生一个观察点事件,后者能激活调试器以产生数据跟踪信息,或者让 ETM 联动以跟踪在哪条指令上发生了匹配命中事件。作为调试功能这里就不过多展开了,可以去查看Cortex-M3 权威指南中内容,下面讲解以下DWT有关的寄存器。
相关的DWT寄存器 要实现延时的功能,总共涉及到三个寄存器:DEMCR、DWT_CTRL、DWT_CYCCNT,分别用于开启DWT功能、开启CYCCNT及获得系统时钟计数值。
DEM_CR寄存器 ...
计算机网络体系结构(五)
运输层 (network layer)




