问题描述

假设我们要开发一款游戏, 当然为了吸引更多的人玩, 游戏难度不能太大(让大家都没有信心了,估计游戏也就没有前途了),但是也不能太简单(没有挑战性也不符合玩家的心理)。于是我们就可以采用这样一种处理策略: 为游戏设立等级,初级、中级、高级甚至有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. [从产品角度学excel 04]-单元格的“衣服”

    忘记发这里了..补发一下 这是<从产品角度学EXCEL>系列——单元格篇. 前言请看: 0 为什么要关注EXCEL的本质 1 excel是怎样运作的 2 EXCEL里的树形结构 3 单元格 ...

  2. rails再体验(第一个程序)

    掌握redmine plugin开发的目标在2016年未实现,2017年继续. 选择<Ruby on Rails Tutorial>教程,windows安装railsinstaller,该 ...

  3. 数据库热备之SQLServer的数据库镜像实施笔记

    / 最初在为公司设计SQLServer数据库镜像的时候,首先考虑的是高可用性(三台计算机,一台见证服务器,一台做主数据库,一台做镜像) 在虚拟机环境下部署成功,一切都是那么的完美.故障转移3秒之内就可 ...

  4. Agile.Net 组件式开发平台 - 内核管理组件

    敏捷开发体系   软件构件技术:所谓软件构件化,就是要让软件开发像机械制造工业一样,可以用各种标准和非标准的零件来进行组装.软件的构件化和集成技术的目标是:软件系统可以由不同厂商提供的,用不同语言开发 ...

  5. 全新 D 系列虚拟机型号

    Kenaz KwaAzure计算运行时项目经理 今天,我们宣布将发布名为D系列的Windows Azure 新VM型号,并支持虚拟机和 Web/Worker Role.这些虚拟机型号最多可以提供 11 ...

  6. Asp.net 4.0,首次请求目录下的文件时响应很慢

    原文:Asp.net 4.0,首次请求目录下的文件时响应很慢 1. 问题起因2. 尝试过的处理思路3. 解决方法 1. 问题起因 一个从VS2003(.Net Framework 1.1)升级到.ne ...

  7. Java的迭代和foreach循环

    Java的迭代(interation statement) Java的迭代(interation statement) 其实就是循环控制语句while.do-while和for,因为他们会从重复地运行 ...

  8. java中log的应用

    log的简单应用 备忘 加入jar包commons-logging-1.1.jar log4j.properties 如下(就放在src根目录底下 名字和位置都不要变) #OFF.FATAL.ERRO ...

  9. 在.NET Core使用TimeZone将客户端时间转服务器本地时间但编译提示已过期

    当我们的项目国际化后,需要处理时区问题. 在.NET Core之前我们可以通过以下代码将客户端时间转换为服务端时间: DateTime serverTime = TimeZone.CurrentTim ...

  10. json_decode与json_encode容易被忽视的点

    一.json_decode的使用,json_decode共有4个参数 json_decode ( string $json [, bool $assoc=FALSE [, int $depth= 51 ...