设计模式之工厂模式学习
来源:互联网 发布:广告设计和美工的区别 编辑:程序博客网 时间:2024/06/04 19:40
与简单工厂模式相比,工厂模式为每个类增加了一个工厂类。每个工厂类返回它所对应的类的对象指针。
简单工厂模式的最大优点:工厂类中包含了必要的逻辑判断。根据客户端的选择条件动态的实例化相关的类。没有在客户端实现判断,也就去除了与客户端的依赖。
简单工厂模式实现计算类结构图:
工厂模式实现计算类结构图:
工厂模式实现代码:
#include<iostream>using namespace std;class Operation{public: double num1; double num2;public: Operation(double n1,double n2) { num1=n1; num2=n2; } virtual double calculate()=0;};class AddOperation:public Operation{public: AddOperation(double n1,double n2) :Operation(n1,n2) { } virtual double calculate() { return num1+num2; }};class SubOperation:public Operation{public: SubOperation(double n1,double n2) :Operation(n1,n2) { } virtual double calculate() { return num1-num2; }};class Factory{public: double n1; double n2;public: Factory(double n1,double n2) { this->n1=n1; this->n2=n2; } virtual Operation *CreateOperation()=0;};class AddFactory:public Factory{ public: AddFactory(double n1,double n2) :Factory(n1,n2) { } virtual Operation*CreateOperation() { return new AddOperation(n1,n2); }};class SubFactory:public Factory{ public: SubFactory(double n1,double n2) :Factory(n1,n2) { } virtual Operation*CreateOperation() { return new SubOperation(n1,n2); }};int main(int argc,char**argv){double n1,n2;cin>>n1>>n2;cout<<AddFactory(n1,n2).CreateOperation()->calculate()<<endl;cout<<SubFactory(n1,n2).CreateOperation()->calculate()<<endl; return 0;}
对于简单工厂模式而言,如果需要添加新的计算功能类,如乘方类,就需要在简单工厂类中添加case分支条件,修改了原来的类,这违背了开放封闭原则。基于此引入了工厂模式。
工厂模式:定义一个用于创建对象的接口,让子类决定实例化那个类。工厂方法模式是一个类的实例化延迟到其子类。此时整个结构没有修改的变化,只是有扩展的变化。这完全符合开放封闭原则。但工厂方法实现时,客户端就需要判断实例化哪个工厂来实现运算类。选择判断仍然是必须的,工厂方法模式将简单工厂内部的逻辑判断移到了客户端进行判断。
对于大话设计模式中的雷锋工厂的例子。使用简单工厂模式时,每次实例化学生类或是志愿者类时,都需要简单工厂类的代码。在使用工厂模式时,会为每个雷锋类派生类,如学生类和志愿者类,都创建一个工厂类,用于生成该类所对应的对象。增加类时,只需要增加代码就可以了。很好的体现了开放封闭原则。
工厂类与简单工厂类实现雷锋工厂代码对比:
#include<iostream>using namespace std;class LeiFeng{public: LeiFeng() { } virtual void sweep()=0; virtual void wash()=0; virtual void buyRice()=0;};class Student:public LeiFeng{public: Student() { } virtual void sweep() { std::cout<<"this student is sweeping now"<<std::endl; } virtual void wash() { std::cout<<"this student is washing now"<<std::endl; }virtual void buyRice(){std::cout<<"this student is buying rice now"<<std::endl;} };class Volunteer:public LeiFeng{public: Volunteer() { } virtual void sweep() { std::cout<<"this Volunteer is sweeping now"<<std::endl; } virtual void wash() { std::cout<<"this Volunteer is washing now"<<std::endl; }virtual void buyRice(){std::cout<<"this Volunteer is buying rice now"<<std::endl;} };class SimpleFactory{public: LeiFeng *lf;public: SimpleFactory() { lf=NULL; } LeiFeng* createLeiFeng(int type) { switch(type) { case 1: { lf=new Student; } break; case 2: { lf=new Volunteer; } break; } return lf; }};class IFactory{public: IFactory() { } virtual LeiFeng*CreateLeiFeng()=0; };class StudentFactory:public IFactory{public: StudentFactory() { } virtual LeiFeng*CreateLeiFeng() { return new Student; } };class VolunteerFactory:public IFactory{public: VolunteerFactory() { } virtual LeiFeng*CreateLeiFeng() { return new Volunteer; } };int main(int argc,char**argv){LeiFeng *lf;/*SimpleFactory *sf=new SimpleFactory;lf=sf->createLeiFeng(1);lf->sweep();lf->wash();lf->buyRice();lf=sf->createLeiFeng(2);lf->sweep();lf->wash();lf->buyRice();*/lf=(new StudentFactory)->CreateLeiFeng();lf->sweep();lf->wash();lf->buyRice();lf=(new VolunteerFactory)->CreateLeiFeng();lf->sweep();lf->wash();lf->buyRice();return 0;}
工厂模式克服了简单工厂模式违背开放封闭原则,保持了封装对象创建过程的优点。要更换对象时不需要做大的改动即可实现,降低了客户程序与产品对象的耦合度。
- 设计模式入门学习之工厂模式(工厂方法模式)
- 设计模式入门学习之工厂模式(工厂方法模式)
- 设计模式学习之工厂模式(简单工厂模式)
- 设计模式学习之简单工厂模式和工厂模式
- 设计模式入门学习之工厂模式
- 设计模式学习笔记之工厂模式
- 设计模式学习之简单工厂模式
- 设计模式学习之工厂模式
- 设计模式 学习之工厂方法模式
- 设计模式之简单工厂模式学习
- 设计模式之工厂模式学习
- 设计模式之抽象工厂模式学习
- 设计模式学习笔记之工厂模式
- 学习笔记:设计模式之工厂模式
- JAVA学习.设计模式之工厂模式
- 设计模式学习之简单工厂模式
- 设计模式学习之简单工厂模式
- Java设计模式学习之工厂模式
- 把二元查找树转变成排序的双向链表
- VS2010中的调试技巧
- ELisp编程十三:宏二
- 配置tomcat通过doget servlet 方法 向jquery脚本发送json格式数据
- Vendor master data
- 设计模式之工厂模式学习
- 开篇
- Sping in Action读书笔记之一----------Bean的各种注入操作
- Linux解压缩指令大全
- 按照RFC3984协议实现H264视频流媒体 RTSP H264
- convert , transform , transfer , transmit ,transit 的区别
- Perl中的向后引用
- gcc常用的编译选项对代码的影响
- 1IOCP背景知识--重叠I/O理解