设计模式之四-Factory模式

简单工厂模式

简单工厂模式是工厂模式中最简单的一种,他可以用比较简单的方式隐藏创建对象的细节,一般只需要告诉工厂类所需要的类型,工厂类就会返回需要的产品类,但客户端看到的只是产品的抽象对象,无需关心到底是返回了哪个子类。客户端唯一需要知道的具体子类就是工厂子类。除了这点,基本是达到了依赖倒转原则的要求。

假如,我们不用工厂类,只用AbstractProduct和它的子类,那客户端每次使用不同的子类的时候都需要知道到底是用哪一个子类,当类比较少的时候还没什么问题,但是当类比较多的时候,管理起来就非常的麻烦了,就必须要做大量的替换,一个不小心就会发生错误。

而使用了工厂类之后,就不会有这样的问题,不管里面多少个类,我只需要知道类型号即可。不过,这里还有一个疑问,那就是如果我每次用工厂类创建的类型都不相同,这样修改起来的时候还是会出现问题,还是需要大量的替换。所以简单工厂模式一般应该于程序中大部分地方都只使用其中一种产品,工厂类也不用频繁创建产品类的情况。这样修改的时候只需要修改有限的几个地方即可。

客户只需要知道SimpleFactory就可以了,使用的时候也是使用的AbstractFactory,这样客户端只在第一次创建工厂的时候是知道具体的细节的,其他时候它都只知道AbstractFactory,这样就完美的达到了依赖倒转的原则。

常用的场景

例如部署多种数据库的情况,可能在不同的地方要使用不同的数据库,此时只需要在配置文件中设定数据库的类型,每次再根据类型生成实例,这样,不管下面的数据库类型怎么变化,在客户端看来都是只有一个AbstractProduct,使用的时候根本无需修改代码。提供的类型也可以用比较便于识别的字符串,这样不用记很长的类名,还可以保存为配置文件。

这样,每次只需要修改配置文件和添加新的产品子类即可。

所以简单工厂模式一般应用于多种同类型类的情况,将这些类隐藏起来,再提供统一的接口,便于维护和修改。

优点

1.隐藏了对象创建的细节,将产品的实例化推迟到子类中实现。

2.客户端基本不用关心使用的是哪个产品,只需要知道用哪个工厂就行了,提供的类型也可以用比较便于识别的字符串。

3.方便添加新的产品子类,每次只需要修改工厂类传递的类型值就行了。

4.遵循了依赖倒转原则。

缺点

1.要求产品子类的类型差不多,使用的方法名都相同,如果类比较多,而所有的类又必须要添加一种方法,则会是非常麻烦的事情。或者是一种类另一种类有几种方法不相同,客户端无法知道是哪一个产品子类,也就无法调用这几个不相同的方法。

2.每添加一个产品子类,都必须在工厂类中添加一个判断分支,这违背了开放-封闭原则。

C++实现代码

#ifndef _ABSTRACTPRODUCT_H_
#define _ABSTRACTPRODUCT_H_

#include <stdio.h>

class AbstractProduct{

public:
    AbstractProduct();
    virtual ~AbstractProduct();

public:
    virtual void operation() = 0;
};

class ProductA:public AbstractProduct{

public:
    ProductA();
    virtual ~ProductA();

public:
    void operation();
};

class ProductB:public AbstractProduct{

public:
    ProductB();
    ~ProductB();

public:
    void operation();
};

#endif

AbstractProduct.h
#include "AbstractProduct.h"

AbstractProduct::AbstractProduct(){
}

AbstractProduct::~AbstractProduct(){
}

ProductA::ProductA(){
}

ProductA::~ProductA(){
}

void ProductA::operation(){
    fprintf(stderr,"productA operation!\n");
}

ProductB::ProductB(){
}

ProductB::~ProductB(){
}

void ProductB::operation(){
    fprintf(stderr,"productB operation!\n");
}

AbstractProduct.cpp
#ifndef _SIMPLEFACTORY_H_
#define _SIMPLEFACTROY_H_

#include <stdio.h>
#include "AbstractProduct.h"

class AbstractFactory{

public:
    AbstractFactory();
    virtual ~AbstractFactory();

public:
    virtual AbstractProduct* createProduct(int type) = 0;
};

