为什么要用设计模式?根本原因是为了代码复用,增加可维护性。

  面向对象设计坚持的原则:开闭原则(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)的更多相关文章

  1. 设计模式二: 工厂方法(Factory Method)

    简介 工厂方法模式是创建型模式的一种, 核心结构有四个角色: 抽象工厂,具体工厂,抽象产品,具体产品; 实现层面上,该模式定义一个创建产品的接口,将实际创建工作推迟到具体工厂类实现, 一个产品对应一个 ...

  2. 抽象工厂(Abstract Factory),工厂方法(Factory Method),单例模式(Singleton Pattern)

    在谈工厂之前,先阐述一个观点:那就是在实际程序设计中,为了设计灵活的多态代码,代码中尽量不使用new去实例化一个对象,那么不使用new去实例化对象,剩下可用的方法就可以选择使用工厂方法,原型复制等去实 ...

  3. Spring 通过工厂方法(Factory Method)来配置bean

    Spring 通过工厂方法(Factory Method)来配置bean 在Spring的世界中, 我们通常会利用bean config file 或者 annotation注解方式来配置bean. ...

  4. 设计模式——工厂方法(Factory Method)

    定义一个用于创建对象的接口,让子类决定实例化哪一个类.工厂方法使一个类的实例化延迟到其子类. ——DP UML类图 模式说明 抽象业务基类 实际业务类的公共基类,也是工厂要创建的所有对象的父类,这部分 ...

  5. 浅谈Python设计模式 - 抽象工厂模式

    声明:本系列文章主要参考<精通Python设计模式>一书,并且参考一些资料,结合自己的一些看法来总结而来. 在上一篇我们对工厂模式中的普通工厂模式有了一定的了解,其实抽象工作就是 表示针对 ...

  6. 浅谈php设计模式(1)---工厂模式

    一.接口继承直接调用 先看看这样一段代码: <?php interface db{ function conn(); } class dbmysql implements db { public ...

  7. [设计模式-创建型]工厂方法(Factory Method)

    概括 名称 Factory Method 结构 动机 定义一个用于创建对象的接口,让子类决定实例化哪一个类.Factory Method 使一个类的实例化延迟到其子类. 适用性 当一个类不知道它所必 ...

  8. 设计模式 笔记 工厂方法 Factory Methon

    //---------------------------15/04/09---------------------------- //factory method 工厂方法-------对象创建型模 ...

  9. Headfirst设计模式的C++实现——工厂方法(Factory Method)

    引用原书的一句话:所有的工厂模式都用来封装对象的创建,工厂方法模式通过让子类决定该创建的对象是什么来达到封装的目的. Pizza类及其派生类与上一例相同 PizzaStore.h #ifndef _P ...

随机推荐

  1. padding下中英文左右两端对齐

    <!DOCTYPE html> <html> <head> <meta charset='UTF-8'> <title>helo</t ...

  2. C#如何实现一个简单的流程图设计器

    以前看过不少Window Form开发的流程图设计器,支持节点拖放,非常方便即可设计出很美观的流程图,作为一个程序员,对其内部实现原理一直很好奇,感叹有朝一日自己如果可以开发一款类似的软件那是多么让人 ...

  3. BasicModal - 简单易用的现代 Web App 弹窗

    BasicModal 是为现代 Web 应用程序打造的弹窗系统.它包括所有你需要显示的信息,问题或接收用户的输入.这里的弹窗还可以链接起来,所以你可以很容易地建立一个预定义顺序的安装帮助或显示对话框. ...

  4. 推荐几个jQuery插件

    jQuery仿京东无限级菜单HoverTree http://www.cnblogs.com/jihua/p/hvtree.html 多级弹出菜单jQuery插件ZoneMenu http://www ...

  5. 性能更好的js动画实现方式——requestAnimationFrame

    用js来实现动画,我们一般是借助setTimeout或setInterval这两个函数,css3动画出来后,我们又可以使用css3来实现动画了,而且性能和流畅度也得到了很大的提升.但是css3动画还是 ...

  6. 【追寻javascript高手之路03】javascript对象大乱斗

    前言 昨天我们学习了下javascript中函数的参数与作用域的东东,现在回过头来看,其实都是与函数相关的,所以javascript中的函数仍然是王道,我们今天大概会发二篇或者三篇博客一起来巩固我们的 ...

  7. JavaScript中的普通函数与构造函数比较

    问题 什么是构造函数?构造函数与普通函数区别是什么?用new关键字的时候到底做了什么?构造函数有返回值怎么办?构造函数能当普通函数调用吗? thisthis永远指向当前正在被执行的函数或方法的owne ...

  8. ng-cordova 手机拍照或从相册选择图片

    1.需求描述 实现一个调用摄像头拍照,或者直接打开本地图库选择照片,然后替换App中图片的功能 2.准备 1) 安装ng-cordova 进入到ionic工程目录,使用bower工具安装, bower ...

  9. Linux学习心得之 jnlp的文件和java应用程序安全设置

    作者:枫雪庭 出处:http://www.cnblogs.com/FengXueTing-px/ 欢迎转载 jnlp的文件和java应用程序安全设置 1.前言2. jnlp的文件打开3.java应用程 ...

  10. 服务 {49A27252-A326-4EF1-B698-6EBC7068833C} 的计时器作业 id {573BE459-DF82-481C-84BD-CA14D287450B} 配置刷新的上一个实例仍在运行,因此将跳过当前的实例。请考虑增加作业之间的时间间隔。

    在SharePoint2007的错误日志中发现大量如下错误: 07/02/2013 16:17:25.99     OWSTIMER.EXE (0x0958)     0x097C    Window ...