State | это... Что такое State? (original) (raw)

State

Состояние (англ. State) — шаблон проектирования. Используется в тех случаях, когда во время выполнения программы объект должен менять свое поведение в зависимости от своего состояния.

Паттерн состоит из 3 блоков:

Widget — класс, объекты которого должны менять свое поведение в зависимости от состояния.

IState — интерфейс, который должно реализовать каждое из конкретных состояний. Через этот интерфейс объект Widget взаимодействует с состоянием, делегируя ему вызовы методов. Интерфейс должен содержать средства для обратной связи с объектом, поведение которого нужно изменить. Для этого используется событие (паттерн Publisher — Subscriber). Это необходимо для того, чтобы в процессе выполнения программы заменять объект состояния при появлении событий. Возможны случаи, когда сам Widget периодически опрашивает объект состояние на наличие перехода.

StateA … StateZ — классы конкретных состояний. Должны содержать информацию о том, при каких условиях и в какие состояния может переходить объект из текущего состояния. Например, из StateA объект может переходить в состояние StateB и StateC, а из StateB — обратно в StateA и так далее. Объект одного из них должен содержать Widget при создании.

Примеры

Javascript

Пример со сменой состояний из State.

// "интерфейс" State

function State() {
    this.someMethod = function() { };
    this.nextState = function() { };
}

// реализация State

// первое состояние
function StateA(widjet) {
    var dublicate = this; // ссылка на инстанцирующийся объект (т.к. this может меняться)

    this.someMethod = function() {
        alert("StateA.someMethod");
        dublicate.nextState();
    };
    this.nextState = function() {
        alert("StateA > StateB");
        widjet.onNextState( new StateB(widjet) );
    };
}
StateA.prototype = new State();
StateA.prototype.constructor = StateA;

// второе состояние
function StateB(widjet) {
    var dublicate = this;

    this.someMethod = function() {
        alert("StateB.someMethod");
        dublicate.nextState();
    };
    this.nextState = function() {
        alert("StateB > StateA");
        widjet.onNextState( new StateA(widjet) );
    };
}
StateB.prototype = new State();
StateB.prototype.constructor = StateB;

// "интерфейс" Widget

function Widget() {
    this.someMethod = function() { };
    this.onNextState = function(state) { };
}

// реализация Widget

function Widget1() {
    var state = new StateA(this);

    this.someMethod = function() {
        state.someMethod();
    };
    this.onNextState = function(newState) {
        state = newState;
    };
}
Widget1.prototype = new Widget();
Widget1.prototype.constructor = Widget1;

// использование

var widget = new Widget1(); widget.someMethod(); // StateA.someMethod // StateA > StateB widget.someMethod(); // StateB.someMethod // StateB > StateA

Смена состояний с помощью вызова метода у Widget (из англоязычной версии статьи).

// "интерфейс" State

function AbstractTool() {
    this.moveTo = function(x, y) { };
    this.mouseDown = function(x, y) { };
    this.mouseUp = function(x, y) { };
}

// реализация State

// инструмент "карандаш"
function PenTool(widjet) {
    var dublicate = this;    // ссылка на инстанцирующийся объект (т.к. this может меняться)
    var mouseIsDown = false; // кнопка мыши сейчас не нажата
    var lastCoords = [];     // прошлые координаты курсора мыши

    this.moveTo = function(x, y) { 
        if (mouseIsDown && lastCoords.length) {
            drawLine(lastCoords, [x, y]);
        }
        lastCoords = [x, y];
    };
    this.mouseDown = function(x, y) {
        mouseIsDown = true;
        lastCoords = [x, y];
    };
    this.mouseUp = function(x, y) { 
        mouseIsDown = false;
    };

    function drawLine(coords1, coords2) {
        alert("drawLine: ["+ coords1[0] +", "+ coords1[1] +"] - ["+ coords2[0] +", "+ coords2[1] +"]");
    }

}
PenTool.prototype = new AbstractTool();
PenTool.prototype.constructor = PenTool;

// инструмент "выделение области"
function SelectionTool(widget) {
    var dublicate = this;    // ссылка на инстанцирующийся объект (т.к. this может меняться)
    var mouseIsDown = false; // кнопка мыши сейчас не нажата
    var startCoords = [];    // координаты курсора мыши при нажатии на кнопку

    this.moveTo = function(x, y) { 
        if (mouseIsDown) {
            setSelection(startCoords, [x, y]);
        }
    };
    this.mouseDown = function(x, y) {
        startCoords = [x, y];
        mouseIsDown = true;
    };
    this.mouseUp = function(x, y) { 
        mouseIsDown = false;
    };

    function setSelection(coords1, coords2) {
        alert("setSelection: ["+ coords1[0] +", "+ coords1[1] +"] - ["+ coords2[0] +", "+ coords2[1] +"]");
    }
};
SelectionTool.prototype = new AbstractTool();
SelectionTool.prototype.constructor = SelectionTool;

// реализация Widget

function DrawingController() {
    var currentTool = new SelectionTool(); // активный инструмент

    this.moveTo = function(x, y) {
        currentTool.moveTo(x, y);
    };
    this.mouseDown = function(x, y) { 
        currentTool.mouseDown(x, y);
    };
    this.mouseUp = function(x, y) { 
        currentTool.mouseUp(x, y);
    };

    this.selectPenTool = function() {
        // выбираем инструмент "выделение области" 
        currentTool = new PenTool();
    };
    this.selectSelectionTool = function() {
        // выбираем инструмент "карандаш" 
        currentTool = new SelectionTool();
    };
}

var widget = new DrawingController();

widget.mouseDown(1, 1); widget.moveTo(1, 2); // setSelection: [1, 1] - [1, 2] widget.moveTo(1, 3); // setSelection: [1, 1] - [1, 3] widget.mouseUp(1, 3); widget.moveTo(1, 4);

widget.selectPenTool(); widget.mouseDown(1, 1); widget.moveTo(1, 2); // drawLine: [1, 1] - [1, 2] widget.moveTo(1, 3); // drawLine: [1, 2] - [1, 3] widget.mouseUp(1, 3); widget.moveTo(1, 4);

Wikimedia Foundation.2010.

Полезное

Смотреть что такое "State" в других словарях: