Maison > interface Web > js tutoriel > le corps du texte

Apprenez le modèle d'état des modèles de conception JavaScript_compétences Javascript

WBOY
Libérer: 2016-05-16 15:20:49
original
1168 Les gens l'ont consulté

La clé du modèle d'État est de distinguer l'état interne des choses. Les changements dans l'état interne des choses conduisent souvent à des changements dans le comportement des choses.

Lorsque la lumière est allumée et que vous appuyez sur l'interrupteur, la lumière s'éteint ; appuyez à nouveau sur l'interrupteur et la lumière se rallume. Le même commutateur se comporte différemment selon les états.

1. Machine à états finis

  • Le nombre total d'états (état) est limité.
  • A tout moment, vous n'êtes que dans un seul état.
  • Sous certaines conditions, il y aura une transition d'un état à un autre.

Permet à un objet de changer de comportement lorsque son état interne change, donnant l'impression que l'objet modifie sa classe.
Explication :
(1) Encapsulez l'état dans une classe indépendante et déléguez la demande à l'objet d'état actuel. Lorsque l'état interne de l'objet change, différents changements de comportement se produiront.
(2) Les objets utilisés ont des comportements complètement différents (effet de délégation) selon les états

En matière d'encapsulation, la priorité est généralement donnée à encapsuler le comportement de l'objet plutôt que l'état de l'objet.
Mais dans le modèle d’état, c’est tout le contraire. La clé du modèle d’état est d’encapsuler chaque état de choses dans une classe distincte.

2. Exemple

Cycle du programme d'éclairage (lumière faible –> lumière forte –> lumière éteinte)

// 关灯
var OffLightState = function(light) {
  this.light = light;
};
// 弱光
var OffLightState = function(light) {
  this.light = light;
};
// 强光
var StrongLightState = function(light) {
  this.light = light;
};

var Light = function(){
  /* 开关状态 */
  this.offLight = new OffLightState(this);
  this.weakLight = new WeakLightState(this);
  this.strongLight = new StrongLightState(this);
  /* 快关按钮 */
  this.button = null;
};
Light.prototype.init = function() {
  var button = document.createElement("button"),
    self = this;
  this.button = document.body.appendChild(button);
  this.button.innerHTML = '开关';
  this.currentState = this.offLight;
  this.button.click = function() {
    self.currentState.buttonWasPressed();
  }
};
// 让抽象父类的抽象方法直接抛出一个异常(避免状态子类未实现buttonWasPressed方法)
Light.prototype.buttonWasPressed = function() {
  throw new Error("父类的buttonWasPressed方法必须被重写");
};
Light.prototype.setState = function(newState) {
  this.currentState = newState;
};

/* 关灯 */
OffLightState.prototype = new Light(); // 继承抽象类
OffLightState.prototype.buttonWasPressed = function() {
  console.log("关灯!");
  this.light.setState(this.light.weakLight);
}
/* 弱光 */
WeakLightState.prototype = new Light();
WeakLightState.prototype.buttonWasPressed = function() {
  console.log("弱光!");
  this.light.setState(this.light.strongLight);
};
/* 强光 */
StrongLightState.prototype = new Light();
StrongLightState.prototype.buttonWasPressed = function() {
  console.log("强光!");
  this.light.setState(this.light.offLight);
};

Copier après la connexion

PS : Explication supplémentaire
Les constructeurs OffLightState, WeakLightState, StrongLightState doivent être avancés.

new A("a");
var A = function(a) {
  console.log(a)
}

new B("b");
function B(b) {
  console.log(b);
}

Copier après la connexion

Les déclarations de fonctions seront hissées avant les variables ordinaires.

3. Points d'optimisation des performances

(1) Comment gérer la création et la destruction des objets d'État ?
Le premier n'est créé que lorsque l'objet d'état est nécessaire puis détruit (l'objet d'état est relativement volumineux, de préférence),
L'autre consiste à créer tous les objets d'état au début et à ne jamais les détruire (l'état change fréquemment).
(2) Utilisez le mode poids mouche pour partager un objet d'état.

4. Version JavaScript de la machine à états

(1) Déléguer directement la requête à un objet littéral pour exécution via la méthode Function.prototype.call

// 状态机
var FSM = {
  off: {
    buttonWasPressed: function() {
      console.log("关灯");
      this.button.innerHTML = "下一次按我是开灯";   // 这是Light上的属性!!!
      this.currState = FSM.on;            // 这是Light上的属性!!!
    }
  },
  on: {
    buttonWasPressed: function() {
      console.log("开灯");
      this.button.innerHTML = "下一次按我是关灯";
      this.currState = FSM.off;
    }
  },
};

var Light = function() {
  this.currState = FSM.off;  // 设置当前状态
  this.button = null;
};

Light.prototype.init = function() {
  var button = document.createElement("button");
  self = this;

  button.innerHTML = "已关灯";
  this.button = document.body.appendChild(button);
  this.button.onclick = function() {
    // 请求委托给FSM状态机
    self.currState.buttonWasPressed.call(self);
  }

}

var light = new Light();
light.init();

Copier après la connexion

(2) Utiliser la fonction délégué

var delegate = function(client, delegation) {
  return {
    buttonWasPressed: function() {
      return delegation.buttonWasPressed.apply(client, arguments);
    }
  };
};

// 状态机
var FSM = {
  off: {
    buttonWasPressed: function() {
      console.log("关灯");
      this.button.innerHTML = "下一次按我是开灯";
      this.currState = this.onState;
    }
  },
  on: {
    buttonWasPressed: function() {
      console.log("开灯");
      this.button.innerHTML = "下一次按我是关灯";
      this.currState = this.offState;
    }
  },
};

var Light = function() {
  this.offState = delegate(this, FSM.off);
  this.onState = delegate(this, FSM.on);
  this.currState = this.offState; // 设置当前状态
  this.button = null;
};

Light.prototype.init = function() {
  var button = document.createElement("button");
  self = this;

  button.innerHTML = "已关灯";
  this.button = document.body.appendChild(button);
  this.button.onclick = function() {
    // 请求委托给FSM状态机
    self.currState.buttonWasPressed();
  }
}

var light = new Light();
light.init();
Copier après la connexion

J'espère que cet article sera utile à tous ceux qui apprennent la programmation JavaScript.

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal
À propos de nous Clause de non-responsabilité Sitemap
Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!