浅谈C++设计模式之工厂方法(Factory Method)
为什么要用设计模式?根本原因是为了代码复用,增加可维护性。
面向对象设计坚持的原则:开闭原则(Open Closed Principle,OCP)、里氏代换原则(Liskov Substitution Principle,LSP)、依赖倒转原则(Dependency Inversion Principle,DIP)、接口隔离原则(Interface Segregation Principle,ISP)、合成/聚合复用原则(Composite/Aggregate Reuse Principle,CARP)、最小知识原则(Principle of Least Knowledge,PLK,也叫迪米特法则)
- 开闭原则:模块应该对扩展开放,而对修改关闭。也就是说,在不修改原来的代码的前提下进行扩展。
- 里氏代换原则:如果调用的是父类的话,那么换成子类也完全没有问题。
- 依赖倒转原则:尽量针对接口编程,而不是针对实现编程。通过抽象父类的指针来调用子类的实现。
- 接口隔离原则:每个接口应该只有一种角色,多个角色应该用多个接口来实现。
- 合成/聚合复用:在新的对象中尽量使用已有的对象,使新对象向这些对象委派来达到复用已有功能的目的,而不是通过继承来实现。
- 最少知识原则:一个对象应对其它对象有尽可能少的了解。
上述的这些原则也正是体现了OOP高内聚、低耦合的基本原则,最终目的都是为了代码复用,增加可维护性。设计模式就是本着这些原则来进行OOP设计的一些方法。
设计模式开篇先来介绍工厂方法(Factory Method)模式
对象创建型模式的一种。工厂方法是定义一个用于创建对象的接口,让子类决定实例化哪一个类,让一个类的实例化延迟到它的子类中。
- 客户Client
- 工厂接口Creator
- 工厂实现类ConcreteCreatorP1和ConcreteCreatorP2
- 产品接口Product
- 产品实现类ConcreteProductP1和ConcreteProductP2

