状态和策略模式

  • 当一个对象的内部状态发生改变时,会导致其行为的改变,这看起来相是改变了对象
  • 对象有自己的状态
  • 不同状态下执行的逻辑不一样
  • 明确状态和每个状态下执行的动作
  • 用来减少 if else子句
//状态模式
class SuccessState{
    show(){
        console.log('high');
    }
}
class WarningState{
    show(){
        console.log('middle');
    }
}
class LowState{
    show(){
        console.log('low');
    }
}
class Battery{
    constructor(){
        this.amount = 'high';
        this.state = new SuccessState();
    }
    show(){
        this.state.show();
        if(this.amount == 'high'){
            this.amount = 'middle';
            this.state = new WarningState();
        }else if(this.amount == 'middle'){
            this.amount = 'low';
            this.state = new LowState();
        }
    }
}
let b1= new Battery();
b1.show();
b1.show();
b1.show();

 状态模式应用场景

<div id="root"></div>
    <script>
        let likeState = {
            render(element){
                element.innerHTML = '赞'
            }
        }
        let likedState = {
            render(element){
                element.innerHTML = '取消'
            }
        }
        class Button{
            constructor(container){
                this.liked = false;//默认未点赞状态
                this.state = likeState;
                this.element = document.createElement("button");
                container.appendChild(this.element);
                this.render()
            }
            setState(state){
                this.state = state;
                this.render();
            }
            
            render(){
                this.state.render(this.element)
            }
        }
        let button = new Button(document.body);
        button.element.addEventListener('click',()=>{
            button.setState(button.liked?likeState:likedState)
            button.liked = !button.liked;
        },false)
    </script>

状态模式应用场景-promise(不完全应用)

class Promise{
    constructor(fn){
        this.state = 'initial';
        this.successes = [];
        this.errors = [];
        let resolve = (data)=>{
            this.state = 'fulfilled';
            this.successes.forEach(item=>item(data))
        }
        let reject = (error)=>{
            this.state = 'failed';
            this.errors.forEach(item=>item(error));
        }
        fn(resolve,reject);
    }
    then(success,error){
        this.successes.push(success);
        this.errors.push(error);
    }
}
let p = new Promise(function(resolve,reject){
    setTimeout(function(){
        let num = Math.random();
        if(num>0.5){
            resolve(num)
        }else{
            reject(num)
        }
    },500)
})
p.then((data)=>{
    console.log(data,'成功')
},(data)=>{
    console.log(data,'失败')
})

策略模式

  • 将定义的一组算法封装起来,使其相互之间可以替换。封装的算法具有一定独立性,不会随客户端变化而变化
  • 避免大量的if else或者 switch case
//常规写法
class Customer{
    constructor(type){
        this.type = type;
    }
    pay(amount){
        if(this.type == 'member'){
            return amount*.9;
        }else if(this.type == 'vip'){
            return amount*.8;
        }else{
            return amount
        }
    }
}
//策略模式
class CustomerNew{
    constructor(kind){
        this.kind = kind;
    }
    pay(amount){
        return this.kind.pay(amount)
    }
}
class Normal{
    pay(amount){
        return amount;
    }
}
class Member{
    pay(amount){
        return amount*0.9;
    }
}
class Vip{
    pay(amount){
        return amount*0.8;
    }
}
let c1 = new CustomerNew(new Normal());
console.log(c1.pay(100))
c1.kind = new Member;
console.log(c1.pay(100))
c1.kind = new Vip;
console.log(c1.pay(100))

//方法2
class Customer1{
    constructor(){
        this.kind = {
            normal:function(amount){
                return amount;
            },
            member:function(amount){
                return amount*0.9
            },
            vip:function(amount){
                return amount*0.8
            }
        }
    }
    pay(kind,amount){
        return this.kind[kind](amount)
    }
}
let c= new Customer1();
console.log(c.pay('normal',100))
console.log(c.pay('member',100))
console.log(c.pay('vip',100))

策略模式应用场景

<form id="userForm">
 用户名:<input type="text" name="username"><br/>
 密码:<input type="text" name="password"><br/>
 手机号:<input type="text" name="mobile"><br/>
 邮箱:<input type="text" name="email"><br/>
 <input type="submit" value="提交">
</form>
<script>
let form = document.getElementById('userForm');
let validator = (function(){
  let rules = {
   notEmpty(val,msg){
	if(val===''){
	  return msg;
	}
  },
  maxLength(val,max,msg){
    if(val===''|| val.length>max){
	 return msg;
	}
  },
  minLength(val,min,msg){
	if(val===''||val.length<min){
	 return msg;
	}
  },
  isMobile(val,msg){
    if(!/1\d{10}/.test(val)){
	 return msg;
	}
  }
 }
 function addRule(name,rule){
   rules[name] = rule;
 }
 let checks = [];
 function add(ele,rule){
   checks.push(function(){
    let val = ele.value;
    let name = rule.shift();
    rule.unshift(val);
    return rules[name] && rules[name].apply(ele,rule)
  })
 };
 function start(){
   for(let i=0;i<checks.length;i++){
	 let check = checks[i];
	 let msg = check();
	 if(msg){
	  return msg;
	 }
   }
 }
 return {addRule,add,start}
})()
validator.addRule('isEmail',function(val,msg){
 if(!/.*@.*/.test(val)){
  return msg;
 }
})
form.onsubmit = function(){
 console.log(form.username)
 validator.add(form.username,['notEmpty','用户名不能为空'])
 validator.add(form.password,['minLength',6,'密码长度不能少于6位'])
 validator.add(form.password,['maxLength',8,'密码长度不能大于8位'])
 validator.add(form.mobile,['isMobile','必须输入合法的手机号'])
 validator.add(form.email,['isEmail','请输入合法邮箱地址'])
 let msg = validator.start();
 if(msg){
  alert(msg);
  return false;
 }
 return true;
}
</script>

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章