class SimpleFactory:public AbstractFactory{

public:
    SimpleFactory();
    ~SimpleFactory();

public:
    AbstractProduct* createProduct(int type);
};

#endif

SimpleFactory.h
#include "SimpleFactory.h"

AbstractFactory::AbstractFactory(){
}

AbstractFactory::~AbstractFactory(){
}

SimpleFactory::SimpleFactory(){
}

SimpleFactory::~SimpleFactory(){
}

AbstractProduct* SimpleFactory::createProduct(int type){
    AbstractProduct* temp = NULL;
    switch(type)
    {
    case 1:
        temp = new ProductA();
        break;
    case 2:
        temp = new ProductB();
        break;
    default:
        break;
    }
    return temp;
}

SimpleFactory.cpp
#include "SimpleFactory.h"

int main(){
    AbstractFactory* factory = new SimpleFactory();
    AbstractProduct* product = factory->createProduct(1);
    product->operation();
    delete product;
    product = NULL;

    product = factory->createProduct(2);
    product->operation();
    delete product;
    product = NULL;
    return 0;
}

client.cpp

工厂模式

工厂模式基本与简单工厂模式差不多,上面也说了,每次添加一个产品子类都必须在工厂类中添加一个判断分支,这样违背了开放-封闭原则,因此,工厂模式就是为了解决这个问题而产生的。

既然每次都要判断,那我就把这些判断都生成一个工厂子类,这样,每次添加产品子类的时候,只需再添加一个工厂子类就可以了。这样就完美的遵循了开放-封闭原则。但这其实也有问题,如果产品数量足够多,要维护的量就会增加,好在一般工厂子类只用来生成产品类,只要产品子类的名称不发生变化,那么基本工厂子类就不需要修改,每次只需要修改产品子类就可以了。

同样工厂模式一般应该于程序中大部分地方都只使用其中一种产品,工厂类也不用频繁创建产品类的情况。这样修改的时候只需要修改有限的几个地方即可。

常用的场景

基本与简单工厂模式一致,只不过是改进了简单工厂模式中的开放-封闭原则的缺陷,使得模式更具有弹性。将实例化的过程推迟到子类中,由子类来决定实例化哪个。

优点

基本与简单工厂模式一致,多的一点优点就是遵循了开放-封闭原则,使得模式的灵活性更强。

缺点

与简单工厂模式差不多。

C++实现代码

#ifndef _ABSTRACTPRODUCT_H_
#define _ABSTRACTPRODUCT_H_

#include <stdio.h>

class AbstractProduct{

public:
    AbstractProduct();
    virtual ~AbstractProduct();

public:
    virtual void operation() = 0;
};

class ProductA:public AbstractProduct{

public:
    ProductA();
    virtual ~ProductA();

public:
    void operation();
};

class ProductB:public AbstractProduct{

public:
    ProductB();
    ~ProductB();

public:
    void operation();
};

#endif

AbstractProduct.h
#include "AbstractProduct.h"

AbstractProduct::AbstractProduct(){
}

AbstractProduct::~AbstractProduct(){
}

ProductA::ProductA(){
}

ProductA::~ProductA(){
}

void ProductA::operation(){
    fprintf(stderr,"productA operation!\n");
}

ProductB::ProductB(){
}

ProductB::~ProductB(){
}

void ProductB::operation(){
    fprintf(stderr,"productB operation!\n");
}

AbstractProduct.cpp
#ifndef _SIMPLEFACTORY_H_
#define _SIMPLEFACTROY_H_

#include <stdio.h>
#include "AbstractProduct.h"

class AbstractFactory{

public:
    AbstractFactory();
    virtual ~AbstractFactory();

public:
    virtual AbstractProduct* createProduct() = 0;
};

class FactoryA:public AbstractFactory{

public:
    FactoryA();
    ~FactoryA();

public:
    AbstractProduct* createProduct();
};

class FactoryB:public AbstractFactory{

public:
    FactoryB();
    ~FactoryB();

public:
    AbstractProduct* createProduct();
};
#endif

AbstractFactory.h
#include "AbstractFactory.h"

AbstractFactory::AbstractFactory(){
}

AbstractFactory::~AbstractFactory(){
}

