通用工厂类Factory(C++实现)
灵光一闪:
class Button{};class LinuxButton : public Button{};class WindowsButton: public Button{};class AbstractFactory{public:Button* create Button() = 0;};class LinuxConcreteFactory : public AbstractFactory{public:Button* createButton(){return new LinuxButton ;}};class WindowsConcreteFactory : public AbstractFactory{pulbic:Base *createBase(){return new WindowsButton;}};
- 有新产品类时,要修改AbstractFactory的接口,同时要改变所有具体工厂去实现新的创建对象函数。比如,现在要加一个Label的控件,那么会有Label、LinuxLabel和WindowsLabel类。这时就要去修改AbstractFactory的接口,然后所有实现类都要去实现新的函数。
- 要记住每个类创建对象的对应函数,当然,名字取得得当,这不是问题,就像上面的例子一样,对于类Button,创建一个createButton的函数。
- 当要使用这个工厂创建对象的类非常多时,这时工厂的接口就非常大。
- 当具体工厂的个数比较多时,这样实现具体工厂就更加麻烦。比如,这时要加上Mac系统的控件,此时就得去新建一个MacConcreteFactory的类,并去继承AbstractFactory类,然后实现所以函数。
Button* createLinuxButton(){return new LinuxButton;}Button *createWindowsButton(){return new WindowsButton;}class ButtonFactoryEx{public:void registerClass(const string &name, Button* (*callback)()){cm[name] = callback;}Button* create(const string &name){CreateMap::iterator it = cm.find(name);if (it != cm.end()){return (*(it->second))();}else{return NULL;}}// ...省略一些其他不用介绍的函数,可以参考《C++ API设计》private:typedef Button* (*CreateCallback)();typedef map<string, CreateCallback> CreateMaps;CreateMaps cm;};
ButtonFactoryEx factory;factory.registerClass("linux", createLinuxButton);factory.registerClass("windows", createWindowsButton);factory.create("linux"); // 产生Linux的buttonfactory.create("windows"); // 产生windows的button
- 对于不同的产品类,要使用不同的工厂,使工厂类个数膨胀。比如,现在要加一个Label的类,那么就要弄一个LabelFactoryEx的工厂。
- 如果传了没有注册进行的字符串去创建对象,或者拼错字符串了,比如"linux"拼成了"linus",那么将会返回NULL。这要运行时才能知道错误,而不是编译期。
- 在运行期要先注册类到工厂。
- 要管理多个不同的工厂对象。这是一个比较严重的问题。如果没管理好,在其他的模块中将访问不了这个对象,那么这个工厂就没有用了。
- 所有的产品类要继承Object。如果这个产品类已经写好了,或者这个产品类不是你写的,你只有这个类的库,没有源代码,不能改接口,那怎么办?即使可以修改这个类的设计,但是所有的产品都继承Object将会很繁琐。修改已经存在的类还可能会引起已存在的代码产生新的问题。
- 是使用dynamic_cast会使系统的运行效率严重降低。
class Factory{public:template <typename ReturnType>bool registerClass(const string &name, ReturnType* (*createCallback)());template <typename ReturnType>ReturnType* produce(const string &name);// ...};
class Factory{public:// 接上面的类设计private:enum HandleType {GET, ADD};template <typename ReturnType>bool callback_container(const string, ReturnType* (**createCallback), HandleType type){typedef ReturnType* (*Callback)();typedef map<string, Callback> CallbackMap;static CallbackMap cm;}};
Factory linuxFactory;linuxFactory.registerClass<Button>("button", createLinuxButton);linuxFactory.registerClass<Label>("label", createLinuxLabel); // 假设设计了这个类和回调函数Factory windowsFactory;windowsFactory.registerClass<Button>("button", createWindowsButton);windowsFactory.registerClass<Label>("label", createWindowsLabel); // 假设设计了这个类和回调函数// 产生Linux的buttonlinuxFactory.produce<Button>("button");// 产生Linux的LabellinuxFactory.produce<Label>("label");
- 运行期要先注册回调函数到工厂。
- 不存在的名字或拼错的名字去创建。
static Factory& Factory::instance(const string &name);
#define LINUX_FACTORY Factory::instance("linux")#define WIN_FACTORY Factory::instance("windows")LINUX_FACTORY.registerClass<Button>("button", createLinuxButton);LINUX_FACTORY.registerClass<Label>("label", createLinuxButton);WIN_FACTORY.registerClass<Button>("button", createWindowsButton);WIN_FACTORY.registerClass<Label>("label", createWindowsLabel);LINUX_FACTORY.produce<Button>("button");LINUX_FACTORY.produce<Label>("label");
- 运行期要先注册回调函数到工厂。
- 不存在的名字或拼错的名字去创建。
通用工厂类Factory(C++实现)相关推荐
- JavaWeb学习篇——使用通用工厂类解耦MVC框架
通过使用经典的MVC(model.view.controller)三层开发框架,可以使我们的项目结构更符合模块化的特点,各层(web.service.dao)只负责本层最擅长的工作.当某一层的业务逻辑 ...
- 设计模式 - 学习笔记 - 工厂模式Factory Pattern
设计模式 - 学习笔记 - 工厂模式Factory Pattern 1. 简单工厂 1.1 应用场景 1.2 UML 1.3 优劣分析 好处 缺点 1.4 代码示例 抽象产品 AbstractProd ...
- 类对象工厂设计模式(Factory Pattern)
本文朋友在深圳逛街的时候突然想到的...这段时间就有想写几篇关于类对象的笔记,所以回家到之后就奋笔疾书的写出来发布了 提供了比工厂模式更高一级的接口级,用于返回若个工厂之一.这个模式是属于创立模式之一 ...
- 【java设计模式】之 工厂(Factory)模式
1.工厂模式的定义 工厂模式使用的频率很高.我们在开发中总能见到它们的身影.其定义为:Define an interface for creating an object, but let subcl ...
- 设计模式之工厂类模式总结对比、简单工厂模式、工厂方法模式、抽象工厂模式、带反射的工厂模式、例子代码分析、最详细
1. 题目 假设某公司同时用SqlServer.MySql数据库,即会切换两数据库(不同数据库的sql语句有些许差异),同时,两数据库里均有对Users.Departments表的操作(sql代码不一 ...
- Spring 通过工厂方法(Factory Method)来配置bean
在spring的世界中, 我们通常会利用bean config file 或者 annotation注解方式来配置bean. 在第一种利用bean config file(spring xml)方式中 ...
- java的工厂类_深入理解Java的三种工厂模式
一.简单工厂模式 简单工厂的定义:提供一个创建对象实例的功能,而无须关心其具体实现.被创建实例的类型可以是接口.抽象类,也可以是具体的类 实现汽车接口 1 public interfaceCar {2 ...
- 设计模式(一)工厂模式Factory(创建型)
设计模式一 工厂模式Factory 在面向对象编程中, 最通常的方法是一个new操作符产生一个对象实例,new操作符就是用来构造对象实例的.但是在一些情况下, new操作符直接生成对象会带来一些问题. ...
- Spring 创建对象的问题,不同构造方法创建对象,使用工厂类类获取对象、单例或多例、延迟创建问题
创建实体类Student package star.july.b_ioc; public class Student {private String name;private int age;publ ...
最新文章
- pycharm 链接wsl和 wsl 配置cuda nvidia
- 如何隐藏iPhone导航栏上的“后退”按钮?
- 弹出窗口显示输出内容_前端加油站(3)-JavaScript 输出
- mysql安装check requirements出错_超详细的MySQL8.0.17版本安装教程
- position absolute定位之所属的containing box
- iPhone清理喇叭灰尘_厉害了!原来可以这样一键清理 iPhone 喇叭灰尘!
- Lunix git stash clear 或者 git stash drop后恢复的方法
- GAN生成的人脸数据集
- c语言炒股软件公式,股票软件怎么使用指标选股公式
- 用计算机怎么弹星辰大海,【计算机学院】你们的征途将是星辰大海~
- python实现报表的分组统计_Python 分组处理
- 几款制作网页线框图的软件介绍
- ICPC North Central NA Contest 2017 H.Zebras and Ocelots
- 编写批量修改扩展名脚本
- FileZilla ftp传输文件报错: 响应:550 Create directory operation failed.
- Mac电脑最强截图工具--iShot
- MySQL高级篇——日志
- 索骥馆-网络创业之《网上赚钱从入门到精通》扫描版[PDF]
- Google 百度 图标收藏(三)
- 计算机程序员的英文简历,电脑程序员英文简历范文