工厂模式

简单工厂、工厂方法,抽象工厂

Posted by bbkgl on October 31, 2019

银碗盛雪

明月藏鹭

白马入芦花

工厂模式是最常用的实例化对象模式了,是用工厂方法代替new操作的一种模式。虽然这样做,可能多做一些工作,但会给系统带来更大的可扩展性和尽量少的修改量。

工厂模式一般分为三种:简单工厂模式、工厂方法模式和抽象工厂模式。

简单工厂模式

工厂创建产品,并且它决定创建产品的类型,就有点像手机的代工厂,比如富士康,要接收小米的手机代工生产,也要接受苹果的代工生产,用C++实现如下:

#include <cstdio>
#include <iostream>

enum PhoneType{MI = 0, APPLE};

class Phone {
public:
    virtual void create() = 0;
};

class MiPhone : public Phone {
public:
    MiPhone() {}
    void create() {
        std::cout << "Created a MI Phone!" << std::endl;
    }
};

class ApplePhone : public Phone {
public:
    ApplePhone() {}
    void create() {
        std::cout << "Created a APPLE Phone!" << std::endl;
    }
};

class PhoneFactory {
public:
    Phone *create_phone(PhoneType type) {
        switch (type) {
        case MI:
            return new MiPhone();
            break;
        case APPLE:
            return new ApplePhone();
            break;
        default:
            break;
        }
    }
};

int main() {
    return 0;
}

简单工厂的缺点是显而易见的,比如上述的手机工厂,只能生成小米和苹果两种品牌的手机,如果要生产更多品牌的手机,就需要修改PhoneFactory类的代码,显然不符合开放封闭原则:软件实体(类、模块、函数)可以扩展,但是不可修改。于是,工厂方法模式出现了。

工厂方法模式

工厂方法模式在简单工厂模式上添加了多种工厂类,也就是工厂类和手机类一样变成了抽象类,生产手机的任务交给具体类型的手机工厂类去实现。这样的话,如果有其他品牌的手机需要生产,不需要修改原来的代码,可以直接添加对应工厂类和手机类,使用继承即可。

C++实现如下:

#include <cstdio>
#include <iostream>

class Phone {
public:
    virtual void create() = 0;
};

class MiPhone : public Phone {
public:
    MiPhone() {
        create();
    }
    void create() {
        std::cout << "Created a MI Phone!" << std::endl;
    }
};

class ApplePhone : public Phone {
public:
    ApplePhone() {
        create();
    }
    void create() {
        std::cout << "Created a APPLE Phone!" << std::endl;
    }
};

class PhoneFactory {
public:
    virtual Phone *create_phone() = 0;
};

class MiPhoneFactory : public PhoneFactory {
public:
    Phone *create_phone() {
        return new MiPhone();
    }
};

class ApplePhoneFactory : public PhoneFactory {
public:
    Phone *create_phone() {
        return new ApplePhone();
    }
};

int main() {
    PhoneFactory *pf = nullptr;
    Phone *p = nullptr;
    pf = new MiPhoneFactory();
    p = pf->create_phone();
    pf = new ApplePhoneFactory();
    p = pf->create_phone();
    return 0;
}

输出如下:

5dbaa022bd461d945a7cf833

抽象工厂

抽象工厂的关键词就在抽象两字,抽象工厂会包含一个抽象工厂类,这个抽象工厂类提供一个个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。

抽象工厂类由其他具体实现的类继承,然后由其他类实现对应创造产品的方法,如果需要增加产品或者增加工厂,只需要增加接口,或者修改实现内容即可,而不需要修改原接口。

C++实现如下:

#include <cstdio>
#include <iostream>

enum Type{MI = 0, APPLE};

class Phone {
public:
    virtual void create() = 0;
};

class PC {
public:
    virtual void create() = 0;
};

class AbstractFactory {
public:
    virtual Phone *get_phone(Type type) = 0;
    virtual PC *get_pc(Type type) = 0;
};

class MiPhone : public Phone {
public:
    MiPhone() {
        create();
    }
    void create() {
        std::cout << "Created a MI Phone!" << std::endl;
    }
};

class MiPC : public PC {
public:
    MiPC() {
        create();
    }
    void create() {
        std::cout << "Created a MI PC!" << std::endl;
    }
};

class ApplePhone : public Phone {
public:
    ApplePhone() {
        create();
    }
    void create() {
        std::cout << "Created a APPLE Phone!" << std::endl;
    }
};

class ApplePC : public PC {
public:
    ApplePC() {
        create();
    }
    void create() {
        std::cout << "Created a APPLE PC!" << std::endl;
    }
};

class PhoneFactory : public AbstractFactory {
public:
    Phone *get_phone(Type type) {
        switch (type) {
        case MI:
            return new MiPhone();
            break;
        case APPLE:
            return new ApplePhone();
            break;
        default:
            break;
        }
    }

    PC *get_pc(Type type) { return nullptr; }
};

class PCFactory : public AbstractFactory {
public:
    PC *get_pc(Type type) {
        switch (type) {
        case MI:
            return new MiPC();
            break;
        case APPLE:
            return new ApplePC();
            break;
        default:
            break;
        }
    }

    Phone *get_phone(Type type) { return nullptr; }
};

int main() {
    AbstractFactory *fac = new PCFactory();
    PC *pc = fac->get_pc(MI);
    fac = new  PhoneFactory();
    Phone *p = fac->get_phone(APPLE);
    return 0;
}

输出结果:

5dbae262bd461d945a885e0b