上面是工厂方法模式的类图。
首先我们有两个产品ProductP1和ProductP2,我们现在要生产这两个产品,这两个产品特征如下:
(1) start(); 启动
(2) execute(); 运行
(3) quit(); 退出
只是启动过程不同,运行过程不同,退出也不同。
那么工厂方法模式是如何实现得到这两个产品的对象的呢??通过上面的类图其实我们就可以大概知道了,工厂方法大致实现过程。有几个产品,就对应着有几个工厂,每个工厂负责生产对应的产品。所有工厂都实现了同一个工厂接口Creator。而所有的产品也都实现了同一个产品的接口Product。
- Product(定义工厂方法所创建的对象的接口,也就是产品的接口)
class Product{
Product(){};
~Product(){};
virtual void start()=;
virtual void execute()=;
virtual void quit()=;
};
- ConcreteProduct(实现Product接口,也就是每个产品具体的实现方法,这里有两个产品ConcreteProductP1和ConcreteProductP2)
/**************************产品1*******************************/
class ConcreteProductP1:public Product{
ConcreteProductP1(){};
~ConcreteProductP1(){};
void start();
void execute();
void quit();
};
ConcreteProductP1::start(){
cout<<"<<----------P1 启动---------->>"<<endl;
}
ConcreteProductP1::execute(){
cout<<"<<----------P1 执行---------->>"<<endl;
}
ConcreteProductP1::quit(){
cout<<"<<----------P1 退出---------->>"<<endl;
}
/*************************产品2********************************/
class ConcreteProductP2:public Product{
ConcreteProductP2(){};
~ConcreteProductP2(){};
void start();
void execute();
void quit();
};
ConcreteProductP2::start(){
cout<<"<<----------P2 启动---------->>"<<endl;
}
ConcreteProductP2::execute(){
cout<<"<<----------P2 执行---------->>"<<endl;
}
ConcreteProductP2::quit(){
cout<<"<<----------P2 退出---------->>"<<endl;
}
Creator(声明工厂方法,该方法返回一个Product类型的对象;Creator也可以定义一个工厂方法的缺省实现,它返回一个缺省的ConcreteProduct对象,可以调用工厂方法以创建一个Product对象)
class Creator{
public:
Creator(){};
~Creator(){};
virtual Product* createProduct()=;
};- ConcreteCreator(重定义工厂方法以返回一个ConcreteProduct实例,这里有两个工厂实现类,各自对应上面的两个产品)
/*************************工厂1生成产品1**************************/
class ConcreteCreatorP1:public Creator{
public:
ConcreteCreatorP1(){};
~ConcreteCreatorP1(){};
Product* createProduct();
};
Product* ConcreteCreatorP1::createProduct(){
return new ConcreteProductP1();
} /*************************工厂2生成产品2**************************/
class ConcreteCreatorP2:public Creator{
public:
ConcreteCreatorP2(){};
~ConcreteCreator()P2{};
Product* createProduct();
};
Product* ConcreteCreatorP2::createProduct(){
return new ConcreteProductP2();
}
- Client (这里使用的是main函数)
int main(){
Creator *factory = new ConcreteCreatorP1();
Product *p1 = factory.createProduct();
p1.start(); //p1是这样启动的
p1.execute(); //p1是这样运行的
p1.quit(); //p1是这样结束的 Creator *factory = new ConcreteCreatorP2();
Product *p2 = factory.createProduct();
p2.start(); //p2是这样启动的
p2.execute(); //p2是这样运行的
p2.quit(); //p2是这样结束的 return ;
}
工厂方法很简单,经常作为一种标准的创建对象的方法。但是缺点就是可能仅仅是为了改变产品类,就可能需要创建一个新的类,也就是说当被实例化的类根本不发生变化或当实例化出现在子类可以很容易重定义的操作中,重新创建一个工厂类就显得太浪费了。
版权所有,欢迎转载,转载请注明出处。
浅谈C++设计模式之工厂方法(Factory Method)的更多相关文章
- 设计模式二: 工厂方法(Factory Method)
简介 工厂方法模式是创建型模式的一种, 核心结构有四个角色: 抽象工厂,具体工厂,抽象产品,具体产品; 实现层面上,该模式定义一个创建产品的接口,将实际创建工作推迟到具体工厂类实现, 一个产品对应一个 ...
- 抽象工厂(Abstract Factory),工厂方法(Factory Method),单例模式(Singleton Pattern)
在谈工厂之前,先阐述一个观点:那就是在实际程序设计中,为了设计灵活的多态代码,代码中尽量不使用new去实例化一个对象,那么不使用new去实例化对象,剩下可用的方法就可以选择使用工厂方法,原型复制等去实 ...
- Spring 通过工厂方法(Factory Method)来配置bean
Spring 通过工厂方法(Factory Method)来配置bean 在Spring的世界中, 我们通常会利用bean config file 或者 annotation注解方式来配置bean. ...
- 设计模式——工厂方法(Factory Method)
定义一个用于创建对象的接口,让子类决定实例化哪一个类.工厂方法使一个类的实例化延迟到其子类. ——DP UML类图 模式说明 抽象业务基类 实际业务类的公共基类,也是工厂要创建的所有对象的父类,这部分 ...
- 浅谈Python设计模式 - 抽象工厂模式
声明:本系列文章主要参考<精通Python设计模式>一书,并且参考一些资料,结合自己的一些看法来总结而来. 在上一篇我们对工厂模式中的普通工厂模式有了一定的了解,其实抽象工作就是 表示针对 ...
- 浅谈php设计模式(1)---工厂模式
一.接口继承直接调用 先看看这样一段代码: <?php interface db{ function conn(); } class dbmysql implements db { public ...
- [设计模式-创建型]工厂方法(Factory Method)
概括 名称 Factory Method 结构 动机 定义一个用于创建对象的接口,让子类决定实例化哪一个类.Factory Method 使一个类的实例化延迟到其子类. 适用性 当一个类不知道它所必 ...
- 设计模式 笔记 工厂方法 Factory Methon
//---------------------------15/04/09---------------------------- //factory method 工厂方法-------对象创建型模 ...
- Headfirst设计模式的C++实现——工厂方法(Factory Method)
引用原书的一句话:所有的工厂模式都用来封装对象的创建,工厂方法模式通过让子类决定该创建的对象是什么来达到封装的目的. Pizza类及其派生类与上一例相同 PizzaStore.h #ifndef _P ...
随机推荐
- 2014年物联网Internet of Things应用简介
body{ font: 16px/1.5em 微软雅黑,arial,verdana,helvetica,sans-serif; } 物联网(Internet of Things,缩写I ...
- 关于jQuery里面的选择器
一.JQuery选择器的概述 选择器是JQuery的根基,在JQuery中,对事件处理.遍历DOM和Ajax操作都依赖于选择器. 二.选择器的优势 1.简洁的语法 2.支持CSS1.0到CSS3.0选 ...
- 七个结构模式之桥接模式(Bridge Pattern)
问题: 当存在多个独立的变化维度时,如果仍采用多层继承结构,会急剧的增加类的个数,因此可以考虑将各个维度分类,使他们不相互影响. 定义: 将抽象部分与它的实现部分进行分离,抽象部分只保留最为本质的部分 ...
- 搭建自己的ngrok服务(国内直接可用http://qydev.com/#)
ngrok 服务可以分配给你一个域名让你本地的web项目提供给外网访问, 特别适合向别人展示你本机的web demo 以及调试一些远程的API (比如微信公众号,企业号的开发) ngrok的官方服务可 ...
- IOS 局域网发送信息
基于ios 例子WiTap 1.创建本地的服务并设置监听时间检测是否有设备连接. NSNetService * server = [[NSNetService alloc] initWithDomai ...
- 请使用java来构造和遍历二叉树?
[分析] 二叉树的结构:根节点.左子树.右子树.其中左子树的值必须小于根节点,右子树的值必须大于根节点.构造这种树结构,就是创建一个类,并提供一个方法,当给定一个值时,它能够自动创建节点并自动挂到二叉 ...
- 总结CSS3新特性(Transform篇)
概述: CSS3新添加的Transform可以改变元素在可视化区域的坐标(这种改变不会引起文档的重排,只有重排),以及形状,还有些3D形变.结合 Animation(这里以后会有个链接的) 能实现酷炫 ...
- Web自动化测试 Selenium 2/3
TesNG和Selenium集成使用 TestNG 是一个设计用来简化广泛的测试需求的测试框架,从单元测试(隔 离测试一个类)到集成测试(测试由有多个类多个包甚至多个外部框架组成的整 个系统,例如运用 ...
- iOS多线程中,队列和执行的排列组合结果分析
本文是对以往学习的多线程中知识点的一个整理. 多线程中的队列有:串行队列,并发队列,全局队列,主队列. 执行的方法有:同步执行和异步执行.那么两两一组合会有哪些注意事项呢? 如果不是在董铂然博客园看到 ...
- Mac本“安全性与隐私”里没有“任何来源”选项
打开"偏号设置"----->"安全性与隐私"----->"通用",里面没有"任何来源",怎么解决? 如果需要 ...