Heim  >  Artikel  >  Web-Frontend  >  Erlernen Sie das Zustandsmuster von JavaScript-Entwurfsmustern_Javascript-Fähigkeiten

Erlernen Sie das Zustandsmuster von JavaScript-Entwurfsmustern_Javascript-Fähigkeiten

WBOY
WBOYOriginal
2016-05-16 15:20:491168Durchsuche

Der Schlüssel zum Zustandsmodell besteht darin, den inneren Zustand der Dinge zu unterscheiden. Veränderungen im inneren Zustand der Dinge führen oft zu Veränderungen im Verhalten der Dinge.

Wenn das Licht eingeschaltet ist und Sie den Schalter drücken, schaltet das Licht in den Aus-Zustand; drücken Sie den Schalter erneut und das Licht schaltet sich wieder ein. Derselbe Schalter verhält sich in verschiedenen Zuständen unterschiedlich.

1. Endliche Zustandsmaschine

  • Die Gesamtzahl der Staaten (Staat) ist begrenzt.
  • Zu jedem Zeitpunkt befinden Sie sich nur in einem Zustand.
  • Unter bestimmten Voraussetzungen kommt es zu einem Übergang von einem Zustand in einen anderen.

Ermöglicht einem Objekt, sein Verhalten zu ändern, wenn sich sein interner Zustand ändert, sodass es so aussieht, als würde das Objekt seine Klasse ändern.
Erläuterung:
(1) Kapseln Sie den Status in eine unabhängige Klasse und delegieren Sie die Anforderung an das aktuelle Statusobjekt. Wenn sich der interne Status des Objekts ändert, treten unterschiedliche Verhaltensänderungen auf.
(2) Die verwendeten Objekte haben in verschiedenen Zuständen völlig unterschiedliche Verhaltensweisen (Delegationseffekt)

Bei der Kapselung wird im Allgemeinen der Kapselung des Verhaltens des Objekts Vorrang eingeräumt und nicht dem Zustand des Objekts.
Aber im Zustandsmuster ist es genau das Gegenteil. Der Schlüssel zum Zustandsmuster besteht darin, jeden Zustand der Dinge in einer separaten Klasse zu kapseln.

2. Beispiel

Beleuchtungsprogramm (wenig Licht –> starkes Licht –> Licht aus) Zyklus

// 关灯
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);
};

PS: Zusätzliche Erklärung
Die Konstruktoren OffLightState, WeakLightState, StrongLightState müssen erweitert werden.

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

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

Funktionsdeklarationen werden vor gewöhnlichen Variablen angezeigt.

3. Leistungsoptimierungspunkte

(1) Wie verwaltet man die Schaffung und Zerstörung staatlicher Objekte?
Das erste wird nur erstellt, wenn das Statusobjekt benötigt wird, und dann zerstört (das Statusobjekt ist relativ groß, bevorzugt),
Die andere besteht darin, alle Zustandsobjekte zu Beginn zu erstellen und sie niemals zu zerstören (der Zustand ändert sich häufig).
(2) Verwenden Sie den Fliegengewichtsmodus, um ein Statusobjekt freizugeben.

4. JavaScript-Version der Zustandsmaschine

(1) Delegieren Sie die Anforderung direkt an ein Literalobjekt zur Ausführung über die Function.prototype.call-Methode

// 状态机
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();

(2) Delegiertenfunktion verwenden

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();

Ich hoffe, dass dieser Artikel für alle hilfreich ist, die JavaScript-Programmierung lernen.

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn