政策模式
簡單點說就是:實作目标的方式有很多種,你可以根據自己身情況選一個方法來實作目标.
是以至少有2個對象 . 一個是政策類,一個是環境類(上下文). 然後自己就可以根據上下文選擇不同的政策來執行方案.
政策模式的優點:
1. 政策模式利用組合、委托和多态等技術和思想,可以有效地避免多重條件選擇語句
2. 政策模式提供了對開放-封閉原則的完美支援,将算法封裝在獨立的 政策類 中,使得它們易于切換,易于了解,易于擴充.
// html
<!DOCTYPE html>
<head>
<meta charset="utf8">
<title>政策模式實作表單驗證</title>
<link rel="stylesheet" type="text/css" href="style.css" target="_blank" rel="external nofollow" >
<script src="rule.js"></script>
<script src="validator.js"></script>
</head>
<body>
<form action="#" method="GET" id="form">
<div class="field">
<label>使用者名</label>
<input type="text" name="name">
</div>
<div class="field">
<label>聯系電話</label>
<input type="text" name="mobile">
</div>
<div class="field">
<label>郵箱</label>
<input type="text" name="email">
</div>
<button class="submit" type="submit">送出</button>
</form>
<script>
let dom = document.getElementById("form");
let formValid = new FormValid(dom);
formValid.add({
field: "name",
rule: new RequiredRule(),
errormsg: "字段必填"
})
formValid.add({
field: "name",
rule: new LengthRule(10),
errormsg: "限定長度為10個字元"
})
formValid.add({
field: "mobile",
rule: new MobileRule(),
errormsg: "手機号碼錯誤"
})
formValid.add({
field: "email",
rule: new EmailRule(),
errormsg: "郵箱格式錯誤"
})
dom.onsubmit = function (event) {
let result = formValid.isValid();
if (result !== true) {
alert(result);
return false;
}
alert("送出成功");
}
</script>
</body>
</html>
// css
#form{
margin: 50px auto;
width: 500px;
}
input {
width: 350px;
height: 24px;
padding: 0 4px;
float: left;
}
.field{
margin-top: 10px;
overflow: hidden;
}
label {
float: left;
text-align: right;
width: 100px;
overflow: hidden;
padding-right: 5px;
}
.submit{
margin-top: 20px;
margin-left:104px;
}
// 政策類
/**
* 必填
*/
class RequiredRule {
/**
* 驗證
* @param {string} value 值
* @param {string} errormsg 錯誤資訊
* @param {any} attach 附加參數
* @returns {string|bool}
*/
test(value, errormsg, attach) {
return /^(:?\s*)$/.test(value) ? errormsg : true;
}
}
/**
* 範圍
*/
class RangeRule {
/**
* 構造函數
* @param {array} range
*/
constructor(range) {
this.range = range;
}
/**
* 驗證
* @param {string} value 值
* @param {string} errormsg 錯誤資訊
* @returns {string|bool}
*/
test(value, errormsg) {
value = Number.parseFloat(value);
if (this.range[0] <= value && this.range[1] > value) {
return true;
}
return errormsg;
}
}
/**
* 有效數值驗證
*/
class NumberRule {
/**
* 驗證
* @param {string} value 值
* @param {string} errormsg 錯誤資訊
* @returns {string|bool}
*/
test(value, errormsg) {
return /^(?:\d+)$/.test(value) || errormsg;
}
}
/**
* 郵箱驗證
* 格式:登入名@主機名.域名
*/
class EmailRule {
constructor() {
this.rule = new RegExp(/(?:\w+)@(?:\w+)\.(?:\w+)/);
}
/**
* 驗證
* @param {string} value 值
* @param {string} errormsg 錯誤資訊
* @returns {string|bool}
*/
test(value, errormsg) {
return this.rule.test(value) || errormsg;
}
}
/**
* 手機号驗證
*/
class MobileRule {
constructor() {
this.rule = new RegExp(/^1\d{10}$/);
}
/**
* 驗證
* @param {string} value 值
* @param {string} errormsg 錯誤資訊
* @returns {string|bool}
*/
test(value, errormsg) {
return this.rule.test(value) || errormsg;
}
}
class LengthRule {
constructor(maxlength) {
this.maxlength = maxlength;
}
/**
* 驗證
* @param {string} value 值
* @param {string} errormsg 錯誤資訊
* @returns {string|bool}
*/
test(value, errormsg) {
return value.length > this.maxlength ? errormsg : true;
}
}
// 環境類
class FormValid {
/**
* 構造函數
* @param {HTMLFormElement} form 元素節點
*/
constructor(form) {
this.form = form;
this.rules = [];
}
/**
* 添加驗證規則
* @param {object} option
* @param {string} option.field 字段名
* @param {object} option.rule 規則
* @param {string} option.errormsg 錯誤資訊
*/
add({ field, rule, errormsg }) {
if (typeof rule.test == "function" && this.form[field]) {
this.rules.push(() => {
return rule.test(this.form[field].value, errormsg);
});
}
}
isValid() {
let result = [];
for (let i = 0; i < this.rules.length; i++) {
let r = this.rules[i]();
if (r !== true) result.push(r);
}
return result.length > 0 ? result : true;
}
}
源碼:https://pan.baidu.com/s/17_oBg1dqmbxAdG_AW3sWgg
樣本:http://js.zhuamimi.cn/%E8%A1%A8%E5%8D%95%E9%AA%8C%E8%AF%81/
轉載于:https://www.cnblogs.com/whnba/p/10301407.html