我以计算器为例写一个简单工厂模式,只完成加减乘除4个计算功能,考虑到其他功能方便日后扩展,遵循开放-封闭原则。

简单工厂类图:

先看一下C#的简单工厂是如何实现的:

定义抽象类Operation,加减乘除的实现由子类派生,最后由OperationFactory决定实例化哪一个子类。

  1. namespace OperationLibrary
  2. {
  3. public abstract class Operation
  4. {
  5. private int num_A = ;
  6. public int Num_A
  7. {
  8. get { return num_A; }
  9. set { num_A = value; }
  10. }
  11.  
  12. private int num_B = ;
  13. public int Num_B
  14. {
  15. get { return num_B; }
  16. set { num_B = value; }
  17. }
  18.  
  19. public abstract double getResult();
  20. }
  21.  
  22. public class OperationAdd : Operation
  23. {
  24. public override double getResult()
  25. {
  26. return Num_A + Num_B;
  27. }
  28. }
  29.  
  30. public class OperationSub : Operation
  31. {
  32. public override double getResult()
  33. {
  34. return Num_A - Num_B;
  35. }
  36. }
  37.  
  38. public class OperationMul : Operation
  39. {
  40. public override double getResult()
  41. {
  42. return Num_A * Num_B;
  43. }
  44. }
  45.  
  46. public class OperationDiv : Operation
  47. {
  48. public override double getResult()
  49. {
  50. if (Num_B == )
  51. throw new Exception("除数不能为0");
  52. return Num_A / Num_B;
  53. }
  54. }
  55.  
  56. public class OperationFactory
  57. {
  58. public static Operation createOperate(string operate)
  59. {
  60. Operation oper = null;
  61. switch (operate)
  62. {
  63. case "+":
  64. oper = new OperationAdd();
  65. break;
  66. case "-":
  67. oper = new OperationSub();
  68. break;
  69. case "*":
  70. oper = new OperationMul();
  71. break;
  72. case "/":
  73. oper = new OperationDiv();
  74. break;
  75. }
  76. return oper;
  77. }
  78. }
  79. }

客户端调用:

  1. Operation oper = OperationFactory.createOperate("/");
  2. oper.Num_A = ;
  3. oper.Num_B = ;
  4. oper.getResult(); //

js模拟C#的简单工厂:

  1. var Operation = function(){
  2. this.num_A = this.num_B = 0;
  3. };
  4.  
  5. var OperationAdd = function(){};
  6. OperationAdd.prototype = new Operation();
  7. OperationAdd.prototype.getResult = function(){
  8. return this.num_A + this.num_B;
  9. };
  10.  
  11. var OperationSub = function(){};
  12. OperationSub.prototype = new Operation();
  13. OperationSub.prototype.getResult = function(){
  14. return this.num_A - this.num_B;
  15. };
  16.  
  17. var OperationMul = function(){};
  18. OperationMul.prototype = new Operation();
  19. OperationMul.prototype.getResult = function(){
  20. return this.num_A * this.num_B;
  21. };
  22.  
  23. var OperationDiv = function(){};
  24. OperationDiv.prototype = new Operation();
  25. OperationDiv.prototype.getResult = function(){
  26. if(this.num_B == 0)
  27. throw new Error('除数不能为0');
  28. return this.num_A / this.num_B;
  29. };
  30.  
  31. var OperateFactory = function(){};
  32. OperateFactory.createOperate = function(operate){
  33. var oper;
  34. switch(operate){
  35. case "+":
  36. oper = new OperationAdd();
  37. break;
  38. case "-":
  39. oper = new OperationSub();
  40. break;
  41. case "*":
  42. oper = new OperationMul();
  43. break;
  44. case "/":
  45. oper = new OperationDiv();
  46. break;
  47. }
  48. return oper;
  49. };
  50.  
  51. //调用:
  52. var oper = OperateFactory.createOperate('+');
  53. oper.num_A = 1;
  54. oper.num_B = 2;
  55. alert(oper.getResult()); //

js完全照搬C#的模式显然太复杂,根据js语言的特性实现一个:

  1. var Operation = function(){
  2. this.num_A = this.num_B = 0;
  3. };
  4. Operation.prototype.OperationAdd = function(){
  5. return this.num_A + this.num_B;
  6. };
  7. Operation.prototype.OperationSub = function(){
  8. return this.num_A - this.num_B;
  9. };
  10. Operation.prototype.OperationMul = function(){
  11. return this.num_A * this.num_B;
  12. };
  13. Operation.prototype.OperationDiv = function(){
  14. if(this.num_B == 0)
  15. throw new Error('除数不能为0');
  16. return this.num_A / this.num_B;
  17. };

  18. //策略
  19. var operateStrategy = {
  20. '+':'OperationAdd',
  21. '-':'OperationSub',
  22. '*':'OperationMul',
  23. '/':'OperationDiv'
  24. };
  25.  
  26. //工厂
  27. var OperateFactory = (function(){
  28.  
  29. var oper;
  30.  
  31. return function(operate){
  32.  
  33. //只实例化一次
  34. oper = oper || new Operation();
  35.  
  36. return {
  37. setNumber:function(a,b){
  38. oper.num_A = a;
  39. oper.num_B = b;
  40. },
  41. getResult:function(){
  42. var fName = operateStrategy[operate],
  43. fun = oper[fName] || function(){};
  44. return fun.call(oper);
  45. }
  46. };
  47. };
  48. })();
  49.  
  50. //调用:
  51. var oper = OperateFactory('+');
  52. oper.setNumber(1,3);
  53. alert(oper.getResult());
  54.  
  55. oper = OperateFactory('*');
  56. oper.setNumber(2,3);
  57. alert(oper.getResult());

