javaScript设计模式之----工厂模式
什么是工厂模式?我们通过一个例子了解一下:
比如我们想要弹出几个字符串
function funA(){
alert('a');
}
function funB(){
alert('b');
}
function funC(){
alert('c');
}
如果我们想要弹出a,b,c我们就需要调用不同的方法funA,funB,funC。但是如果我们想弹出的东西很多呢,每次调用都需要看是需要调用哪个方法,会不会很麻烦。所以我们可以再包一个方法来做处理,如下所示:
function choose(type){
switch(type){
case 'funA' : funA(); break;
case 'funB' : funB(); break;
default : funC();
}
}
很显然,我们在调用的时候就统一使用choose这个方法就行了,省去了很多步骤。
官方是这么定义工厂模式的:Simple Factory,又叫静态工厂方法,由一个工厂对象决定创建某一种产品对象的实例。主要用来创建同一类对象。
如果是一个工厂,必须具备以下基本条件才能成立:
抽象: 定义一个最初的对象(告诉你有这么一个东西);
工厂: 用于创建对象,也即对象的大本营(告诉你这个东西是一堆宝箱,你可以选择要哪个);
具体对象: 最具象的对象,也就是某个大本营(告诉你这个宝箱中都有什么)
而工厂模式,又分为三种:简单工厂,工厂方法和抽象工厂。
1.我们先来看一下什么是简单工厂模式:
function createPop(type,text){
var o = new object();
o.content = text;
o.show = function(){
//todo
};
if(type == 'alert'){
//todo
} else if(type == 'conform'){
//todo
} else if(type == 'prompt'){
//todo
}
}
我们可以简单地理解为就好比一条生产线,不同的员工有不同的职责,要生产这个产品,我们只需要把他放在生产线里就行了。
2.工厂方法
var FoodFactory = function(type,count){
if(this instanceof FoodFactory){
return new this[type](count);
}
}
FoodFactory.prototype = {
Pie: function(count){
//todo
},
Pizza: function(count){
//todo
},
Cake: function(count){
//todo
}
}
我们可以把工厂方法类比为一个大的汽车生产厂商,他可以生产轿车,也可以生产电动车,还能够生产货车,不同的车类有不同的生产线,但是又都属于这个大的厂商,只是不同的车类有不同的生产方法罢了。
3.抽象工厂
抽象类显示定义一些功能,但没有具体实现。子类继承了抽象类还需要实现各个虚方法。就是在其他面向对象语言里的多态,创建子类赋值给父类,好处是调用方式都是一样的,运行时会自动选择子类对应的方法。如一个汽车的公司有多个品牌,它只负责设计汽车有什么功能,但真正的生产给子公司实现
var VehicleFactory = function(subType,superType){
if(typeof VehicleFactory[superType] === 'function'){
fucntion F(){}; //缓存类
F.prototype = new VehicleFactory[super]();
subType.constructor = subType;
subType.prototype = new F();
} else {
throw new Error('未创建该抽象类');
}
}
//抽象类
VehicleFactory.Car = function(){
this.type = 'Car';
};
VehicleFactory.Car.prototype = {
getPrice:function(){
return new Error('抽象方法不能调用');
},
// ...
}
//抽象类
VehicleFactory.Truck= function(){
this.type = 'Truck';
};
VehicleFactory.Truck.prototype = {
getPrice:function(){
return new Error('抽象方法不能调用');
},
// ...
}
//宝马子类
var BMW = function(price,speed){
this.price = price;
this.speed = speed;
};
VehicleFactory(BMW,'Car'); //宝马继承了抽象父类Car,有了一些抽象方法,但是不能使用
BMW.prototype.getPrice = function(){
return this.price;
}
//使用
var z4 = new BMW(50000);
console.log(z4.type); //Car 继承父类Car的属性
console.log(z4.getPrice()); //50000 继承父类Car的抽象方法,自己重新实现
抽象工厂做了什么?我们需要一个新的子类时,使用抽象工厂让子类继承对应的一个抽象类,得到一些属性和虚方法,子类再实现这些虚方法,就可以使用了。
我们再来创建一个原型,就叫person吧:
var Person = function(name,methods){
if(arguments.length > 2){
throw new Error('参数过多');
};
this.name = name;
this.methods = [];
for(var i=0,l=methods.length;i<l;i++){
if(typeof methods[i] !== 'string'){
throw new Error('参数命名需要为字符串');
}
this.methods.push(methods[i]);
}
};
Person.ensureImplements = function(obj){
for(var i=1,l=obj.length;i<l;i++){
var interface = arguments[i];
if(interface.constructor!=Interface){
throw new Error('此类型接口有误');
}
for(var j=0,ml=interface.methods.length;j<ml;j++){
var methods = interface.methods[j];
if(!obj[methods] || typeof obj[methods] !== 'function'){
throw new Error(methods + '方法不存在');
}
}
}
}
这里我们创建了一个Person对象,拥有name和method属性,并做了简单处理。然后我们创建一个抽象的Person,代码如下:
var interfacePerson = new Person('Ren',['run','eat']);
然后,看看我们的具体对象,如下所示:
var PersonOne = function(){};
PersonOne.prototype = {
run : function(){
console.log('第一个人文文要跑了');
},
eat : function(){
console.log('第一个人文文要吃饭了')
}
}
var PersonTwo = function(){};
PersonTwo.prototype = {
run : function(){
console.log('第二个人瑞瑞要跑了');
},
eat : function(){
console.log('第二个人瑞瑞要吃饭了')
}
}
var PersonThree = function(){};
PersonThree.prototype = {
run : function(){
console.log('第三个人文瑞要跑了');
},
eat : function(){
console.log('第三个人文瑞要吃饭了')
}
}
我们定义了3个人,分别拥有run和eat的功能,并且每个人又都不一样。好了,接下来我们要开始创建我们的工厂了
var WenRui = function(){};
WenRui.prototype = {
catchWenRui : function(whichOne){
switch(whichOne){
case '1' : pm = new PersonOne(); break;
case '2' : pm = new PersonTwo(); break;
default : pm = new PersonThree();
}
Interface.ensureImplements(pm);
return pm;
}
}
var wenRui = new WenRui();
wenRui.catchWenRui('1').run(); //第一个人文文要跑了
wenRui.catchWenRui('2').run(); //第二个人瑞瑞要跑了
wenRui.catchWenRui('3').eat(); //第三个人文瑞要吃饭了
WenRui这个构造函数充当了我们的factory的角色,我们放跑了第一个和第二个的文文和瑞瑞,留下了文瑞来吃饭。
好,我们来总结一下:其实,工厂模式的实现方法非常简单,解决了创建多个相似对象的问题,但是工厂模式却无从识别对象的类型,因为全部都是Object,不像Date、Array等,所以这个要用构造函数模式来解决。但是工厂模式的优点也很明显:他可以实现一些相同的方法,这些相同的方法我们可以放在父类中编写代码,那么需要实现具体的业务逻辑,那么可以放在子类中重写该父类的方法,去实现自己的业务逻辑;
也就是说有两点:
1、弱化对象间的耦合,防止代码的重复。在一个方法中进行类的实例化,可以消除重复性的代码。
2、重复性的代码可以放在父类去编写,子类继承于父类的所有成员属性和方法,子类只专注于实现自己的业务逻辑。
好吧,工厂模式我了解的就这么多了,其实,不管是什么模式,只要我们在以后的编程过程中反复的思考我们可以怎么利用设计模式来优化我们的代码,那么,我们写出来的代码一定简而精,为更多人复用。
javaScript设计模式之----工厂模式的更多相关文章
- JavaScript设计模式之工厂模式
一.工厂模式概念 工厂模式定义一个用于创建对象的接口,这个接口由子类决定实例化哪一个类.该模式使一个类的实例化延迟到了子类.而子类可以重写接口方法以便创建的时候指定自己的对象类型(抽象工厂). 这个模 ...
- JavaScript设计模式(3)-工厂模式
工厂模式 1. 简单工厂 简单工厂:使用一个类或对象封装实例化操作 假如我们有个自行车商店类 BicycleShop,它提供了销售自行车的方法可以选择销售两类自行车 Speedster,Comfort ...
- JavaScript设计模式--简单工厂模式
一,介绍 工厂模式创建对象(视为工厂里的产品)时无需指定创建对象的具体类. 工厂模式定义一个用于创建对象的接口,这个接口由子类决定实例化哪一个类.该模式使一个类的实例化延迟到了子类.而子类可以重写接口 ...
- JavaScript设计模式-10.工厂模式实例xhr
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- 【javascript】javascript设计模式之工厂模式
1.要解决的问题 2.如何实现 3.与构造函数的区别 4.总结 1.要解决的问题 工厂模式通常用于重复创建相似对象,提供动态创建对象的接口. 2.工厂模式最为设计模式中构造模式之一,通常在类或类的静态 ...
- javascript设计模式-抽象工厂模式
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- JavaScript设计模式-9.工厂模式
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- JavaScript设计模式--简单工厂模式例子---XHR工厂
第一步,Ajax操作接口(目的是起一个接口检测作用) (1)引入接口文件 //定义一个静态方法来实现接口与实现类的直接检验 //静态方法不要写出Interface.prototype ,因为这是写到接 ...
- JavaScript 设计模式之工厂模式
随机推荐
- CSS样式渐变代码,兼容IE8
background: -webkit-linear-gradient(top,#ffffff,#f5f5f5); background: -moz-linear-gradient(top,#ffff ...
- mysql 基本命令操作
1. 查看存储引擎 show engines; 2. 查看数据存储位置 show variables like 'datadir': 3. 存储引擎 create table mytest engin ...
- 和同门一起做的PHP网站
用的是PHP语言开发,使用ThinkPHP框架,数据库是mysql 统计是用的站长统计,前端很多都是别人网 上扒下来的.css.js水平不高啊.服务器是香港恒创科技的,性价比还可以哦,而且还免备案. ...
- tomcat的配置使用详细版
摘要: 开发者开发部署web应用时通常使用tomcat服务器,很多初学者只懂得在开发工具上配置,但离开了开发工具,自己手动配置部署,并让一个项目跑起来,你会了吗.小编也遇到过这样的困扰.网上查找的资料 ...
- 谈谈书本《c#物联网程序设计基础》中的技术瑕疵,如果你将要读本书,请进来看看!
今天去书店看到一本名为<c#物联网程序设计基础>的书,对物联网感兴趣的我抓起来就看,书中的项目都是上位机开发项目,较简单,如果物联网开发只是这样,看起来我做物联网开发也是绰绰有余.这边书我 ...
- jndi通俗理解以及它的指令缺陷
jndi(java naming directory interface),可以把JNDI看成一个全局的目录服务接口,实现了这个接口的类可以提供你想要的东西,不管这个东西是什么,只要注册到了目录中就可 ...
- 监控与管理dubbo服务
Dubbo是阿里多年前开源的一套服务治理框架,在众多互联网企业里应用广泛.本文介绍了一些如何监控与管理dubbo服务.使用的工具与<dubbox 的各种管理和监管>大致相同,本文更侧重于命 ...
- APNs 推送原理及问题
http://bbs.csdn.net/topics/390461996 在 iOS 平台上,大部分应用是不允许在后台运行并连接网络的.在应用没有被运行的时候,只能通过 Apple Push Noti ...
- Python 时间模块
模块分类 标准库 python解释器自带的, sys, os等 开源模块 比如selenium中的测试框架 自定义模块 比如自己封装的测试框架 时间格式 时间戳 当前时间减去1970年1月1日00:0 ...
- java 中 “==” 和 equals 的区别
转自https://www.cnblogs.com/www123----/p/7857298.html 在初学Java时,可能会经常碰到下面的代码: 1 String str1 = new Strin ...