当前位置: 首页 > news >正文

工厂模式抽象工厂

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

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;
}

运行结果

 

相关文章:

  • 链表翻转
  • LRU缓存算法
  • 判断单链表中是否存在环
  • LeeCode61 旋转链表
  • LeeCode74 搜索二维矩阵
  • (0)Nginx 功能特性
  • (2)nginx 安装、启停
  • (3)nginx 配置(nginx.conf)
  • 汇编语言学习笔记--基础知识篇
  • IAR for 430软件的简单使用
  • 430单片机时钟系统与复位系统的配置(1)
  • 430单片机时钟系统与复位系统的配置(2)
  • STM32F103芯片的一些小知识
  • RCC的一些小知识
  • stm32 SPI学习
  • [PHP内核探索]PHP中的哈希表
  • 【译】JS基础算法脚本:字符串结尾
  • 【140天】尚学堂高淇Java300集视频精华笔记(86-87)
  • 【编码】-360实习笔试编程题(二)-2016.03.29
  • 【跃迁之路】【463天】刻意练习系列222(2018.05.14)
  • 5分钟即可掌握的前端高效利器:JavaScript 策略模式
  • isset在php5.6-和php7.0+的一些差异
  • Java 多线程编程之:notify 和 wait 用法
  • python 学习笔记 - Queue Pipes,进程间通讯
  • React as a UI Runtime(五、列表)
  • Redis字符串类型内部编码剖析
  • springMvc学习笔记(2)
  • Spring思维导图,让Spring不再难懂(mvc篇)
  • SwizzleMethod 黑魔法
  • Twitter赢在开放,三年创造奇迹
  • TypeScript实现数据结构(一)栈,队列,链表
  • Zepto.js源码学习之二
  • 安装python包到指定虚拟环境
  • 反思总结然后整装待发
  • 仿天猫超市收藏抛物线动画工具库
  • 后端_ThinkPHP5
  • 精益 React 学习指南 (Lean React)- 1.5 React 与 DOM
  • 前端之Sass/Scss实战笔记
  • 说说动画卡顿的解决方案
  • 为什么要用IPython/Jupyter?
  • 最简单的无缝轮播
  • $.extend({},旧的,新的);合并对象,后面的覆盖前面的
  • $emit传递多个参数_PPC和MIPS指令集下二进制代码中函数参数个数的识别方法
  • (Java)【深基9.例1】选举学生会
  • (附源码)spring boot校园健康监测管理系统 毕业设计 151047
  • (考研湖科大教书匠计算机网络)第一章概述-第五节1:计算机网络体系结构之分层思想和举例
  • (蓝桥杯每日一题)love
  • (每日持续更新)jdk api之FileReader基础、应用、实战
  • (最全解法)输入一个整数,输出该数二进制表示中1的个数。
  • .h头文件 .lib动态链接库文件 .dll 动态链接库
  • .Net mvc总结
  • .Net 垃圾回收机制原理(二)
  • .net快速开发框架源码分享
  • .ui文件相关
  • ?php echo $logosrc[0];?,如何在一行中显示logo和标题?