问题描述

假设我们要开发一款游戏, 当然为了吸引更多的人玩, 游戏难度不能太大(让大家都没有信心了,估计游戏也就没有前途了),但是也不能太简单(没有挑战性也不符合玩家的心理)。于是我们就可以采用这样一种处理策略: 为游戏设立等级,初级、中级、高级甚至有BT 级。 假设也是过关的游戏, 每个关卡都有一些怪物( monster) 守着, 玩家要把这些怪物干掉才可以过关。 作为开发者, 我们就不得不创建怪物的类, 然后初级怪物、 中级怪物等都继承自怪物类(当然不同种类的则需要另创建类,但是模式相同)。在每个关卡, 我们都要创建怪物的实例,例如初级就创建初级怪物( 有很多种类)、中级创建中级怪物等。可以想象在这个系统中, 将会有成千上万的怪物实例要创建, 问题是还要保证创建的时候不会出错:初级不能创建 BT 级的怪物(玩家就郁闷了,玩家一郁闷,游戏也就挂挂了),反之也不可以。

AbstractFactory 模式就是用来解决这类问题的:要创建一组相关或者相互依赖的对象。

UML类图

其关键就是将这一组对象的创建封装到一个用于创建对象的类( ConcreteFactory)中, 维护这样一个创建类总比维护 n 多相关对象的创建过程要简单的多

适用场合

工厂方法模式适用于产品种类结构单一的场合,为一类产品提供创建的接口;而抽象工厂方法适用于产品种类结构多的场合,主要用于创建一组(有多个种类)相关的产品,为它们提供创建的接口;就是当具有多个抽象角色时,抽象工厂便可以派上用场。

代码实现