FactoryA::FactoryA(){
}

FactoryA::~FactoryA(){
}

AbstractProduct* FactoryA::createProduct(){
    AbstractProduct* temp = NULL;
    temp = new ProductA();
    return temp;
}

FactoryB::FactoryB(){
}

FactoryB::~FactoryB(){
}

AbstractProduct* FactoryB::createProduct(){
    AbstractProduct* temp = NULL;
    temp = new ProductB();
    return temp;
}

AbstractFactory.cpp
#include "AbstractFactory.h"

int main(){
    AbstractFactory* factory = new FactoryA();
    AbstractProduct* product = factory->createProduct();
    product->operation();
    delete product;
    product = NULL;
    delete factory;
    factory = NULL;

    factory = new FactoryB();
    product = factory->createProduct();
    product->operation();
    delete product;
    product = NULL;
    delete factory;
    factory = NULL;
    return 0;
}

client.cpp

抽象工厂模式

抽象工厂模式就变得比工厂模式更为复杂,就像上面提到的缺点一样,工厂模式和简单工厂模式要求产品子类必须要是同一类型的,拥有共同的方法,这就限制了产品子类的扩展。于是为了更加方便的扩展,抽象工厂模式就将同一类的产品子类归为一类,让他们继承同一个抽象子类,我们可以把他们一起视作一组,然后好几组产品构成一族。

此时,客户端要使用时必须知道是哪一个工厂并且是哪一组的产品抽象类。每一个工厂子类负责产生一族产品,而子类的一种方法产生一种类型的产品。在客户端看来只有AbstractProductA和AbstractProductB两种产品,使用的时候也是直接使用这两种产品。而通过工厂来识别是属于哪一族产品。

产品ProductA_1和ProductB_1构成一族产品,对应于有Factory1来创建,也就是说Factory1总是创建的ProductA_1和ProductB_1的产品,在客户端看来只需要知道是哪一类工厂和产品组就可以了。一般来说, ProductA_1和ProductB_1都是适应同一种环境的,所以他们会被归为一族。

常用的场景

例如Linux和windows两种操作系统下,有2个挂件A和B,他们在Linux和Windows下面的实现方式不同,Factory1负责产生能在Linux下运行的挂件A和B,Factory2负责产生能在Windows下运行的挂件A和B,这样如果系统环境发生变化了,我们只需要修改工厂就行了。

优点

1.封装了产品的创建,使得不需要知道具体是哪种产品,只需要知道是哪个工厂就行了。

2.可以支持不同类型的产品,使得模式灵活性更强。

3.可以非常方便的使用一族中间的不同类型的产品。

缺点

1.结构太过臃肿,如果产品类型比较多,或者产品族类比较多,就会非常难于管理。

2.每次如果添加一组产品,那么所有的工厂类都必须添加一个方法,这样违背了开放-封闭原则。所以一般适用于产品组合产品族变化不大的情况。

C++实现代码

#ifndef _ABSTRACTPRODUCTA_H_
#define _ABSTRACTPRODUCTA_H_

#include <stdio.h>

class AbstractProductA{

public:
    AbstractProductA();
    virtual ~AbstractProductA();

public:
    virtual void operationA() = 0;
};

class ProductA_1:public AbstractProductA{

public:
    ProductA_1();
    virtual ~ProductA_1();

public:
    void operationA();
};

class ProductA_2:public AbstractProductA{

public:
    ProductA_2();
    ~ProductA_2();

public:
    void operationA();
};

#endif

AbstractProductA.h
#include "AbstractProductA.h"

AbstractProductA::AbstractProductA(){
}

AbstractProductA::~AbstractProductA(){
}

ProductA_1::ProductA_1(){
}

ProductA_1::~ProductA_1(){
}

void ProductA_1::operationA(){
    fprintf(stderr,"productA_1 operation!\n");
}

ProductA_2::ProductA_2(){
}

ProductA_2::~ProductA_2(){
}

void ProductA_2::operationA(){
    fprintf(stderr,"productA_2 operation!\n");
}

AbstractProductA.cpp
#ifndef _ABSTRACTPRODUCTB_H_
#define _ABSTRACTPRODUCTB_H_

