首页 > 代码库 > Javascript设计模式之工厂模式

Javascript设计模式之工厂模式

设计模式并不是某一种语言所特有的,而是一种设计理念,现在学习Javascript的设计模式相关知识点。


工厂模式

工厂模式设计目标是:根据不同的需求创建实例化对象。我们将通过一个特定的需求来逐渐深入的讲解工程模式的用法。

我们需要达到的一个需求是,做一个音乐播放器,这个播放器有四个按钮,分别是上一首、下一首、播放暂停、静音。

 

针对上面的需求,我们先按照最简单的工厂模式写一个方法。

 1 <script> 2     function WangyiMusicAction(action) { 3         var obj = new Object; 4         obj.vender = "网易云音乐"; 5         obj.playingMusic = "see you again"; 6  7         switch (action) { 8             case "last": 9                 obj.information = { currentMusic: "小幸运", status: "200|404", message: "上一曲" };10                 break;11             case "next":12                 obj.information = { currentMusic: "野子", status: "200|404", message: "下一曲" };13                 break;14             case "play":15                 obj.information = { currentMusic: "see you again", status: "200|500", message: "播放" };16                 break;17             case "mute":18                 obj.information = { currentMusic: "see you again", status: "200|500", message: "静音" };19                 break;20         }21 22         return obj;23     };24 25     /***下面是调用测试代码***/26     var music = new WangyiMusicAction("next");27     console.log("音乐提供商:" + music.vender); // 网易云音乐28     console.log("正在播放:" + music.playingMusic); // see you again29     console.log("执行动作:" + music.information.message); // 下一曲30     console.log("接口状态:" + music.information.status); // 200|40431     console.log("执行动作后歌曲:" + music.information.currentMusic); //野子32 33 </script>

通过给action传递不同的参数,可以获取不同的播放器状态。

 

面向对象理念

但是上述的方法并没有用到面向对象的理念,我们使用面向对象的思维重新修改上面的方法。

 1 <script> 2     var WangyiMusicAction = function () { 3         this.vender = "网易云音乐"; 4         this.playingMusic = "see you again"; 5     }; 6  7     //扩展其prototype属性 8     WangyiMusicAction.prototype = { 9         last: function () {10             this.information = { currentMusic: "小幸运", status: "200|404", message: "上一曲" };11         },12         next: function () {13             this.information = { currentMusic: "野子", status: "200|404", message: "下一曲" };14         },15         play: function () {16             this.information = { currentMusic: "see you again", status: "200|500", message: "播放" };17         },18         mute: function () {19             this.information = { currentMusic: "see you again", status: "200|500", message: "静音" };20         }21     };22 23 24     /***下面是调用测试代码***/25     var music = new WangyiMusicAction();26     console.log("音乐提供商:" + music.vender); // 网易云音乐27     console.log("正在播放:" + music.playingMusic); // see you again28 29     music.next(); // 执行下一曲动作30     console.log("执行动作:" + music.information.message); // 下一曲31     console.log("接口状态:" + music.information.status); // 200|40432     console.log("执行动作后歌曲:" + music.information.currentMusic); //野子33 34 </script>

在上述面向对象的工厂模式中,建立一个WangyiMusicAction对象,然后扩展其prototype属性,这样每个实例都会有自己的方法。

 

改进工厂模式

上面的工厂模式中,只能生成WangyiMusicAction的对象,如果我还要生成一个QQMusic和BaiduMusic,XiamiMusic,只有每个music都得写一遍方法,这是不值得推荐的。

我们可以通过一个Factory来动态创建各种类型的Music,首先是WangyiMusicAction。

 

优化工厂模式

但是在上面的工厂模式中,我们发现对于不同音乐提供商共用的属性可以封装成一个对象,用作父类继承。

1,定义父类

2,继承
通过修改prototype属性实现继承。

3,建立Factory工厂

建立工厂动态生成WangyiMusic或者QQMusic,然后生成一个QQMusic实例,并调用相应的方法。

 

 1 <script> 2     //基类(父类)Music方法 3     var BaseMusic = function () { 4         this.playingMusic = "see you again"; 5         this.information = { 6             currentMusic: "", 7             status: "", 8             message: "" 9         };10     };11 12     //实现通用方法13     BaseMusic.prototype = {14         last: function () {15             this.information.currentMusic = "小幸运";16             this.information.status = "200|404";17             this.information.message = "上一曲";18         },19         next: function () {20             this.information.currentMusic = "野子";21             this.information.status = "200|404";22             this.information.message = "下一曲";23         },24         play: function () {25             this.information.currentMusic = "see you again";26             this.information.status = "200|500";27             this.information.message = "播放";28         },29         mute: function () {30             this.information.currentMusic = "see you again";31             this.information.status = "200|500";32             this.information.message = "静音";33         }34     };35 36 37     //网易云音乐不同于父类的构造方法38     var WangyiMusicAction = function (action) {39         this.vender = "网易云音乐";40     };41     //通过prototype实现类继承42     WangyiMusicAction.prototype = new BaseMusic(); //将动作放在基类,到达代码复用的目的43 44     //QQ音乐不同于父类的构造方法45     var QQMusicAction = function (action) {46         this.vender = "QQ音乐";47     };48     //通过prototype实现类继承49     QQMusicAction.prototype = new BaseMusic(); //将动作放在基类,到达代码复用的目的50 51 52     //音乐工厂53     var MusicFactory = function (type) {54         switch (type) {55             case "wangyi":56                 return new WangyiMusicAction();57             case "qq":58                 return new QQMusicAction();59         }60     };61 62     /***下面是调用测试代码***/63     var music = new MusicFactory("wangyi");64     console.log("音乐提供商:" + music.vender);65     console.log("正在播放:" + music.playingMusic);66 67     music.next(); // 执行下一曲动作68     console.log("执行动作:" + music.information.message);69     console.log("接口状态:" + music.information.status);70     console.log("执行动作后歌曲:" + music.information.currentMusic);71 72 </script>

通过上述的继承父类方案,可以优化代码结构,工厂模式也使用的更加简洁。

 

Javascript设计模式之工厂模式