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 again
29     console.log("执行动作:" + music.information.message); // 下一曲
30     console.log("接口状态:" + music.information.status); // 200|404
31     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 again
28 
29     music.next(); // 执行下一曲动作
30     console.log("执行动作:" + music.information.message); // 下一曲
31     console.log("接口状态:" + music.information.status); // 200|404
32     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>

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

原文地址:https://www.cnblogs.com/xiongzaiqiren/p/6789461.html