#include <stdio.h>

class AbstractProductB{

public:
    AbstractProductB();
    virtual ~AbstractProductB();

public:
    virtual void operationB() = 0;
};

class ProductB_1:public AbstractProductB{

public:
    ProductB_1();
    virtual ~ProductB_1();

public:
    void operationB();
};

class ProductB_2:public AbstractProductB{

public:
    ProductB_2();
    ~ProductB_2();

public:
    void operationB();
};

#endif

AbstractProductB.h
#include "AbstractProductB.h"

AbstractProductB::AbstractProductB(){
}

AbstractProductB::~AbstractProductB(){
}

ProductB_1::ProductB_1(){
}

ProductB_1::~ProductB_1(){
}

void ProductB_1::operationB(){
    fprintf(stderr,"productB_1 operation!\n");
}

ProductB_2::ProductB_2(){
}

ProductB_2::~ProductB_2(){
}

void ProductB_2::operationB(){
    fprintf(stderr,"productB_2 operation!\n");
}

AbstractProductB.cpp
#ifndef _SIMPLEFACTORY_H_
#define _SIMPLEFACTROY_H_

#include <stdio.h>
#include "AbstractProductA.h"
#include "AbstractProductB.h"

class AbstractFactory{

public:
    AbstractFactory();
    virtual ~AbstractFactory();

public:
    virtual AbstractProductA* createProductA() = 0;
    virtual AbstractProductB* createProductB() = 0;
};

class Factory1:public AbstractFactory{

public:
    Factory1();
    ~Factory1();

public:
    AbstractProductA* createProductA();
    AbstractProductB* createProductB();
};

class Factory2:public AbstractFactory{

public:
    Factory2();
    ~Factory2();

public:
    AbstractProductA* createProductA();
    AbstractProductB* createProductB();
};
#endif

AbstractFactory.h
#include "AbstractFactory.h"

AbstractFactory::AbstractFactory(){
}

AbstractFactory::~AbstractFactory(){
}

Factory1::Factory1(){
}

Factory1::~Factory1(){
}

AbstractProductA* Factory1::createProductA(){
    AbstractProductA* temp = NULL;
    temp = new ProductA_1();
    return temp;
}

AbstractProductB* Factory1::createProductB(){
    AbstractProductB* temp = NULL;
    temp = new ProductB_1();
    return temp;
}

Factory2::Factory2(){
}

Factory2::~Factory2(){
}

AbstractProductA* Factory2::createProductA(){
    AbstractProductA* temp = NULL;
    temp = new ProductA_2();
    return temp;
}

AbstractProductB* Factory2::createProductB(){
    AbstractProductB* temp = NULL;
    temp = new ProductB_2();
    return temp;
}

AbstractFactory.cpp
#include "AbstractFactory.h"

int main(){

    AbstractFactory* factory = new Factory1();
    AbstractProductA* productA = factory->createProductA();
    AbstractProductB* productB = factory->createProductB();
    productA->operationA();
    productB->operationB();

    delete factory;
    factory = NULL;
    delete productA;
    productA = NULL;
    delete productB;
    productB = NULL;

    factory = new Factory2();
    productA = factory->createProductA();
    productB = factory->createProductB();
    productA->operationA();
    productB->operationB();

    delete factory;
    factory = NULL;
    delete productA;
    productA = NULL;
    delete productB;
    productB = NULL;
    return 0;
}

client.cpp

转载自http://www.cnblogs.com/cxjchen/p/3143633.html

时间: 2024-07-30 10:19:27

设计模式之四-Factory模式的相关文章

C#设计模式之四建造者模式(Builder Pattern)【创建型】

原文:C#设计模式之四建造者模式(Builder Pattern)[创建型] 一.引言 今天我们要讲讲Builder模式,也就是建造者模式,当然也有叫生成器模式的,英文名称是Builder Pattern.在现实生活中,我们经常会遇到一些构成比较复杂的物品,比如:电脑,它就是一个复杂的物品,它主要是由CPU.主板.硬盘.显卡.机箱等组装而成的.手机当然也是复杂物品,由主板,各种芯片,RAM 和ROM  摄像头之类的东西组成.但是无论是电脑还是手机,他们的组装过程是固定的,就拿手机来说,组装流水线

