设计模式(1) - Factory工厂模式

目录

1. 简单工厂模式

2.工厂方法模式

3. 抽象工厂模式

4. 几种模式的区别


Factory(工厂)模式大致可以分为三种:简单工厂模式工厂方法模式以及抽象工厂模式

1. 简单工厂模式

    首先是简单工厂模式。主要逻辑是在工厂类中进行判断,根据类型生产出对应的产品。当需要增加新的产品时,就需要修改工厂类。换言之,抽象出一个公共接口形成抽象类或者接口,然后声明一个指向基类的指针,来指向实际的子类,以达到多态目的。

#include<iostream>
using namespace std;

enum PRODUCTTYPE {TYPEA, TYPEB};
class Product
{
public:
	virtual ~Product(){};
	virtual void show() = 0;
};

class ConcreteProductA:public Product
{
public:
	void show()	{ cout<<"ConcreteProductA"<<endl; }
};

class ConcreteProductB:public Product
{
public:
	void show() { cout<<"ConcreteProductB"<<endl;	}
};

class SimpleFactory
{
public:
	Product *CreateProduct(enum PRODUCTTYPE type)
	{
		if(TYPEA == type)
		    return new ConcreteProductA();
		else if(TYPEB == type)
			return new ConcreteProductB();
		else
			return NULL;
	}
};

int main()
{
	SimpleFactory factory;
	Product *prdt = factory.CreateProduct(TYPEB);
	prdt->show();
	delete prdt;

	system("pause");
	return 0;
}

 运行结果:
ConcreteProductB
    这种实现方法,存在一些问题:
    1).客户程序员必须知道实际子类的名称。
    2).每增加一种新产品,就需要修改工厂类。违背了开放封闭原则,并且导致程序的扩展性以及维护变得困难。
    3).父类中并不知道具体要实例化哪一个具体的子类。假设:类A中需要使用类B, 而B是一个抽象父类,则A中无法知道具体要实例化哪一个B的子类,但是在A的子类D中是可以知道的。在A中,无法直接使用类似于new XXX,因为无法知道XXX代表的是哪种类。

2.工厂方法模式

    于是有了工厂方法模式。它的主要特征是:定义一个用于创建对象的接口,让子类去决定实例化哪一个类。将类的实例化延迟到子类中。

    仍然基于上述例子:新增一个工厂类B来生产B类型产品。此时,每个类型的工厂,生产不同类型的产品。因此,在产品生产的过程中,不再需要告诉其生产类型,而是选择对应的工厂即可。

class Product
{
public:
	virtual ~Product(){};
	virtual void show() = 0;
};

class ConcreteProductA:public Product
{
public:
	void show()	{ cout<<"ConcreteProductA"<<endl; }
};

class ConcreteProductB:public Product
{
public:
	void show() { cout<<"ConcreteProductB"<<endl;	}
};

class Factory
{
public:
	virtual Product *CreateProduct() = 0;
};

class FactoryA:public Factory
{
public:
	ConcreteProductA *CreateProduct()
	{
		return new ConcreteProductA;
	}
};

class FactoryB:public Factory
{
public:
	ConcreteProductB *CreateProduct()
	{
		return new ConcreteProductB;
	}
};

int main()
{
	FactoryA factory_a;
	Product *product = factory_a.CreateProduct();
	product->show();
	delete product;

	FactoryB factory_b;
	product = factory_b.CreateProduct();
	product->show();
	delete product;

	system("pause");
	return 0;
}

运行结果:
ConcreteProductA
ConcreteProductB

    工厂方法模式,也存在一定的缺陷:
    1).只要每增加一种新的产品,就需要相应的增加一个工厂,这样会产生大量的类。比起简单工厂模式,这种模式需要更多的类。这样,Factory的接口永远就无法封闭了。
        (当然,也有其它方法可以解决此问题。可以通过给Factory Method传递一个类型参数,来决定具体要创建哪种Product;或者利用模板,将具体的Product类做为模板参数).
    2).Factory模式存在局限性。它仅仅局限于一种类,即具体的产品类都有一个共同基类Product。如果需要为不同类型的类提供一个对象创建的接口,此方法就不行了。

3. 抽象工厂模式

    因此,引出了抽象工厂模式。它的主要特点是:提供一个用来创建一系列相关联或依赖的类的接口,而无需指定它们的具体的类。
    举例说明:电脑做为一种产品,即有笔记本电脑(Laptop),也有台式机(Computer)。其中,每种产品又有不同的生产/实现者。因此,有下面的实现:

//抽象产品-Laptop
class ProductLaptop
{
public:
	virtual ~ProductLaptop()=0;
};
ProductLaptop::~ProductLaptop()
{
}

//抽象产品-Computer
class ProductComputer
{
public:
	virtual ~ProductComputer() = 0;
};
ProductComputer::~ProductComputer()
{
}

//具体产品-LenovoLaptop
class ProductLenovoLaptop:public ProductLaptop
{
public:
	ProductLenovoLaptop(){cout<<"ProductLenovoLaptop"<<endl;}
};

//具体产品-DellLaptop
class ProductDellLaptop:public ProductLaptop
{
public:
	ProductDellLaptop(){cout<<"ProductDellLaptop"<<endl;}
};

//具体产品-LenovoComputer
class ProductLenovoComputer:public ProductComputer
{
public:
	ProductLenovoComputer(){cout<<"ProductLenovoComputer"<<endl;}
};

//具体产品-DellComputer
class ProductDellComputer:public ProductComputer
{
public:
	ProductDellComputer(){cout<<"ProductDellComputer"<<endl;}
};

//抽象工厂
class AbstractFactory
{
public:
	virtual ~AbstractFactory(){};
	virtual ProductComputer* CreateProductComputer()=0;
	virtual ProductLaptop* CreateProductLaptop()=0;
};

//具体工厂,生产lenovo品牌电脑
class ConcreteFactoryLenovo:public AbstractFactory
{
public:
	ProductLaptop* CreateProductLaptop(){return new ProductLenovoLaptop();};
	ProductComputer* CreateProductComputer() {return new ProductLenovoComputer();};
};

//具体工厂,生产Dell品牌电脑
class ConcreteFactoryDell:public AbstractFactory
{
public:
	ProductLaptop* CreateProductLaptop(){return new ProductDellLaptop();};
	ProductComputer* CreateProductComputer() {return new ProductDellComputer();};
};


int main()
{
	ConcreteFactoryLenovo lenovo;
	lenovo.CreateProductLaptop();
	lenovo.CreateProductComputer();

	ConcreteFactoryDell dell;
	dell.CreateProductLaptop();
	dell.CreateProductComputer();

	system("pause");
	return 1;
}

运行结果为:
ProductLenovoLaptop
ProductLenovoComputer
ProductDellLaptop
ProductDellComputer

    从上面看出,当需要创建一组对象(ProductLenovoLaptop, ProductLenovoComputer)的时候,只需要维护一个创建对象(ConcreteFactoryLenovo)即可。

4. 几种模式的区别

    AbstractFactory与Factory的区别:
    实际上,AbstractFactory模式是为创建一组相关或依赖的对象提供创建接口,而Factory是为一类对象提供创建接口或延迟对象的创建到子类中实现。并且,可以看出AbstractFactory模式通常都是使用Factory模式实现的(ConcreteFactoryA)。
    基于上面的例子:同样是Laptop和Computer,它们都可以由厂家生产,但是有不同的实现。有Lenovo和Dell两家生产出来的不同的Laptop与Computer。而负责生产Laptop与Computer就是Factory模式了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值