gobject实现简单工厂模式

news/2024/11/19 12:23:10/

由于C语言的特点,这里我们无需创建静态工厂类,直接调用make_product()函数就行。

main.c:

#include "abs_product.h"
#include "con_productA.h"
#include "con_productB.h"
#include "con_factory.h"int
main (void)
{AbsProduct *pro;pro = make_product ("ConProductA");abs_product_print (pro);pro = make_product ("ConProductB");abs_product_print (pro);g_object_unref (pro);
}

输出结果为:

called print() from ConProductA
called print() from ConProductB

抽象产品类AbsProduct

abs_product.h:

#ifndef ABS_PRODUCT_H
#define ABS_PRODUCT_H#include <glib-object.h>#define ABS_TYPE_PRODUCT    (abs_product_get_type())
G_DECLARE_DERIVABLE_TYPE (AbsProduct, abs_product, ABS, PRODUCT, GObject)struct _AbsProductClass {GObjectClass  base_class;void (*print) (AbsProduct *self);
};void
abs_product_print (AbsProduct *self);#endif // ABS_PRODUCT_H

abs_product.c:

#include "abs_product.h"G_DEFINE_ABSTRACT_TYPE (AbsProduct, abs_product, G_TYPE_OBJECT)static void
abs_product_class_init (AbsProductClass *class_)
{class_->print = NULL;
}static void
abs_product_init (AbsProduct *instance)
{ }void
abs_product_print (AbsProduct *self)
{g_return_if_fail (ABS_IS_PRODUCT (self));AbsProductClass *class_ = ABS_PRODUCT_GET_CLASS (self);if (class_->print == NULL) {g_print ("纯虚函数print()未被覆盖\n");abort();}class_->print (self);
}

具体产品类ConProductA

con_productA.h:

#ifndef CON_PRODUCTA_H
#define CON_PRODUCTA_H#include "abs_product.h"#define CON_TYPE_PRODUCTA   (con_productA_get_type())
G_DECLARE_FINAL_TYPE (ConProductA, con_productA, CON, PRODUCTA, AbsProduct)ConProductA *
con_productA_new();#endif // CON_PRODUCTA_H

con_productA.c:

#include "con_productA.h"struct _ConProductA {AbsProduct base_class;
};G_DEFINE_TYPE (ConProductA, con_productA, ABS_TYPE_PRODUCT)static void
override_print (AbsProduct *self)
{if (!CON_IS_PRODUCTA (self)) {g_print ("con_productA_print(): 不兼容的类型!");abort();}g_print ("called print() from ConProductA\n");
}static void
con_productA_class_init (ConProductAClass *class_)
{AbsProductClass *parent_class = ABS_PRODUCT_CLASS (class_);parent_class->print = override_print;
}static void
con_productA_init (ConProductA *instance)
{ }ConProductA *
con_productA_new()
{return g_object_new (CON_TYPE_PRODUCTA, NULL);
}

具体产品类ConProductB

con_productB.h:

#ifndef CON_PRODUCTB_H
#define CON_PRODUCTB_H#include "abs_product.h"#define CON_TYPE_PRODUCTB   (con_productB_get_type())
G_DECLARE_FINAL_TYPE (ConProductB, con_productB, CON, PRODUCTB, AbsProduct)ConProductB *
con_productB_new();#endif // CON_PRODUCTB_H

con_product.c:

#include "con_productB.h"struct _ConProductB {AbsProduct base_class;
};G_DEFINE_TYPE (ConProductB, con_productB, ABS_TYPE_PRODUCT)static void
overide_print (AbsProduct *self)
{if (!CON_IS_PRODUCTB (self)) {g_print ("con_productB_print(): 不兼容的类型\n");abort();}g_print ("called print() from ConProductB\n");
}static void
con_productB_class_init (ConProductBClass *class_)
{AbsProductClass *parent_class = ABS_PRODUCT_CLASS (class_);parent_class->print = overide_print;
}static void
con_productB_init (ConProductB *instance)
{ }ConProductB *
con_productB_new()
{return g_object_new (CON_TYPE_PRODUCTB, NULL);
}

具体工厂类ConFactory

con_factory.h:

#ifndef CON_FACTORY_H
#define CON_FACTORY_H#include <glib-object.h>
#include "abs_product.h"#define CON_TYPE_FACTORY    (con_factory_get_type())
G_DECLARE_FINAL_TYPE (ConFactory, con_factory, CON, FACTORY, GObject)AbsProduct *
make_product (const char *type);#endif // CON_FACTORY_H

