工厂模式&抽象工厂

面向对象系统设计中经常遇到的两类问题&工厂模式要解决的问题

1、为了提高内聚和松耦合,我们经常会抽象出一些类的公共接口以形成抽象基类或者接口。这样我们可以通过声明一个指向基类的指针来指向实际的子类实现,达到了多态的目的。这里很容易出现的一个问题是:若干个子类继承自抽象基类,我们必须在每次要用到子类的地方就写如: new ×××; 的代码。这里带来两个问题:     

   (1)客户程序员必须知道实际子类的名称(当系统复杂后,命名将是一个很不好处理的问题,为了处理可能的名字冲突,有的命名可能并不是具有很好的可读性和可记忆性,而且每个程序员都有自己的编程命名风格) 

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

2、另一种情况就是在父类中并不知道到具体要实例化哪一个具体的子类。比如类A中使用到类B,但类B是一个抽象父类,类A并不知道要实例化类B的哪一个子类,因此类A表示很懵逼。

这两个问题就引出了工厂模式最重要的功能:

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

       2、延迟具体化类的工作到子类中。

总的来说:工厂模式主要解决接口选择的问题,该模式下定义一个创建对象的接口,让子类自己决定要实例化哪一个工厂类,使其创建过程延迟到子类进行。

 

工厂模式

#include <iostream>
using namespace std;

// Product block
class Product
{
public:
	// 析构函数可以被声明为纯虚函数,但也必须给出函数定义
	virtual ~Product() = 0;
protected:
	Product() { cout << "Product()" << endl; }
};
class ConcreteProduct :public Product
{
public:
	ConcreteProduct() { cout << "ConcreteProduct() "; cout << "生产罐头" << endl; }
	~ConcreteProduct() { cout << "~ConcreteProduct()" << endl; }
};

// Factory block
class Factory
{
public:
	virtual ~Factory() = 0;
	virtual Product* CreateProduct() = 0; // 纯虚函数   返回(抽象)产品类型
protected:
	Factory() { cout << "Factory()" << endl; }
};

class ConcreteFactory :public Factory    //具体
{
public:
	~ConcreteFactory() { cout << "~ConcreteFactory()" << endl; }
	ConcreteFactory() { cout << "ConcreteFactory() 构造罐头厂" << endl; }

	Product* CreateProduct()   // 重写生产 产品类
	{
		return new ConcreteProduct();
	}
};

int main()
{
	Factory* fac = new ConcreteFactory();  //父类指针指向子类对象
	Product* pro = fac->CreateProduct();
	return 0;
}

 程序这里有点问题:

 不知道为什么?然后我在Product类的虚析构函数那右键 【快速操作和重构】,生成它的定义,然后还有Factory类中的虚析构函数也是一样的操作,然后就好了。很懵。。。

这是运行结果

抽象工厂模式

#include <iostream>
using namespace std;

// Product block
class Abs_ProductA  // 抽象产品类A
{
public:
	virtual ~Abs_ProductA(){ cout << "~Abs_ProductA()" << endl; }
protected:
	Abs_ProductA() { cout << "Abs_ProductA()" << endl; }
};
class Abs_ProductB   // 抽象产品类B
{
public:
	virtual ~Abs_ProductB() { cout << "~Abs_ProductB()" << endl; }
protected:
	Abs_ProductB() { cout << "Abs_ProductB()" << endl; }
};

class ProductA1 :public Abs_ProductA
{
public:
	ProductA1() { cout << "ProductA1()" << endl; }
	~ProductA1() { cout << "~ProductA1()" << endl; }
};
class ProductA2 :public Abs_ProductA
{
public:
	ProductA2() { cout << "ProductA2()" << endl; }
	~ProductA2() { cout << "~ProductA2()" << endl; }
};

class ProductB1 :public Abs_ProductB
{
public:
	ProductB1() { cout << "ProductB1()" << endl; }
	~ProductB1() { cout << "~ProductB1()" << endl; }
};
class ProductB2 :public Abs_ProductB
{
public:
	ProductB2() { cout << "ProductB2()" << endl; }
	~ProductB2() { cout << "~ProductB2()" << endl; }
};


//Abstract Factory block
class Abs_Factory
{
public:
	virtual ~Abs_Factory() { cout << "~Abs_Factory()" << endl; }

	virtual Abs_ProductA* createProductA() = 0;
	virtual Abs_ProductB* createProductB() = 0;
protected:
	Abs_Factory() { cout << "Abs_Factory()" << endl; }
};
class ConcreteFactory1 :public Abs_Factory
{  //具体工厂 1 可以生产A1、A2、B1、B2四种产品,假设具体工厂 1 只生产标号为1 的产品
public:
	ConcreteFactory1() { cout << "ConcreteFactory1()" << endl; }
	~ConcreteFactory1() { cout << "~ConcreteFactory1()" << endl; }

	Abs_ProductA* createProductA() { return new ProductA1(); }
	Abs_ProductB* createProductB() { return new ProductB1(); }
};
class ConcreteFactory2 :public Abs_Factory
{
public:
	ConcreteFactory2() { cout << "ConcreteFactory2()" << endl; }
	~ConcreteFactory2() { cout << "~ConcreteFactory2()" << endl; }

	Abs_ProductA* createProductA() { return new ProductA2(); }
	Abs_ProductB* createProductB() { return new ProductB2(); }
};

int main()
{
	Abs_Factory* af1 = new ConcreteFactory1();
	af1->createProductA();
	af1->createProductB();

	Abs_Factory* af2 = new ConcreteFactory2();
	af2->createProductA();
	af2->createProductB();
	return 0;
}

运行结果

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值