js-设计模式(总结)

2016-11-12  本文已影响55人  Jianshu9527
1.什么叫做设计模式(基本概念)
①:创建型模式:单例模式,抽象工厂模式,建造者模式,工厂者模式,原型模式
②:结构型模式:适配器模式,桥接模式,装饰模式,组合模式,外观模式,亨元模式,代理模式,
③:行为型模式:模板方法模式,命令模式,迭代器模式,观察者模式,中介者模式,备忘录模式,解释器模式,状态模式,策略模式,职责链模式,访问者模式。

2.设计模式能干什么

设计模式-创建型模式(之工厂者模式)

案列-四则运算

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        input[type="text"]{
            width: 100px;
        }
    </style>
</head>
<body>
    <div style="width:500px;height:80px;margin:50px auto;border:2px solid #ddd;">
        <input type="text" id="num1">
        <select name="" id="operator">
            <option value="+">+</option>
            <option value="-">-</option>
            <option value="*">*</option>
            <option value="/">/</option>
        </select>
        <input type="text" id="num2">
        <input type="button" value='计算' id='btn'>
        <input type="text" id="result">
    </div>
    <script>
        function $(id){
            return document.getElementById(id);
        }
        
        $('btn').onclick=function(){
            //收集信息
            var num1 = $("num1").value;
            var num2 = $("num2").value;

            //正则验证
            var reg = /^[1-9]\d*$/;//正整数
            if(reg.test(num1) && reg.test(num2)){
                num1 = parseFloat(num1);
                num2 = parseFloat(num2);
                var op = $("operator").value;
                var result;
                //计算
                
                if("+" == op){
                    result = num1 + num2;
                }
                else if("-" == op){
                    result = num1 - num2;
                }
                else if("*" == op){
                    result = num1 * num2;
                }
                else if("/" == op){
                    result = num1 / num2;
                }
                //显示结果
                $("result").value = result;
                console.info(num1,num2,op);
            }
            else{
                alert("请输入正整数")
            }
        }
    </script>
</body>
</html>

分析:在给一个运算符添加新功能时,会有一个安全隐患:全部的代码暴露在当前的程序员面前,同时,相当与是在修改源代码的方法去拓展一个新功能,但是这不符合“对修改关闭原则”

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        input[type="text"]{
            width: 100px;
        }
    </style>
</head>
<body>
    <div style="width:500px;height:80px;margin:50px auto;border:2px solid #ddd;">
        <input type="text" id="num1">
        <select name="" id="operator">
            <option value="+">+</option>
            <option value="-">-</option>
            <option value="*">*</option>
            <option value="/">/</option>
            <option value="%">%</option>
        </select>
        <input type="text" id="num2">
        <input type="button" value='计算' id='btn'>
        <input type="text" id="result">
    </div>
    <script>
        function Add(num1,num2){
            this.num1 = num1;
            this.num2 = num2;
        }
        Add.prototype.getResult = function(){
            return this.num1 + this.num2;
        }
        function Mul(num1,num2){
            this.num1 = num1;
            this.num2 = num2;
        }
        Mul.prototype.getResult = function(){
            return this.num1 * this.num2;
        }
        function Div(num1,num2){
            this.num1 = num1;
            this.num2 = num2;
        }
        Div.prototype.getResult = function(){
            if(this.num2 == 1){
                return this.num1;
            }
            return this.num1 / this.num2;
        }
        function Sub(num1,num2){
            this.num1 = num1;
            this.num2 = num2;
        }
        Sub.prototype.getResult = function(){
            return this.num1 - this.num2;
        }
        function Mod(num1,num2){
            this.num1 = num1;
            this.num2 = num2;
        }
        Mod.prototype.getResult = function(){
            return this.num1 % this.num2;
        }
        function $(id){
            return document.getElementById(id);
        }
        /**
         * 功能:计算器
         * @param  {[type]} op   [操作符]
         * @param  {[type]} num1 [第一个操作数]
         * @param  {[type]} num2 [第二个操作数]
         * @return {[type]}      [返回结果]
         */
        function computer(op,num1,num2){
            var c;
            if("+" == op){
                c = new Add(num1,num2);
            }
            else if("-" == op){
                c = new Sub(num1,num2);
            }
            else if("*" == op){
                c = new Mul(num1,num2);
            }
            else if("/" == op){
                c = new Div(num1,num2);
            }
            else if("%" == op)
                c = new Mod(num1,num2);
            
            return c.getResult();
        }
        /**
         * 正则验证
         * @param  {[type]} type [类型]
         * @param  {[type]} str  [要验证的字符串]
         * @return {[type]}      [验证结果]
         */
        function reg(type,str){
            if( "number" == type){
                var reg = /^[1-9]\d*$/;//正整数
                return reg.test(str);
            }
            else if("email" == type ){
                var reg = /^\w+@\w+(\.[a-z]{2,3})+$/i;
                return reg.test(str);
            }
        }
        $('btn').onclick=function(){
            //收集信息
            var num1 = $("num1").value;
            var num2 = $("num2").value;
            //正则验证
            if(reg("number",num1) && reg("number",num2)){
                num1 = parseFloat(num1);
                num2 = parseFloat(num2);
                var op = $("operator").value;

                //计算
                var result = computer(op,num1,num2);
                
                //显示结果
                $("result").value = result;
                console.info(num1,num2,op);
            }
            else{
                alert("请输入正整数")
            }
        }
    </script>