con_factory.c:

#include "con_factory.h"
#include "con_productA.h"
#include "con_productB.h"#include <string.h>struct _ConFactory {GObject base_class;
};G_DEFINE_TYPE (ConFactory, con_factory, G_TYPE_OBJECT)static void
con_factory_class_init (ConFactoryClass *class_)
{ }static void
con_factory_init (ConFactory *instance)
{ }AbsProduct *
make_product (const char *type)
{AbsProduct *ret;if (strcmp (type, "ConProductA") == 0)ret = ABS_PRODUCT (con_productA_new());else if (strcmp (type, "ConProductB") == 0)ret = ABS_PRODUCT (con_productB_new());else {g_print ("没有该产品类型!\n");abort();}return ret;
}

CMakeLists.txt:

cmake_minimum_required(VERSION 3.1)
project(demo)set(EXE main)aux_source_directory(. SRC)add_executable(${EXE} ${SRC})add_compile_options(${GLIB_CFLAGS_OTHER})find_package(PkgConfig REQUIRED)
pkg_check_modules(GLIB REQUIRED gobject-2.0)target_include_directories(${EXE} PUBLIC ${GLIB_INCLUDE_DIRS})
target_link_libraries(${EXE} PUBLIC ${GLIB_LIBRARIES})

http://www.ppmy.cn/news/51007.html

相关文章

JSP企业电子投票系统(源代码+论文+开题报告+文献综述)

J2EE已经成为开发商创建电子商务应用的事实标准。正是认识到J2EE平台作为一种可扩展的、全功能的平台&#xff0c;可以将关键的企业应用扩展到任何Web浏览器上并可适合多种不同的Internet数据流、可连接到几乎任何一种传统数据库和解决方案、使企业经理根据多家企业所提供的产品…

【数据库】数据库的基础知识

目录 前言 1、 查看数据库 1.1、查看所有数据库&#xff08;show databases;&#xff09; 1.2、创建数据库之后&#xff0c;查看创建的数据库的基本信息。 2、 创建数据库 2.1、直接创建数据库&#xff08;create database [数据库名];&#xff09; 2.2、创建数据库的时…

【正点原子STM32精英V2开发板体验】体验LVGL的SD NAND文件系统

目的 验证基于SD NAND卡在正点原子STM32精英V2开发板上的兼容效果 实验材料 正点原子STM32精英V2开发板 TF 卡一片 SD NAND卡一片 实验步骤 1、打开例程【正点原子】精英STM32F103开发板 V2-资料盘(A盘)\4&#xff0c;程序源码\3&#xff0c;扩展例程\4&#xff0c;LVGL…

[Golang] 设计模式以及单例设计模式实例实现

&#x1f61a;一个不甘平凡的普通人&#xff0c;致力于为Golang社区和算法学习做出贡献&#xff0c;期待您的关注和认可&#xff0c;陪您一起学习打卡&#xff01;&#xff01;&#xff01;&#x1f618;&#x1f618;&#x1f618; &#x1f917;专栏&#xff1a;算法学习 &am…

vs2010 MSBuild Example

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言先加入相关的头文件和库文件。 [可以参考](http://msdn.microsoft.com/en-us/library/7szfhaft.aspx) 一、一级标题二级标题三级标题四级标题五级标题六级标题 …

P1030 [NOIP2001 普及组] 求先序排列

题目描述 给出一棵二叉树的中序与后序排列。求出它的先序排列。&#xff08;约定树结点用不同的大写字母表示&#xff0c;且二叉树的节点个数 ≤8≤8&#xff09;。 输入格式 共两行&#xff0c;均为大写字母组成的字符串&#xff0c;表示一棵二叉树的中序与后序排列。 输出…

Android之 Bitmap使用

一&#xff0c;简介 1.1 Bitmap是一种图片在内存中的表现形式&#xff0c;不管是png&#xff0c;还是jpg最终都是以bitmap的形式显示到控件上面。 Bitmap是一种位图&#xff0c;位图​是点阵图像​或栅格图像&#xff0c;是由称作像素&#xff08;图片元素&#xff09;的单个…

从初识RabbitMQ到安装了解

一、同步和异步通讯 微服务间通讯有同步和异步两种方式&#xff1a; 同步通讯&#xff1a;就像打电话&#xff0c;需要实时响应。 异步通讯&#xff1a;就像发邮件&#xff0c;不需要马上回复。 两种方式各有优劣&#xff0c;打电话可以立即得到响应&#xff0c;但是你却不…