Patrón de diseño JS------Patrón de estrategia

Separar las partes que no cambian de las que cambian es un tema de todo patrón de diseño.

¿Cuál es el patrón de estrategia?
El patrón de estrategia consiste en clasificar y encapsular razonablemente diferentes algoritmos por separado, de modo que los diferentes algoritmos puedan reemplazarse entre sí sin afectar a los usuarios de los algoritmos.

A continuación, utilizamos un ejemplo simple para ilustrar el modo de estrategia:
por ejemplo: según la puntuación entrante, determine si el estado de la puntuación actual es reprobado, aprobado o excelente.

// 一般写法
const score1 = 59;
function judgeScore(score) {
    
    
    if(score < 60 ) {
    
    
        return '不及格'
    }else if(score > 60 && score < 85) {
    
    
        return '及格了'
    }else if(score >= 85) {
    
            
    	return '优秀'
    }
}

judgeScore(58); // 不及格
judgeScore(66);	// 及格
judgeScore(88);	// 优秀

Como se muestra arriba:
Necesitamos usar múltiples if...else... para juzgar las puntuaciones entrantes. Si la puntuación se divide más finamente, el código será muy redundante y difícil de mantener.

A continuación, echemos un vistazo a los efectos logrados utilizando el patrón de estrategia:

// 策略模式
let strategies = {
    
    
    noPass: function(score, tipText) {
    
    
        if(score < 60) {
    
    
            return tipText;
        }
    },

    pass: function(score, tipText) {
    
    
        if(score > 60 && score < 85) {
    
    
            return tipText
        }    
    },

    excellent: function(score, tipText) {
    
    
        if(score >= 85) {
    
    
            return tipText;
        }
    }
}

function judgeScore(score) {
    
    
    let noPass = strategies['noPass'](score, '不及格');
    let pass = strategies['pass'](score, '及格');
    let excellent = strategies['excellent'](score, '优秀');
    let res = noPass || excellent || pass;
    return res;
}

judgeScore(58); // 不及格
judgeScore(66);	// 及格
judgeScore(88);	// 优秀

La aplicación más clásica del patrón de estrategia es la validación de formularios:

// 一般写法
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <form action="xxxx" id="myForm">
        <input type="text" placeholder="userName" name="userName" />
        <input type="text" placeholder="password" name="password"/>
        <button>登录</button>
    </form>
    <script>
        const myForm = document.getElementById('myForm');
        myForm.onsubmit = function () {
    
    
            if(myForm.telephone.value === '') {
    
    
                console.log('电话号码不能为空');
                return false;
            }else if(myForm.userName.password === '') {
    
    
                console.log('密码不能为空');
                return false;
            }
        }
    </script>
</body>

</html>

Como se muestra en el código anterior:
el mismo código es fácil de entender, pero cada vez que agregamos un elemento de formulario, debemos agregar una declaración if.

A continuación aplicamos el patrón de estrategia para transformarlo:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <form action="xxxx" id="myForm">
        <input type="text" placeholder="telephone" name="telephone" />
        <input type="text" placeholder="至少8位数" name="password"/>
        <button>登录</button>
    </form>
    <script>
        const myForm = document.getElementById('myForm');
        let strategies = {
    
    
            isNotEmpty: function(value, tipText) {
    
    
                if(vlaue === '') {
    
    
                    return tipText;
                }
            },
            minLength: function(value, length, tipText) {
    
    
                debugger
                if(value.length < length) {
    
    
                    return tipText;
                }
            },
            matchTelephone: function(value, tipText) {
    
    
                if(!/^1[3|4|5|7|8|9][0-9]{9}$/.test(value)) {
    
    
                    return tipText;
                }
            }
        }

        class Validator {
    
    
            constructor(strategies) {
    
    
                this.strategies = strategies;
                this.cache = [];
            }

            add(dom, rule, tipText) {
    
      // add(dom, 'minLength:8', '***')
                this.cache.push(function() {
    
    
                    const r = rule.split(':');
                    const strategy = r.shift();
                    const params = [...r, tipText];
                    return strategies[strategy](dom, ...params);
                })
            }

            startValidate() {
    
    
                for(let i = 0; i < this.cache.length; i++) {
    
    
                    let msg = this.cache[i]();
                    if(msg) {
    
    
                        return msg;
                    }
                }
            }
        }

        let validateFunc = function() {
    
    
            let validator = new Validator();
            validator.add(myForm.telephone.value, 'matchTelephone', '请输入正确的手机号格式');
            validator.add(myForm.password.value, 'minLength:8', '密码至少8位数');
            let tipText = validator.startValidate();
            return tipText;
        }

        myForm.onsubmit = function(e) {
    
    
            const tipText = validateFunc();
            if(tipText) {
    
    
                console.log(tipText);
                return false // 有错误,阻止表单提交
            }
        }


    </script>
</body>

</html>

Guess you like

Origin blog.csdn.net/u013558749/article/details/122495670