</body>
</html>

分析:

设计模式-创建型模式(之单例模式)

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
    </style>
</head>
<body>
    <input type="button" value="anniu" id="btn">
    <script>
        function $(id){
            return document.getElementById(id);
        }
        //arguments
        function f(){
            console.info("我是事件响应函数");
        }
        function one(func){

            var isclicked;
            function f1(){
                if(!isclicked){
                    func();
                    isclicked = true;
                }
            }
            return f1;
        }
        $('btn').onclick=one(f);    
    </script>
</body>
</html>

总结:构造器的返回值,以及闭包的使用是对单例模型实现的一个完美体现

设计模式-行为模式(策略模式)

定义:把一系列的算法,封装起来,并且可以使它们可以相互替换
需求:给定一个值,进行求值
案列:计算公司员工的年终奖

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <script>

//  公司的年终奖是根据工资基数和绩效来发放的。例如绩效为S的员工有4倍工资。A的员工有3倍工资。B的员工有2倍工资。
// 请你给出代码
        var salary = {
            S:function(basic){
                return 4 * basic;
            },
            A:function(basic){
                return 3 * basic;
            },
            B:function(basic){
                return 2 * basic;
            },
            C:function(basic){
                return 1.5 * basic;
            }
        };
        function getSalary(level,basic){
            //var f1 = salary[level];
            //return f1(basic);
            
            return salary[level](basic);
        }
        console.info ( getSalary("S",10000) );
        console.info ( getSalary("B",8000) );
        console.info ( getSalary("C",6000) );
        // console.info( salary("S",10000) );
        // console.info( salary("C",6000) );
        //问题:加一个等级C 1.5系数
    </script>
</body>
</html>

总结:①保证了对修改的关闭,同时对拓展开放
②保证了代码之间的相互不影响

设计模式-行为模式(策略模式)

定义:观察者模式又叫发布订阅模式(Publish/Subscribe),它定义了一种一对多的关系,让多个观察者对象同时监听某一个主题对象,这个主题对象的状态发生变化时就会通知所有的观察者对象,使得它们能够自动更新自己。

<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>观察者模式</title>
</head>
<body>
    <h1 id='header'>消息列表1条</h1>
    <ul id="list">
        <li>
            消息内容<br><br>
            <button value='删除' id='del'>删除</button>
        </li>
    </ul>
    <input type="text" id='news'>
    <button value='点击添加消息' id='btn'>点击添加消息</button>