设计模式之Factory模式(C++)

Factory模式具有两大重要的功能: (1).定义创建对象的接口,封装了对象的创建: (2).使具体化类工作延迟到了子类中. //Product.h #ifndef _PRODUCT_H_ #define _PRODUCT_H_ class Product { public: virtual void ~Product(); protected: void Product(); private: } class ConcreteProduct:public Product { public:

设计模式之四 代理模式

代理模式是一个使用率非常高的模式,其定义如下: 为其他对象提供一种代理可以控制对这个对象的访问. Subject 抽象主题角色 抽象主题类可以是抽象类也可以是接口,是一个最普通的业务类型定义,无特殊要求 RealSubject 具体主题角色 被委托的角色,被代理的角色. 它才是冤大头,是业务逻辑的具体执行者. Proxy 代理主题角色 也叫委托类,代理类. 它负责对真是角色的应用,把所有抽象主题类定义的方法限制委托给真实主题角色实现,并且在真实主题角色处理完毕前后做预处理和善后处理工作.

Java学习笔记——设计模式之四.代理模式

To be, or not to be: that is the question. --<哈姆雷特> 代理模式(Proxy),为其他对象提供一种代理以控制对这个对象的访问. 上代码: 1 package cn.no4.proxy; 2 3 public interface IMakeMoney { 4 5 void makeMoney(); 6 } 1 package cn.no4.proxy; 2 3 public class Proxy implements IMakeMoney { 4

java设计模式之四建造者模式(Builder)

工厂类模式提供的是创建单个类的模式,而建造者模式则是将各种产品集中起来进行管理,用来创建复合对象,所谓复合对象就是指某个类具有不同的属性,其实建造者模式就是前面抽象工厂模式和最后的Test结合起来得到的.我们看一下代码: 还和前面一样,一个Sender接口,两个实现类MailSender和SmsSender.最后,建造者类如下: [java] view plaincopy public class Builder { private List<Sender> list = new ArrayL

java23种设计模式之四:建造者模式

一.build 介绍 二.实现原理 通过访问静态内部的形式得到内部类,内部类通过有参方法将传入的参数赋值给静态内部类对象,外部类私有构造函数,参数设置成静态内部类对象当静态内部类对象通过无参的build方法获得外部类时,外部类构造函数需要传入静态内部类实例对象,此时,精彩的来了,因为通过访问静态内部的方法获得了内部类对象,而在调用build方法时需要传入内部类对象,而在外部类的私有构造中传入的是静态内部类对象,因此build方法之前全是静态内部类对象,而在build时,确将自己当成参数传入外部类

IOS设计模式之四(备忘录模式,命令模式)

本文原文请见:http://www.raywenderlich.com/46988/ios-design-patterns. 由 @krq_tiger(http://weibo.com/xmuzyq)翻译,如果你发现有什么错误,请与我联系谢谢. 备忘录(Memento)模式 备忘录模式快照对象的内部状态并将其保存到外部.换句话说,它将状态保存到某处,过会你可以不破坏封装的情况下恢复对象的状态,也就是说原来对象中的私有数据仍然是私有的. 如何使用备忘录模式 在ViewController.m中增加

设计模式(3)-对象创建型模式-Abstract Factory模式

1.对象创建型模式 1.3           Abstract Factory模式 1.3.1 需求 在下面情况能够使用Abstract Factory模式: ?  一个系统要独立于它的产品的创建.组合和表示时(这个需求和FactoryMethod类似). ?  一个系统要由多个产品系列中的一个来配置时(这个需求也和Factory Method类似). ?  当你要强调一系列相关的产品对象的设计以便进行联合使用时(这个需求表明一个工厂要创建多个相关的产品对象,是比FactoryMethod多的

设计模式 - 抽象工厂模式(abstract factory pattern) 详解

抽象工厂模式(abstract factory pattern) 详解 本文地址: http://blog.csdn.net/caroline_wendy/article/details/27091671 参考工厂模式: http://blog.csdn.net/caroline_wendy/article/details/27081511 抽象工厂模式: 提供一个接口, 用于创建相关或依赖对象的家族, 而不需要明确指定具体类. 全部代码: http://download.csdn.net/de