(1)定义3

简单工厂模式中,每新增一个具体产品,就需要修改工厂类内部的判断逻辑。为了不修改工厂类,遵循开闭原则,工厂方法模式中不再使用工厂类统一创建所有的具体产品,而是针对不同的产品设计了不同的工厂,每一个工厂只生产特定的产品。

定义一个用于创建对象的接口,但是让子类决定将哪一个类实例化。工厂方法模式让一个类的实例化延迟到其子类。

(2)结构

工厂模式结构如下:

  • 抽象工厂(AbstractFactory):所有生产具体产品的工厂类的基类,提供工厂类的公共方法;
  • 具体工厂(ConcreteFactory):生产具体的产品;
  • 抽象产品(AbstractProduct):所有产品的基类,提供产品类的公共方法;
  • 具体产品(ConcreteProduct):具体的产品类。

(3)实例

Factory.h

#ifndef FACTORY_H
#define FACTORY_H
#include <iostream>
#include <string> /********************************产品类***********************************/
//抽象产品类AbstractProduct(并非真正意义上的抽象类,含有纯虚函数才是抽象类)
class AbstractSportProduct
{
public:
AbstractSportProduct(){}
~AbstractSportProduct(){} //虚函数
virtual void play(){}
}; //具体产品类Basketball
class Basketball :public AbstractSportProduct
{
public:
Basketball(){}
~Basketball(){} //具体实现方法
void play();
}; //具体产品类Football
class Football :public AbstractSportProduct
{
public:
Football(){}
~Football(){} //具体实现方法
void play();
}; /********************************工厂类***********************************/
//抽象工厂类
class AbstractFactory{
public:
//纯虚函数
virtual AbstractSportProduct *getSportProduct() = 0;
}; //具体工厂类BasketballFactory
class BasketballFactory:public AbstractFactory
{
public:
BasketballFactory(){}
~BasketballFactory(){} AbstractSportProduct *getSportProduct();
}; //具体工厂类FootballFactory
class FootballFactory:public AbstractFactory
{
public:
FootballFactory(){}
~FootballFactory(){} AbstractSportProduct *getSportProduct();
}; #endif // FACTORY_H

Factory.cpp

#include "Factory.h"

/********************************产品类方法***********************************/
//Basketball方法
void Basketball::play(){
printf("play Basketball\n");
} //Football方法
void Football::play(){
printf("play Football\n");
} /********************************工厂类方法***********************************/
//BasketballFactory方法
AbstractSportProduct *BasketballFactory::getSportProduct()
{
return new Basketball();
} //FootballFactory方法
AbstractSportProduct *FootballFactory::getSportProduct()
{
return new Football();
}

main.cpp

#include "Factory.h"

int _tmain(int argc, _TCHAR* argv[])
{
AbstractSportProduct *pro = nullptr;
AbstractFactory *fac = nullptr; fac = new BasketballFactory();
pro = fac->getSportProduct();
pro->play(); fac = new FootballFactory();
pro = fac->getSportProduct();
pro->play(); return 0;
}

输出结果:

(4)总结

如果想增加棒球(Baseball)类,只需要增加一个棒球工厂(BaseballFacory),然后在客户端代码中修改具体工厂类的类名,而原有的类的代码无需修改。由此可看到,相较简单工厂模式,工厂方法模式更加符合开闭原则。工厂方法是使用频率最高的设计模式之一,是很多开源框架和API类库的核心模式。

优点:

  • 工厂方法用于创建客户所需产品,同时向客户隐藏某个具体产品类将被实例化的细节,用户只需关心所需产品对应的工厂;
  • 工厂自主决定创建何种产品,并且创建过程封装在具体工厂对象内部,多态性设计是工厂方法模式的关键;
  • 新加入产品时,无需修改原有代码,增强了系统的可扩展性,符合开闭原则。

缺点:

  • 添加新产品时,需要同时添加新的产品工厂,系统中类的数量成对增加,增加了系统的复杂度,更多的类需要编译和运行,增加了系统的额外开销;
  • 工厂和产品都引入了抽象层,客户端代码中均使用的抽象层,增加了系统的抽象层次和理解难度。

最新文章

  1. 【Java EE 学习 16 上】【dbcp数据库连接池】【c3p0数据库连接池】
  2. SQLite数据库
  3. 关于分布式事务、两阶段提交、一阶段提交、Best Efforts 1PC模式和事务补偿机制的研究 转载
  4. [ucgui] 对话框5——鼠标位置和移动窗口
  5. Python之Django【基础篇】
  6. 轻松了解Spring中的控制反转和依赖注入(二)
  7. HTML文件基本结构
  8. Android--用DownLoadManager下载完成后启动安装
  9. 1.7.1 solr Searching概述
  10. 树形结构的维护:BZOJ 3991: [SDOI2015]寻宝游戏
  11. BIGINT UNSIGNED value is out of range in … 问题的解决方法
  12. js-计算器
  13. 轻松创建nodejs服务器(1):一个简单nodejs服务器例子
  14. hibernate系列笔记(2)---Hibernate的核心API
  15. 用Spring Tools Suite(STS)开始一个RESTful Web Service
  16. Django 日志配置
  17. vue 用huilder打包APP时,安卓按返回键就退出App改为按两次再退出App
  18. Python之旅Day15 Bootstrap与Django初识
  19. MySQL数据库性能优化思路与解决方法(一转)
  20. MySql安装和基本管理&amp;mysql语句

热门文章

  1. 区间查询与等效minus查询
  2. nginx安装第三方模块echo
  3. Java面试炼金系列 (1) | 关于String类的常见面试题剖析
  4. Intersection of Two Prisms(AOJ 1313)
  5. shell字体颜色应用
  6. 浅谈Charles —— 青花瓷
  7. CentOS 7使用PuppeteerSharp无头浏览器注意事项
  8. Flutter 使用image_gallery_saver保存图片
  9. AtomicInteger原理&amp;源码分析
  10. 面向对象技术-原文转载自jingwhale