设计模式之开闭原则:对修改关闭,对扩展开放

  • 底层模块的变动,必然有高层模块的耦合,开闭原则就是减小变动的扩展性

通俗的意思就是说,在开发过程当中,在前期设计就必须作好相对应的扩展html

  • 在修改代码时必需要尽可能少动原有的代码,最好不要修改老的代码,这就是对修改关闭
  • 那么如何处理新的需求呢?这里就涉及到代码的前期涉及了,尽可能作到的是新增函数,只对新需求作扩展

这里举一个栗子:前端

这里有个表单:bash

<div id="loginForm">
    <input type="text" class="username" id="username" placeholder="username"><br>
    <input type="text" class="pwd" id="pwd" placeholder="pwd"><br>
    <button onclick="checkLogin()">提交</button>
</div>
复制代码

通常作前端校验的方法可能就会是这个样子:函数

  • 写一个公共的校验方法来对表单中的每一个输入项进行校验
  • 取出 input 表单中的每一个值,依次根据指定的校验规则,来校验前端输入的内容
  • 若是出现错误的话,就会对这个输入错误的数据进行提醒

好比下面这样的方式:ui

function checkLogin() {

    let username = document.querySelector("#username").value;
    if (!username) {
        alert("username must not be null");
    }

    let pwd = document.querySelector("#pwd").value;
    if (!pwd) {
        alert("pwd must not be null");
    }
}
复制代码

这样就会面临下面的问题:spa

  • 若是校验规则有变更的话,就须要对原来的代码进行修改
  • 若是需求有变更,好比在原来的表单中新增了一个 input 输入框的话,就还须要修改原来的这个校验的代码
  • 通常来讲,修改代码都有可能对原来的代码形成必定的问题,修改就有可能出错

对修改关闭

这是一个很是重要的原则,对原来已有的代码最好不作修改设计

那么咱们在这里该这么作呢?看这样的修改:code

  1. 在 html 中添加一个 input 输入框自身的自定义属性 data-validate 用来标识这个 input 输入框对应的校验函数名
<div id="loginForm">
    <input type="text" class="username" data-validate="checkUsername" id="username" placeholder="username"><br>
    <input type="text" class="pwd" data-validate="checkPwd" id="pwd" placeholder="pwd"><br>
    <button onclick="checkLoginForm()">提交</button>
</div>
复制代码
  1. 写通用函数,专门负责这个表单的校验,获取全部的 input 输入框,拿到对应的校验函数,并调用对应的挂载在 window 上的校验函数
function checkLoginForm() {
    // 表单
    let form = document.querySelector("#loginForm");
    // 表单中input
    let ipts = form.querySelectorAll("input");
    // 获取input中的校验函数名,并调用对应的函数
    for (let i = 0; i < ipts.length; i++) {
        let input = ipts[i];
        let validate = input.dataset.validate;
        let validateFn = window[validate];
        if (validateFn) {
            let rst = !validateFn(input.value);
            if (rst) {
                return false;
            }
        } else {
            alert(`当前没有这个${validate}校验函数`);
        }
    }

}
复制代码
  1. 这样之后的扩展就能够单独写对应的校验函数就ok,无需再去修改原来的 checkLoginForm 函数,同时校验函数还能够复用。
function checkUsername(username) {
    if (!username) {
        alert("username must not be null");
    }
}
复制代码
  1. data-validate="checkUsername" 属性值对应的就是通用的校验函数名称,减小对原有代码的修改和侵入。
相关文章
相关标签/搜索