</body>
<script>
    function $(id){
        return document.getElementById(id);
    };
    var counts=1;
    $('del').onclick=function(){
        counts--;
        this.parentNode.parentNode.removeChild(this.parentNode);
        $('header').innerHTML="消息列表"+counts+"条"
    }

    $('btn').onclick=function(){    
        var news=document.createElement('li'),
        del=document.createElement('button');
        news.innerHTML=$('news').value+'<br><br>';
        del.innerHTML="删除";
        del.onclick=function(){
            counts--;
            this.parentNode.parentNode.removeChild(this.parentNode);
            $('header').innerHTML="消息列表"+counts+"条"
        }
        news.appendChild(del);
        $('list').appendChild(news);
        counts++;
        $('header').innerHTML="消息列表"+counts+"条";
    }
    </script>
</html>
<html>
<head>
    <meta charset="utf-8" />
    <title></title>
    <style>
            .container{
                border:3px solid #ccc;
                padding:0 20px;
                margin:30px auto;
                width: 600px;
            }
            a{
                text-decoration: none;
            }
            ul{list-style: none;}
        </style>
</head>
<body>
    <div class="container">
        <h1>消息列表<span id="num">0</span>条</h1>
        <ul id="ulmsg">
            <!-- <li><p>消息内容</p><button>删除</button></li> -->
        </ul>
        <form action="">
            <input type="text" id="words">
            <input type="button" value="添加" id="btnsubmit">
        </form>
    </div>
    <script type="text/javascript">
        function $(id){
            return document.getElementById(id);
        }
        function create(flag){
            return document.createElement(flag)
        }
        //实现观察者
        function NumberManager(data){
            $("num").innerHTML = $("num").innerHTML*1 + data.num;
        }
        function MessageManager(data){
            //<li><p>消息内容</p><button>删除</button></li>
            var li = create("li");
            var p = create("p");
            var button = create("button");
            button.innerHTML="删除";

            button.onclick = function(){
                $("ulmsg").removeChild(li);
                
                center.fire("delMsg",{num:-1});
            }
            p.innerHTML = data.txt;
            li.appendChild(p);
            li.appendChild(button);
            $("ulmsg").appendChild(li);
        }
        function Somthingelse(data){
            console.info(data);
        }
        var center = {
            viewers:{},
            addViewer:function(eventtype,callback){
                if(this.viewers.hasOwnProperty(eventtype)){
                    this.viewers[eventtype].push(callback);
                }
                else{
                    this.viewers[eventtype] = [callback];
                }
            },
            delViewer:function(){
            },
            fire:function(eventtype,data){ //有变化 通知所有的观察者
                if(this.viewers.hasOwnProperty(eventtype)){
                    for (var i = 0; i < this.viewers[eventtype].length; i++) {
                        this.viewers[eventtype][i].call(this,data);
                    }
                }

            }
        }
        center.addViewer("addMsg",Somthingelse); //添加订阅者
        center.addViewer("addMsg",NumberManager);
        center.addViewer("addMsg",MessageManager);
        center.addViewer("delMsg",NumberManager);
        $("btnsubmit").onclick = function(){
            var data={
                txt:$("words").value,
                num:1
            };

            center.fire("addMsg",data);
        }
    </script>
</body>
</html>

设计模式-结构型模式(装饰者模式)

<html>
<head>
    <meta charset="utf-8" />
    <title></title>
    <script src="jquery-2.1.4.js"></script>
</head>
<body>

    <script type="text/javascript">

    function ready(f){
    debugger;
        //判断一下window.onload是否存在 。如果存在 ,则先调用它,再调用f函数
        var t = window.onload;
        if(typeof t =="function"){
            window.onload = function(){
                t();
                f();
            }
        }
        else{
            window.onload = function(){
                f();
            }
        }
    }
    ready(function(){console.info(2)});
    ready(function(){console.info(3)});
    ready(function(){console.info(1)});
    </script>
</body>
</html>

3.设计模式的利与弊
4.关于自学设计模式的浅略总结(坑)
设计模式“可复用面向对象软件的基础”。
设计模式完全是从面向对象设计的角度出发的,通过对封装、继承、多态、组合等技术的反复使用,提炼出一些可重复使用的面向对象设计技巧。所以有一种说法是设计模式仅仅是就面向对象的语言而言的。

上一篇 下一篇

猜你喜欢

热点阅读