zoukankan      html  css  js  c++  java
  • 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>

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

  • 相关阅读:
    Red Hat Enterprise Linux 4 下安装 Oracle 10g [转]
    C# 轻松实现对窗体(Form)换肤[转]
    广州.NET俱乐部第一次活动安排暨动员书
    庆祝广州.net俱乐部成立暨迎接新成员暨讨论社区活动
    有感于广州.NET俱乐部的成立暨全体动员书
    如何在列表模板中增加一个计算列
    BI有感续
    BI有感
    列表属性查看器WebPart
    广州.NET第一次活动内容及演讲安排(本贴持续更新中)
  • 原文地址:https://www.cnblogs.com/xiongzaiqiren/p/6789461.html
Copyright © 2011-2022 走看看