总结:如果日后需要扩展计算器的功能,我们需要维护2个地方,一个是为Operation的原型添加所需要的新功能,另一个是维护策略对象:operateStrategy, 基本上不需要修改程序的内部方法,而是为它增加扩展,基本符合开放-封闭原则。我认为只要对面向对象编程思想有所了解,都能写出简单工厂模式,使用场景无需考虑因为在编码过程中这是一件很自然的事情,他简单到都不能算是一个模式。

js简单工厂的更多相关文章

  1. JS 简单工厂模式,工厂模式(二)

    一.什么是工厂模式: 工厂模式就是用来创建对象的一种最常用的设计模式,我们不暴露创建对象的具体逻辑,而是将逻辑封装到一个函数中,那么,这个函数 就可以被视为一个工厂.那么,在实际项目中,我们是不是可以 ...

  2. JS设计模式--简单工厂模式

    在JS中创建对象会习惯的使用new关键字和类构造函数(也是可以用对象字面量). 工厂模式就是一种有助于消除两个类依赖性的模式. 工厂模式分为简单工厂模式和复杂工厂模式,这篇主要讲简单工厂模式. 简单工 ...

  3. js原生设计模式——3简单工厂模式\简单工厂模式封装简单对象

    1.Factory基本写法 <!DOCTYPE html><html lang="en"><head>    <meta charset= ...

  4. 【JS设计模式】温习简单工厂模式、工厂方法模式、抽象工厂模式概念

    注:空心箭头表示的是种继承关系,工厂类和产品类之间是一种依赖关系.是用箭头加虚线表示的,以下的模型图是用的实线是不正确(时间不够用,在这里我偷懒了.这个习惯不好,呵呵) 简单工厂模式(Simple F ...

  5. Jquery如何序列化form表单数据为JSON对象 C# ADO.NET中设置Like模糊查询的参数 从客户端出现小于等于公式符号引发检测到有潜在危险的Request.Form 值 jquery调用iframe里面的方法 Js根据Ip地址自动判断是哪个城市 【我们一起写框架】MVVM的WPF框架(三)—数据控件 设计模式之简单工厂模式(C#语言描述)

    jquery提供的serialize方法能够实现. $("#searchForm").serialize();但是,观察输出的信息,发现serialize()方法做的是将表单中的数 ...

  6. JS常用的设计模式(2)——简单工厂模式

    简单工厂模式是由一个方法来决定到底要创建哪个类的实例, 而这些实例经常都拥有相同的接口. 这种模式主要用在所实例化的类型在编译期并不能确定, 而是在执行期决定的情况. 说的通俗点,就像公司茶水间的饮料 ...

  7. 《JS设计模式笔记》 2,简单工厂模式

    <script type="text/javascript"> //简单工厂模式 //定义:由一个方法来决定到底要创建哪个类的实例,而这些实例经常拥有相同的接口.其实例 ...

  8. js简单的工厂模式

    <!DOCTYPE html> <html> <head> <title></title> </head> <body&g ...

  9. js之简单工厂模式

    简单工厂模式是由一个方法来决定到底要创建哪个类的实例, 而这些实例经常都拥有相同的接口. 这种模式主要用在所实例化的类型在编译期并不能确定, 而是在执行期决定的情况. 说的通俗点,就像公司茶水间的饮料 ...

随机推荐

  1. 前端发起resultUrl请求,服务端收到后做逆向处理,校验sign后,执行originUrl逻辑

    originUrl=http://test.com:8080/user/alipay_phone?uid=123&amount=21.3第0步:前后端约定32位密钥KEY第一步:对参数按照ke ...

  2. es 中 for in for of

    arr=[11,22,33,44,55,66,77,88]for (const i in arr){ console.log(i) if (i===4){ console.log(arr[i]) }} ...

  3. SOE 部署错误 ClassFactory cannot supply requested class

    问题描述: 部署完SOE,对某个服务启用部署的SOE时,出现错误信息,假如对地图服务SampleWorldCities启用刚部署的SOE,错误信息如下: service failed to start ...

  4. jq cookie

    //$.cookie("xx");//读取xx的值 //$.cookie("xx","123");//设置xx的值为123 //$.cook ...

  5. 【题解】Journeys(线段树优化连边)

    [#3073. Pa2011]Journeys (线段树优化连边) 这张图太直观了,直接讲透了线段树优化连边的原理和正确性. 考虑建立两颗线段树,一颗是外向树,一颗是内向树,相当于网络流建模一样,我们 ...

  6. Ubuntu系统下完全卸载和安装Mysql

    删除 mysql sudo apt-get autoremove --purge mysql-server-5.0 sudo apt-get remove mysql-server sudo apt- ...

  7. SingleNumber

    Given an array of integers, every element appears twice except for one. Find that single one. Note: ...

  8. myBatis 课纲

    myBatis 课纲 第一章 MyBatis 架构.主要构件及相互关系 使用 MyBatis 构建项目 基本的增删改查映射文件方式(特殊符号处理),使用接口方式实现 结果集映射: 单个对象映射到Has ...

  9. Eclipse Find/Replace

    1.Eclipse内容助手 选中Regular expressions,使用正则表达式进行匹配.图中出现了小黄灯,Ctrl+Space显示出帮助信息. 2.Wrap search(循环检索)选中后,检 ...

  10. 本地yum源建立

    一.openstack(ocata)本地yum源的建立: 1.配置yum缓存: vi /etc/yum.conf 把yum.conf配置改为: [main] cachedir=/var/cache/y ...