• 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>

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

  • 相关阅读:
    Codeforces 1265A Beautiful String
    1039 Course List for Student (25)
    1038 Recover the Smallest Number (30)
    1037 Magic Coupon (25)
    1024 Palindromic Number (25)
    1051 Pop Sequence (25)
    1019 General Palindromic Number (20)
    1031 Hello World for U (20)
    1012 The Best Rank (25)
    1011 World Cup Betting (20)
  • 原文地址:https://www.cnblogs.com/xiongzaiqiren/p/6789461.html
Copyright © 2020-2023  润新知