Factory 模式:c语言实现和使用

Factory 模式

主要为了提高内聚(Cohesion)和松耦合(Coupling性,同时为了防止一些蹩脚实现提供的设计模式。

原理: 网上太多了。

使用原因 (转载) :

在面向对象系统设计中经常可以遇到以下的两类问题:

1)为了提高内聚(Cohesi on)和松耦合(Coupling),我们经常会抽象出一些类的公共

接口以形成抽象基类或者接口。这样我们可以通过声明一个指向基类的指针来指向实际的子

类实现,达到了多态的目的。这里很容易出现的一个问题多的子类继承自抽象基类,我们不得不在每次要用到子类的地方就编写诸如ne w  ×××的代码。这里带来两个问题 )客户程序员必须知道实际子类的名称(当系统复杂后,命名将是一个很不好处理的问题,为了处理可能的名字冲突,有的命名可能并不是具有很好的可读性和可记忆性,就姑且不论不同程序员千奇百怪的个人偏好了。),

   2)程序的扩展性和维护变得越来越困难

2)还有一种情况就是在父类中并不知道具体要实例化哪一个具体的子类。这里的意思

为:假设我们在类中要使用到类是一个抽象父类,在中并不知道具体要实例化那一个的子类,但是在类的子类中是可以知道的。在中我们没有办法直接使用类似于new  ×××的语句,因为根本就不知道×××是什么。 

  以上两个问题也就引出了Factory模式的两个最重要的功能: 

  1)定义创建对象的接口,封装了对象的创建; 

 2)使得具体化类的工作延迟到了子类中。

上面文字转载

网上c++ 代码 有点抽象, 有时候看不出他的好处,这里直接写一个真实实例的源码:

linux 应用层加锁其中有两种方式pthread_spinlcok_t pthread_mutex_t;

头文件 lock.h

#ifndef __LOCK_H__

#define __LOCK_H__

typedef void* lock_t;

typedef enum

{

   LOCK_PTSPIN,

   LOCK_PTMUTEX,

   LOCK_BUTTON

}lock_type;

typedef struct lock_ops {

    lock_t      (*alloc)(void);

    int         (*acquire)(lock_t l);

    int         (*release)(lock_t l);

    void        (*free)(lock_t l);

} lock_ops;

lock_ops *lock_ops_create(lock_type locktype);

void        lock_free(lock_t l);

int         lock_acquire(lock_t l);

int         lock_release(lock_t l);

lock_t      lock_alloc(void);

#endif /* __LOCK_H__ */

Lock.c 

#include "lcok.h"

extern lock_ops spin_ops;

extern lock_ops ptspin_ops;

#ifdef LOCK_PTTHREAD_MUTEX

#define OPS spin_ops

#elif defined(LOCK_PTTHREAD_PSIN)

#define OPS ptmutex_ops

#else

#error No lock type defined

#endif

lock_t lock_alloc (void)

{

    lock_t   mr;

    mr = OPS.alloc();

    return mr;

}

int lock_acquire (lock_t lock)

{

    if (NULL == lock)

    {

        return -1;

    }

    return OPS.acquire(lock);

}

int lock_release (lock_t lock)

{

    if (NULL == lock)

    {

        return -1;

    }

    return OPS.release(lock);

}

void lock_free (lock_t lock)

{

    if (NULL == lock)

    {

        return;

    }

    OPS.free(lock);

}

lock_ops *lock_ops_create(lock_type locktype)

{

    switch(locktype)

    {

        case LOCK_PTSPIN: 

            return &spin_ops;

        case LOCK_PTMUTEX

            return ptmutex_ops;

        default:

            return NULL;

    }

    return NULL;

}

Pthread_mutex_lock.c

#include <pthread.h>

#include "lock.h"

static lock_t ptmutex_alloc(void)

{

    pthread_mutex_t *m;

    int             err;

    m = malloc(sizeof(pthread_mutex_t));

    if (NULL == m)

    {

        return NULL;

    }

    err = pthread_mutex_init(m, NULL);

    if (err < 0)

    {

        free(m);

        m = NULL;

    }

    return m;

}

static int ptmutex_acquire(lock_t l)

{

    int err;

    err = pthread_mutex_lock(l);

    if (err < 0);

    {

        return -1;

    }

    return 0;

}

static int ptmutex_release(lock_t l)

{

    int err;

    err = pthread_mutex_unlock(l);

    if (err < 0);

    {

        return -1;

    }

    return 0;

}

static void ptmutex_free(lock_t l)

{

    pthread_mutex_destroy(l);

    free(l);

}

lock_ops ptmutex_ops = {

    .alloc = ptmutex_alloc,

    .acquire = ptmutex_acquire,

    .release = ptmutex_release,

    .free = ptmutex_free,

};

Pthread_spinlock.c

#include <pthread.h>

#include "lock.h"

static lock_t ptspin_alloc(void)

{

    pthread_spinlock_t *m;

    int             err;

    m = malloc(sizeof(pthread_spinlock_t ));

    if (NULL == m)

    {

        return NULL;

    }

    err = pthread_spin_init(m, 0);

    if (err < 0)

    {

        free(m);

        m = NULL;

    }

    return m;

}

static int ptspin_acquire(lock_t l)

{

    int err;

    err = pthread_spin_lock(l);

    if (err < 0);

    {

        return -1;

    }

    return 0;

}

static int ptspin_release(lock_t l)

{

    int err;

    err = pthread_spin_unlock(l);

    if (err < 0);

    {

        return -1;

    }

    return 0;

}

static void ptspin_free(lock_t l)

{

    pthread_spin_destroy(l);

    free(l);

}

lock_ops ptspin_ops = {

    .alloc = ptspin_alloc,

    .acquire = ptspin_acquire,

    .release = ptspin_release,

    .free = ptspin_free,

};

#include <stdlib.h>

#include <unistd.h>

#include "lock."

Int main(int argc, char *argv[])

{

lock_ops  *lock_factory =  lock_ops_create(LOCK_PTSPIN); /* 创建工厂*/

lock_t  lock;

If (NULL == lock_factory )

{

      Return -1;

}

Lock = lock_factory->alloc();  /* 创建锁 */

}

应用场景: 给出的例子就是很好的实例。

对外的接口只需要关注头文件。

使用工厂模式有几个特点:

1、对外只暴露 函数接口,接口作为实现的抽象

2、整个接口可能有多个实现方式。

这种模块其实也很常见,

比如,

1、要测试某种锁的性能,只需要改动lock_ops_create(LOCK_PTSPIN); 即可

讨论

1、 直接将某个或者多个函数定义成一个宏,也能实现这种抽象。 缺点:不好维护,每次变动需要改动所有的宏

2、  直接使用宏控制 #ifdef等,直接实现多个具体实现,而且还可以再makefile中控制。

 优点: 保持常用的c语言编程的调用的习惯, 可以再makefile中控制。 

 缺点: 不好维护,代码中可能到处都是#ifdef,如果这个实现方式多的话,这将是维护的灾难


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值