> 文章列表 > gobject实现简单工厂模式

gobject实现简单工厂模式

gobject实现简单工厂模式

由于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})