#include <iostream>
#include <string>
using namespace std; class IUser
{
public:
virtual void getUser() = 0;
virtual void setUser() = 0;
}; class SqlUser :public IUser
{
public:
void getUser()
{
cout << "在sql中返回user" << endl;
}
void setUser()
{
cout << "在sql中设置user" << endl;
}
}; class AccessUser :public IUser
{
public:
void getUser()
{
cout << "在Access中返回user" << endl;
}
void setUser()
{
cout << "在Access中设置user" << endl;
}
}; class IDepartment
{
public:
virtual void getDepartment() = 0;
virtual void setDepartment() = 0;
}; class SqlDepartment :public IDepartment
{
public:
void getDepartment()
{
cout << "在sql中返回Department" << endl;
}
void setDepartment()
{
cout << "在sql中设置Department" << endl;
}
}; class AccessDepartment :public IDepartment
{
public:
void getDepartment()
{
cout << "在Access中返回Department" << endl;
}
void setDepartment()
{
cout << "在Access中设置Department" << endl;
}
}; class IFactory
{
public:
virtual IUser *createUser() = 0;
virtual IDepartment *createDepartment() = 0;
}; class SqlFactory :public IFactory
{
public:
IUser *createUser()
{
return new SqlUser();
}
IDepartment *createDepartment()
{
return new SqlDepartment();
}
}; class AccessFactory :public IFactory
{
public:
IUser *createUser()
{
return new AccessUser();
}
IDepartment *createDepartment()
{
return new AccessDepartment();
}
}; /*************************************************************/ class DataAccess
{
private:
static string db;
//string db="access";
public:
static IUser *createUser()
{
if (db == "access")
{
return new AccessUser();
}
else if (db == "sql")
{
return new SqlUser();
}
}
static IDepartment *createDepartment()
{
if (db == "access")
{
return new AccessDepartment();
}
else if (db == "sql")
{
return new SqlDepartment();
}
}
};
string DataAccess::db = "sql"; /*************************************************************/ int main()
{
//IFactory *factory=new SqlFactory();
IFactory *factory;
IUser *user;
IDepartment *department; factory = new AccessFactory();
user = factory->createUser();
department = factory->createDepartment(); user->getUser();
user->setUser();
department->getDepartment();
department->setDepartment(); user = DataAccess::createUser();
department = DataAccess::createDepartment(); user->getUser();
user->setUser();
department->getDepartment();
department->setDepartment(); return 0;

运行结果:


抽象工厂模式的优缺点

优点:(1)易于切换产品系列,由于具体工厂类在一个应用中只需要在初始化的时候出现一次,使得改变具体工厂非常容易。(2)具体的创建实例过程与客户端分离,客户端通过他们的抽象接口操纵实例,产品的具体类名也被具体工厂的实现分离,不会出现在客户端代码中。---充分运用了开放封闭原则和依赖倒转原则。

缺点:(2)根据上例,抽象工厂模式可以很方便地切换两个数据库访问的代码,但是如果你的需求来自增加功能,比如增加项目表Project,就至少需要增加三个雷,IProject、SqlserverProject、AccessProject,而且还要更改IFactory、SqlserverFactory和AccessFactory才行。

优化

(1)用简单工厂来改进抽象工厂

参考文献:

《C++设计模式》

《大话设计模式》

可推荐博客:C++设计模式——抽象工厂模式

c++实现反射

C++实现反射机制

 

设计模式之抽象工厂模式(附带类似反射功能的实现/c++)的更多相关文章

  1. 设计模式:抽象工厂模式(Abstract Factory)

    定   义:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类. 结构图: 示例结构图: 实体类: class User { public int Id { get; set; } p ...

  2. 乐在其中设计模式(C#) - 抽象工厂模式(Abstract Factory Pattern)

    原文:乐在其中设计模式(C#) - 抽象工厂模式(Abstract Factory Pattern) [索引页][源码下载] 乐在其中设计模式(C#) - 抽象工厂模式(Abstract Factor ...

  3. 桥接模式及C++实现 C++设计模式-AbstractFactory抽象工厂模式

    桥接模式及C++实现 桥接模式 先说说桥接模式的定义:将抽象化(Abstraction)与实现化(Implementation)分离,使得二者可以独立地变化. 桥接模式号称设计模式中最难理解的模式之一 ...

  4. Java 设计模式之抽象工厂模式(三)

    原文地址:Java 设计模式之抽象工厂模式(三) 博客地址:http://www.extlight.com 一.前言 上篇文章 <Java 设计模式之工厂模式(二)>,介绍了简单工厂模式和 ...

  5. 【设计模式】抽象工厂模式 Abstract Factory Pattern

    简单工厂模式是一个工厂类根据工厂方法的参数创建不出不同的产品, 工厂方法模式是每一个产品都有一个一一对应的工厂负责创建该产品.那么今天要讲的抽象工厂模式是一个工厂能够产生关联的一系列产品.抽象工厂模式 ...

  6. java设计模式之抽象工厂模式

    上一篇文章(http://www.cnblogs.com/liaoweipeng/p/5768197.html)讲了简单工厂模式,但是简单工厂模式存在一定的问题,如果想要拓展程序,必须对工厂类进行修改 ...

  7. php设计模式之抽象工厂模式

    之前总结了一下工厂模式,其实准确地说是简单 工厂模式,在它的基础上再进行抽象就可以得到一种新的模式:抽象工厂模式. 专业一点的定义为: 抽象工厂模式(Abstact Factory)是一种常见的软件设 ...

  8. (@WhiteTaken)设计模式学习——抽象工厂模式

    抽象工厂模式,可以向客户端提供一个接口,而客户端不用指定具体的类型创建对象,却能够创建多个产品族(一类具有共性产品,如地域等)的对象. 下面直接上代码. 1.苹果需要实现水果的接口,而苹果可以有北方的 ...

  9. 再起航,我的学习笔记之JavaScript设计模式06(抽象工厂模式)

    我的学习笔记是根据我的学习情况来定期更新的,预计2-3天更新一章,主要是给大家分享一下,我所学到的知识,如果有什么错误请在评论中指点出来,我一定虚心接受,那么废话不多说开始我们今天的学习分享吧! 前两 ...

随机推荐

  1. the security of smart contract- 2

    出处:https://cloud.tencent.com/developer/article/1192548 深度解析Solidity的17个坑及超详细避坑指南 写的很好,好好学习 1. Re-Ent ...

  2. 如何优雅地使用Sublime Text3(转)

    转自http://www.jianshu.com/p/3cb5c6f2421c/ Sublime Text:一款具有代码高亮.语法提示.自动完成且反应快速的编辑器软件,不仅具有华丽的界面,还支持插件扩 ...

  3. 深入springboot原理——动手封装一个starter

    从上一篇文章<深入springboot原理——一步步分析springboot启动机制(starter机制)> 我们已经知道springboot的起步依赖与自动配置的机制.spring-bo ...

  4. 3902-luogu 最长不下降子区间

    题目 现有数列A1,A2,…An ,修改最少的数字,使得数列严格单调递增. 依旧是书上的题 但是书上的范围比较小 而 lg上的数据范围很大 按书上的 方法 是会超时 只能过一半的数据 但是 算法思路还 ...

  5. <操作系统>内存管理

    单道程序设计:内存被划分为两部分:一部分供操作系统使用,另一部分供当前正在执行的程序使用. 多道程序设计:内存中进一步细分用户部分,以满足多个进程的要求. 内存管理的需求: 重定位:程序从磁盘换入内存 ...

  6. Win10上运行Docker

    1. 前言 Docker最近推出了可以运行在Win10和Mac上的稳定版本,让我们赶紧来体验一下. Docker发布Mac和Windows 的目标非常简单——开发者可以更加简单方便地在研发机器上使用D ...

  7. 解析 STM32 的库函数

    解析 STM32 的库函数意法半导体在推出 STM32 微控制器之初,也同时提供了一套完整细致的固件开发包,里面包含了在 STM32 开发过程中所涉及到的所有底层操作.通过在程序开发中引入这样的固件开 ...

  8. github打开慢,甚至打不开

    有人使用github后,在某些网络下发现打开慢,甚至打不开,这都是因为他是国外站:目前互联网的连接机制导致超过一定的路由节点的连接就会出现这个问题,解决办法就是直接告诉本机ip.不要先层层询问域名转i ...

  9. BZOJ3926 ZJOI2015 诸神眷顾的幻想乡 Trie、广义SAM

    传送门 树上的任意一条路径一定会在以某一个叶子节点为根的树上成为一条直上直下的链,而总共只有\(20\)个叶子节点. 于是每一次选所有叶子节点中的一个作为根,形成一个\(Trie\),把\(20\)个 ...

  10. 创建一个Scalar-valued Function函数来实现LastIndexOf

    昨天有帮助网友解决的个字符串截取的问题,<截取字符串中最后一个中文词语(MS SQL)>http://www.cnblogs.com/insus/p/7883606.html 虽然实现了, ...