- 当一个对象的内部状态发生改变时,会导致其行为的改变,这看起来相是改变了对象
- 对象有自己的状态
- 不同状态下执行的逻辑不一样
- 明确状态和每个状态下执行的动作
- 用来减少 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>