设计模式之抽象工厂和工厂方法

一,抽象工厂

目的:抽象工厂主要的作用就是,提供一系列的接口,将对象的创建者和对象的创建过程分离。通俗点将就是将对象new的过程进行封装,通过接口的方式返回对象。
简单的用法:
假设某个用户在建房子,需要钢筋和钢管来搭框架,那么.
用户:client
钢材厂:factory
钢筋:productA
钢管:productB

class productA {
public:
    productA();
    ~productA();
};
class productB {
public:
    productB();
    ~productB();
};
class factory{
publicvirtual productA* createA() { return new productA(); }
    virtual productB* createB() { return new productB(); }
};
class client {
protected:
    factory* fac;
};

在任何需要产品的时候,用户client只需要通过factory的对象,调用对应的接口,就可以拿到想要产品。
注:这里传送最好使用智能指针,避免导致内存泄漏。
扩展用法:
把抽象工厂和面向对象结合起来。接上面的例子,现在client知道了有两家工厂可以生产钢管和钢筋,但两个工厂生产的产品粗细,质量,价格却不相同,需要在建房时做出选择,那么:

class productA_0 : public productA {
protected:
        int len;
        int size;
};
class productB_0 : public productB {
protected:
    int len;
    int size;
};
class productA_1 : public productA {
protected:
    int len;
    int size;
};
class productB_1 : public productB{
protected:
    int len;
    int size;
};
class factory_0 : public factory {
public:
    virtual productA* createA() { return new productA_0(); }
    virtual productB* createB() { return new productB_0(); }
};
class factory_1: public factory {
public:
    virtual productA* createA() { return new productA_1(); }
    virtual productB* createB() { return new productB_1(); }
};
class client {
public:
    client();
    ~client();
protected:
    factory* fac;
};

这样client中定义的代码就不需要改动。只需要在factory创建的时候,根据自己的需要创建对应的工厂对象即可。而且如果需要更换工厂也很方便。
抽象工厂的局限性:
假设用户突然发现,用钢材的成本太高了,现在想要用木材了。那么上面设计的就全部废掉了。
所以抽象工厂在系列产品的扩展/交换方面很有优势。却难以支持新品种的扩展,任何新品种的扩展都需要添加新的工厂。而且对于同一个系列的的产品,一个工厂一次只能使用一种,如果想要同时使用同一个系列的多个产品,则需要创建多个工厂。

二,工厂方法

目的:工厂方法本质上就是一个函数。在一个class中定义一个用于创建对象的接口。与class的继承结合起来,可以让一个类的实例化延迟到子类。
简单的用法:
在user中创建一个create()的func,用于创建Product对象

class Product {
protected:
    int param;
};
class user {
public:
    virtual Product* create() { return new Product(); }
};

扩展用法:
对于工厂方法的简单用法其实并没有什么意义。我觉得有意思的还是工厂方法与继承的结合。

class Product_0  : public Product{
protected:
    int param;
    int extend;
};
class Product_1 : public Product {
protected:
    int param;
    int extend;
};
class user_0 :public user {
public:
    virtual Product* create() { return new Product_0(); }
};
class user_1 :public user {
public:
    virtual Product* create() { return new Product_1(); }
};

user的子类只需要根据自己的需要,重写create函数即可。这种模式尤其是在写基础代码时有用,很多时候, 并不知道自己定义的class 会被谁用到怎么用。用工厂方法,相当于给子类预留了一个hook,让使用者自己去决定,去生成什么对象。
另外:工厂方法可以携带参数,实现者可以根据传入的参数去决定生产需要的对象。

class user_2:public user {
public:
    virtual Product* create( int res ) {
        if( res == 0 )
            return new Product_0();
        else
            return new Product_1();
    }
};

三,区别

首先,抽象工厂是一个class,而工厂方法只是一个fun。
第二,抽象工厂一般关联多个对象,更注重对象之间的关系,工厂方法只是创建对象。
第三,抽象工厂将对象的创建封装了,如果想要换对象就必须换工厂。而工厂方法,创建对象是可见的。更改对象时,需要直接更改工厂方法。
第四,在某种意义上来说,抽象工厂也可以看作是一个只有工厂方法的class。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值