大话设计模式C语言之抽象工厂
大话设计模式C语言之抽象工厂抽象工厂模式
抽象工厂 (AbstractFactory) 模式是一种创建型设计模式, 它能创建一系列相关的对象, 而无需指定其具体类。
案例代码抽象产品接口
抽象产品(Abstract Product)为构成系列产品的一组不同但相关的产品声明接口。
抽象button接口 button.h12345678910#ifndef BUTTON_H#define BUTTON_Htypedef struct Button Button;void button_draw(Button *self);void button_destroy(Button *self);#endif
抽象checkbox接口 checkbox.h12345678910#ifndef CHECKBOX_H#define CHECKBOX_Htypedef struct Checkbox Checkbox;void checkbox_draw(Checkbox *self);void checkbox_destroy(Checkbox *self);#endif
具体产品
具体产品 ...
大话设计模式C语言之观察者模式
大话设计模式C语言之观察者模式观察者模式
观察者模式 (ObserverPattern) 是一种行为设计模式,允许你定义一种订阅机制,可在对象事件发生时通知多个 “观察” 该对象的其他对象。
观察者模式就像是MQTT的Pub/Sub机制,两者道相同,但观察者模式属于一种软件设计模式最重要针对代码层次,而发布订阅机制是一种系统架构模式,针对的是系统架构层次。但本质思想是相同的。
案例代码观察者接口 observer.h
接口声明了通知接口。在绝大多数情况下,该接口仅包含一个update更新方法。该方法可以拥有多个参数,使发布者能在更新时传递事件的详细信息。
1234567891011121314151617#ifndef OBSERVER_H#define OBSERVER_Htypedef struct Observer Observer;/* 观察者回调接口 */typedef void (*ObserverUpdateFn)(Observer *self, const void *event);/* 创建 / 销毁 */Observer *o ...
大话设计模式C语言之建造模式
大话设计模式C语言之建造模式建造模式
建造模式 (BuilderPattern) 是一种创建型设计模式,使你能够分步骤创建复杂对象。该模式允许你使用相同的创建代码生成不同类型和形式的对象。
下面举了一个Director + Builder模式构造不同的 ServerConfig 配置实例,使用director的三个预设方法(build_http / build_https / build_high_perf)并传入同一个builder和不同的host字符串来构建三种配置,然后把各实例的字段打印出来并销毁的例子。
案例代码产品接口 server_config.h
产品 (Products) 是最终生成的对象。 由不同生成器构造的产品无需属于同一类层次结构或接口。
123456789101112131415161718#ifndef SERVER_CONFIG_H#define SERVER_CONFIG_Htypedef struct ServerConfig ServerConfig;/* 只读访问接口 */const char *se ...
大话设计模式C语言之外观模式
大话设计模式C语言之外观模式外观模式
外观 (Facade) 提供了一种访问特定子系统功能的便捷方式,其了解如何重定向客户端请求,知晓如何操作一切活动部件。
案例代码外观接口 facade.h
抽象类(AbstractClass)会声明作为算法步骤的方法,以及依次调用它们的实际模板方法。算法步骤可以被声明为抽象类型,也可以提供一些默认实现。
外观模式提供一个统一的高层接口使子系统更容易使用降低依赖复杂性。通过initialize_system、shutdown_system 和 read_data 这几个函数,客户端可以控制系统的行为,而不需要关心具体的子系统实现。每个函数的实现实际上都在内部调用了多个低级别的操作(例如硬件初始化、传感器校准等)。
123456789101112131415#ifndef FACADE_H#define FACADE_Htypedef struct Facade Facade;// 公共接口Facade *create_facade();void destroy_facade(Facade *facade);void in ...
大话设计模式C语言之模板模式
大话设计模式C语言之模板模式模板模式
模板方法 (Template Method) 模式:在基类中定义算法骨架,将某些步骤延迟到子类实现,使子类在不改变算法结构的情况下重新定义算法的某些步骤。
案例代码 这里举了数据处理模板的例子,在基类中定义了数据处理模板,将数据处理的具体步骤延迟到文件数据处理与网络数据处理两个子类实现,使子类在不改变数据处理模板的情况下重新定义数据处理的具体步骤。
案例代码抽象基类 data_processor.h
抽象类(AbstractClass)会声明作为算法步骤的方法,以及依次调用它们的实际模板方法。算法步骤可以被声明为抽象类型,也可以提供一些默认实现。
模型模式通过结构体内的函数指针定义了类中必须实现和可选实现的抽象方法步骤,以及声明了通用的算法模板。
12345678910111213141516171819202122232425262728#ifndef DATA_PROCESSOR_H#define DATA_PROCESSOR_Htypedef struct DataProcessor Dat ...
关于工厂方法的补充
产品接口 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 ...

