🧠 State β‰  State Machine: Ρ€Π°Π·Π±ΠΈΡ€Π°Π΅ΠΌ повСдСнчСский ΠΏΠ°Ρ‚Ρ‚Π΅Ρ€Π½, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ часто ΠΏΡƒΡ‚Π°ΡŽΡ‚

🧠 State β‰  State Machine: Ρ€Π°Π·Π±ΠΈΡ€Π°Π΅ΠΌ повСдСнчСский ΠΏΠ°Ρ‚Ρ‚Π΅Ρ€Π½, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ часто ΠΏΡƒΡ‚Π°ΡŽΡ‚

Π₯ΠΎΡ‚Π΅Π» Π½Π°ΠΏΠΈΡΠ°Ρ‚ΡŒ ΠΊΠΎΡ€ΠΎΡ‚ΠΊΠΈΠΉ пост ΠΎ своём любимом ΠΏΠ°Ρ‚Ρ‚Π΅Ρ€Π½Π΅ проСктирования. Но ΠΏΠΎΠΊΠ° разбирался β€” понял, Ρ‡Ρ‚ΠΎ знаю ΠΎ Π½Ρ‘ΠΌ Π³ΠΎΡ€Π°Π·Π΄ΠΎ мСньшС, Ρ‡Π΅ΠΌ Π΄ΡƒΠΌΠ°Π» πŸ˜…. Π’ ΠΈΡ‚ΠΎΠ³Π΅ ΠΊΠΎΡ€ΠΎΡ‚ΠΊΠΈΠΉ пост прСвратился Π² ΠΏΠΎΠ»Π½ΠΎΡ†Π΅Π½Π½Ρ‹ΠΉ Π»ΠΎΠ½Π³Ρ€ΠΈΠ΄ с ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π°ΠΌΠΈ. Π‘ΡƒΠ΄Ρƒ ΠΏΡƒΠ±Π»ΠΈΠΊΠΎΠ²Π°Ρ‚ΡŒ Π΅Π³ΠΎ ΠΏΠΎ кусочкам. Π Π°ΡΡΠΊΠ°Π·Ρ‹Π²Π°ΡŽ, Ρ‡Ρ‚ΠΎ Ρ‚Π°ΠΊΠΎΠ΅ ΠΏΠ°Ρ‚Ρ‚Π΅Ρ€Π½ State, ΠΊΠΎΠ³Π΄Π° Π΅Π³ΠΎ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ, ΠΊΠ°ΠΊ Π½Π΅ ΠΏΠ΅Ρ€Π΅ΠΏΡƒΡ‚Π°Ρ‚ΡŒ Π΅Π³ΠΎ с State Machine. πŸ‘‡

State ΠΏΠ°Ρ‚Ρ‚Π΅Ρ€Π½ ("БостояниС") β€” это повСдСнчСский ΠΏΠ°Ρ‚Ρ‚Π΅Ρ€Π½ проСктирования, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ позволяСт ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Ρƒ ΠΈΠ·ΠΌΠ΅Π½ΡΡ‚ΡŒ своё ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ Π² зависимости ΠΎΡ‚ Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½Π΅Π³ΠΎ состояния. МногиС ΠΎΠΏΠΈΡΡ‹Π²Π°ΡŽΡ‚ этот ΠΏΠ°Ρ‚Ρ‚Π΅Ρ€Π½ Π² контСкстС ΠΏΠ°Ρ‚Ρ‚Π΅Ρ€Π½Π° State Machine ("ΠšΠΎΠ½Π΅Ρ‡Π½Ρ‹ΠΉ Π°Π²Ρ‚ΠΎΠΌΠ°Ρ‚", "Машина состояний") ΠΈ Π½Π΅ Ρ€Π°ΡΡΠΌΠ°Ρ‚Ρ€ΠΈΠ²Π°ΡŽΡ‚ Π² ΠΎΡ‚Ρ€Ρ‹Π²Π΅ ΠΎΡ‚ этой ΠΊΠΎΠ½Ρ†Π΅ΠΏΡ†ΠΈΠΈ. На самом Π΄Π΅Π»Π΅ State ΡΠ°ΠΌΠΎΡΡ‚ΠΎΡΡ‚Π΅Π»ΡŒΠ½Ρ‹ΠΉ ΠΏΠ°Ρ‚Ρ‚Π΅Ρ€Π½ ΠΈ часто ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅Ρ‚ΡΡ нСзависимо.

πŸ“Œ Когда ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ State

ΠŸΠ°Ρ‚Ρ‚Π΅Ρ€Π½ State особСнно ΠΏΠΎΠ»Π΅Π·Π΅Π½ ΠΊΠΎΠ³Π΄Π°:

  • Π›ΠΎΠ³ΠΈΠΊΠ° повСдСния ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° зависит ΠΎΡ‚ Π΅Π³ΠΎ Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Ρ… состояний.
  • Π›ΠΎΠ³ΠΈΠΊΠ° содСрТит мноТСство условных ΠΎΠΏΠ΅Ρ€Π°Ρ‚ΠΎΡ€ΠΎΠ² (if/else, switch), зависящих ΠΎΡ‚ Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π³ΠΎ состояния ΠΈΠ»ΠΈ Π²Π½ΡƒΡ‚Ρ€Π΅Π½Π½ΠΈΡ… Ρ„Π»Π°Π³ΠΎΠ².
  • Π₯ΠΎΡ‚ΠΈΠΌ ΡƒΠ±Ρ€Π°Ρ‚ΡŒ связь ΠΌΠ΅ΠΆΠ΄Ρƒ состояниСм ΠΈ ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ΠΌ.
  • Π•ΡΡ‚ΡŒ мноТСство состояний ΠΈ ΠΎΠ½ΠΈ ΠΌΠΎΠ³ΡƒΡ‚ ΠΌΠ΅Π½ΡΡ‚ΡŒΡΡ со Π²Ρ€Π΅ΠΌΠ΅Π½Π΅ΠΌ.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€Ρ‹:

  • ВСкстовый Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΎΡ€ с Ρ€Π΅ΠΆΠΈΠΌΠ°ΠΌΠΈ: Ρ‡Ρ‚Π΅Π½ΠΈΠ΅, Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅, навигация.
  • Бостояния Π·Π°ΠΊΠ°Π·Π° / ΠΏΠ»Π°Ρ‚Π΅ΠΆΠ°.
  • Π–ΠΈΠ·Π½Π΅Π½Π½Ρ‹ΠΉ Ρ†ΠΈΠΊΠ» ΠΊΡ€Π΅Π΄ΠΈΡ‚Π°/Π·Π°ΠΉΠΌΠ°.
  • Π’Ρ€Π°Π½Π·Π°ΠΊΡ†ΠΈΠΈ ΠΌΠ΅ΠΆΠ΄Ρƒ счСтами.
  • ΠΠΊΡ‚ΠΈΠ²Π½ΠΎΡΡ‚ΡŒ ΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚Π΅Π»ΡŒΡΠΊΠΎΠ³ΠΎ Π°ΠΊΠΊΠ°ΡƒΠ½Ρ‚Π°.

βœ… ΠŸΡ€Π΅ΠΈΠΌΡƒΡ‰Π΅ΡΡ‚Π²Π°, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ ΠΌΡ‹ ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠΌ, ΠΊΠΎΠ³Π΄Π° ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΠ΅ΠΌ State:

  • Π‘ΠΎΠ»Π΅Π΅ чистый ΠΈ структурированный ΠΊΠΎΠ΄ - Π·Π° счСт примСнСния Single Responsibility ΠΈ Open-Closed ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏΠΎΠ² ООП.
  • УмСньшаСм ΡΠ²ΡΠ·Π°Π½Π½ΠΎΡΡ‚ΡŒ ΠΌΠ΅ΠΆΠ΄Ρƒ ΠΊΠΎΠΌΠΏΠΎΠ½Π΅Π½Ρ‚Π°ΠΌΠΈ.
  • Π Π°ΡΡˆΠΈΡ€ΡΠ΅ΠΌΠΎΡΡ‚ΡŒ - Π΄ΠΎΠ±Π°Π²Π»Π΅Π½ΠΈΠ΅ Π½ΠΎΠ²ΠΎΠ³ΠΎ состояния Ρ‚Ρ€Π΅Π±ΡƒΠ΅Ρ‚ минимального измСнСния ΡΡƒΡ‰Π΅ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΡ….
  • Π˜Π½ΠΊΠ°ΠΏΡΡƒΠ»ΡΡ†ΠΈΡ Π»ΠΎΠ³ΠΈΠΊΠΈ.

✍ ΠŸΡ€ΠΈΠΌΠ΅Ρ€ Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ Π½Π° Java

Π•ΡΡ‚ΡŒ нСсколько Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ΠΎΠ² Ρ€Π΅Π°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ ΠΏΠ°Ρ‚Ρ‚Π΅Ρ€Π½Π° State, ΠΎΠ΄ΠΈΠ½ ΠΈΠ· Π½ΠΈΡ… Π½Π°Ρ€ΡƒΡˆΠ°Π΅Ρ‚ Liskov Substitution Principle, Π½ΠΎ Ρ‚Π΅ΠΌ Π½Π΅ ΠΌΠ΅Π½Π΅Π΅ ΠΎΠ½ прСдставлСн Π½Π° мноТСствС рСсурсов. Рассмотрим сначала Π±ΠΎΠ»Π΅Π΅ ΠΏΡ€Π°Π²ΠΈΠ»ΡŒΠ½Ρ‹ΠΉ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚:

1. ΠžΠΏΡ€Π΅Π΄Π΅Π»ΡΠ΅ΠΌ интСрфСйс состояния:

public interface EditorState { void handle(TextEditor context); }

2. ΠšΠΎΠ½ΠΊΡ€Π΅Ρ‚Π½Ρ‹Π΅ состояния Ρ€Π΅Π°Π»ΠΈΠ·ΡƒΡŽΡ‚ интСрфСйс `EditorState`:

public class ReadingState implements EditorState { @Override public void handle(TextEditor context) { System.out.println("You are in Reading mode. View the document."); System.out.println("Switching to Editing mode."); context.setState(new ReadingState()); } } public class EditingState implements EditorState { @Override public void handle(TextEditor context) { System.out.println("You are in Editing mode. Make changes to the text."); System.out.println("Switching to Navigating mode."); context.setState(new NavigatingState()); } } public class NavigatingState implements EditorState { @Override public void handle(TextEditor context) { System.out.println("You are in Navigating mode. Browse through sections."); System.out.println("Switching to Reading mode."); context.setState(new ReadingState()); } }

3. ΠšΠΎΠ½Ρ‚Π΅ΠΊΡΡ‚, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΉ Ρ…Ρ€Π°Π½ΠΈΡ‚ Ρ‚Π΅ΠΊΡƒΡ‰Π΅Π΅ состояниС:

public class TextEditor { // Π’Π΅ΠΊΡƒΡ‰Π΅Π΅ состояниС Ρ€Π΅Π΄Π°ΠΊΡ‚ΠΎΡ€Π° private EditorState currentState; public TextEditor() { this.currentState = new EditingState(); // Π½Π°Ρ‡Π°Π»ΡŒΠ½ΠΎΠ΅ состояниС } public void setState(EditorState state) { this.currentState = state; } public void performAction() { currentState.handle(this); } }

ВСстированиС:

public class Main public static void main(String[] args) { TextEditor editor = new TextEditor(); // Π¦ΠΈΠΊΠ» ΠΏΠ΅Ρ€Π΅ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠΉ состояний for (int i = 0; i < 3; i++) { editor.performAction(); System.out.println("----------------------------"); } } }

Π Π΅Π·ΡƒΠ»ΡŒΡ‚Π°Ρ‚:

Π’Ρ‹ Π½Π°Ρ…ΠΎΠ΄ΠΈΡ‚Π΅ΡΡŒ Π² Ρ€Π΅ΠΆΠΈΠΌΠ΅ рСдактирования. ВноситС измСнСния Π² тСкст. ΠŸΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ Π² Ρ€Π΅ΠΆΠΈΠΌ Π½Π°Π²ΠΈΠ³Π°Ρ†ΠΈΠΈ. ---------------------------- Π’Ρ‹ Π½Π°Ρ…ΠΎΠ΄ΠΈΡ‚Π΅ΡΡŒ Π² Ρ€Π΅ΠΆΠΈΠΌΠ΅ Π½Π°Π²ΠΈΠ³Π°Ρ†ΠΈΠΈ. ΠŸΡ€ΠΎΡΠΌΠ°Ρ‚Ρ€ΠΈΠ²Π°ΠΉΡ‚Π΅ Ρ€Π°Π·Π΄Π΅Π»Ρ‹. ΠŸΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ Π² Ρ€Π΅ΠΆΠΈΠΌ чтСния. ---------------------------- Π’Ρ‹ Π½Π°Ρ…ΠΎΠ΄ΠΈΡ‚Π΅ΡΡŒ Π² Ρ€Π΅ΠΆΠΈΠΌΠ΅ чтСния. ΠŸΡ€ΠΎΡΠΌΠ°Ρ‚Ρ€ΠΈΠ²Π°ΠΉΡ‚Π΅ Π΄ΠΎΠΊΡƒΠΌΠ΅Π½Ρ‚. ΠŸΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ Π² Ρ€Π΅ΠΆΠΈΠΌ рСдактирования. ----------------------------

А Ρ‚Π΅ΠΏΠ΅Ρ€ΡŒ рСализация с Π½Π°Ρ€ΡƒΡˆΠ΅Π½ΠΈΠ΅ΠΌ LSP ΠΏΡ€ΠΈΠ½Ρ†ΠΈΠΏΠ°. Иногда приходится ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ Ρ‚Π°ΠΊΠΎΠ΅ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅, исходя ΠΈΠ· потрСбностСй систСмы ΠΈ бизнСс Π»ΠΎΠ³ΠΈΠΊΠΈ:

public class Main { public static interface DoorState { void open(Door context); void close(Door context); void lock(Door context); } // ΠžΡ‚ΠΊΡ€Ρ‹Ρ‚ΠΎΠ΅ состояниС public static class OpenState implements DoorState { @Override public void open(Door context) { System.out.println("Π”Π²Π΅Ρ€ΡŒ ΡƒΠΆΠ΅ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚Π°!"); } @Override public void close(Door context) { System.out.println("Π”Π²Π΅Ρ€ΡŒ закрываСтся."); context.setState(new ClosedState()); } @Override public void lock(Door context) { System.out.println("НСвозмоТно Π·Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΎΡ‚ΠΊΡ€Ρ‹Ρ‚ΡƒΡŽ Π΄Π²Π΅Ρ€ΡŒ!"); } } // Π—Π°ΠΊΡ€Ρ‹Ρ‚ΠΎΠ΅ состояниС public static class ClosedState implements DoorState { @Override public void open(Door context) { System.out.println("Π”Π²Π΅Ρ€ΡŒ открываСтся."); context.setState(new OpenState()); } @Override public void close(Door context) { System.out.println("Π”Π²Π΅Ρ€ΡŒ ΡƒΠΆΠ΅ Π·Π°ΠΊΡ€Ρ‹Ρ‚Π°!"); } @Override public void lock(Door context) { System.out.println("Π”Π²Π΅Ρ€ΡŒ блокируСтся."); context.setState(new LockedState()); } } // Π—Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½Π½ΠΎΠ΅ состояниС public static class LockedState implements DoorState { @Override public void open(Door context) { System.out.println("Π”Π²Π΅Ρ€ΡŒ Π·Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½Π°, сначала Ρ€Π°Π·Π±Π»ΠΎΠΊΠΈΡ€ΡƒΠΉΡ‚Π΅!"); } @Override public void close(Door context) { System.out.println("Π”Π²Π΅Ρ€ΡŒ ΡƒΠΆΠ΅ Π·Π°ΠΊΡ€Ρ‹Ρ‚Π° ΠΈ Π·Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½Π°!"); } @Override public void lock(Door context) { System.out.println("Π”Π²Π΅Ρ€ΡŒ ΡƒΠΆΠ΅ Π·Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½Π°!"); } } public static class Door { private DoorState currentState; public Door() { this.currentState = new ClosedState(); // ΠΠ°Ρ‡Π°Π»ΡŒΠ½ΠΎΠ΅ состояниС } public void setState(DoorState state) { this.currentState = state; } public void open() { currentState.open(this); } public void close() { currentState.close(this); } public void lock() { currentState.lock(this); } } public static void main(String[] args) { Door door = new Door(); door.open(); // "Π”Π²Π΅Ρ€ΡŒ открываСтся." β†’ состояниС Open door.close(); // "Π”Π²Π΅Ρ€ΡŒ закрываСтся." β†’ состояниС Closed door.lock(); // "Π”Π²Π΅Ρ€ΡŒ блокируСтся." β†’ состояниС Locked door.open(); // "Π”Π²Π΅Ρ€ΡŒ Π·Π°Π±Π»ΠΎΠΊΠΈΡ€ΠΎΠ²Π°Π½Π°, сначала Ρ€Π°Π·Π±Π»ΠΎΠΊΠΈΡ€ΡƒΠΉΡ‚Π΅!" } }

πŸ“Œ Π’Ρ‹Π²ΠΎΠ΄

ΠŸΠ°Ρ‚Ρ‚Π΅Ρ€Π½ State β€” подходящий инструмСнт для управлСния состояниСм ΠΎΠ±ΡŠΠ΅ΠΊΡ‚ΠΎΠ² ΠΈ ΠΎΡ€Π³Π°Π½ΠΈΠ·Π°Ρ†ΠΈΠΈ чистого ΠΊΠΎΠ΄Π°. Π•Π³ΠΎ стоит ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ, ΠΊΠΎΠ³Π΄Π° трСбуСтся Π±ΠΎΠ»Π΅Π΅ слоТная систСма управлСния состояниями с ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΎΠΉ ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠ΄ΠΎΠ², Π²Π°Π»ΠΈΠ΄Π°Ρ†ΠΈΠΈ ΠΈ Π²ΠΈΠ·ΡƒΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΠΈ. Он ΠΏΠΎΠ»Π΅Π·Π΅Π½, ΠΊΠΎΠ³Π΄Π° ΠΏΠΎΠ²Π΅Π΄Π΅Π½ΠΈΠ΅ ΠΎΠ±ΡŠΠ΅ΠΊΡ‚Π° слоТно ΠΈ зависит ΠΎΡ‚ мноТСства состояний. Однако Ссли Π½ΡƒΠΆΠ½ΠΎ явно ΠΎΠΏΠΈΡΡ‹Π²Π°Ρ‚ΡŒ всС Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹Π΅ ΠΏΠ΅Ρ€Π΅Ρ…ΠΎΠ΄Ρ‹ ΠΌΠ΅ΠΆΠ΄Ρƒ состояниями ΠΈ Π²Π°Π»ΠΈΠ΄ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ ΠΈΡ…, стоит ΠΏΠΎΡΠΌΠΎΡ‚Ρ€Π΅Ρ‚ΡŒ Π² сторону ΠΏΠ°Ρ‚Ρ‚Π΅Ρ€Π½Π° State Machine.

Использовали ΠΏΠ°Ρ‚Ρ‚Π΅Ρ€Π½? ΠŸΠΎΡ‚ΠΎΠΌ Ρ‡Π΅Ρ€Π΅Π· ΠΏΠΎΠ»Π³ΠΎΠ΄Π° открывая ΠΏΡ€ΠΎΠ΅ΠΊΡ‚, Π³ΠΎΠ²ΠΎΡ€ΠΈΠ»ΠΈ: "Π”Π° ΠΎΡ‚ΠΊΡƒΠ΄Π° ΠΆΠ΅ это взялось???"

Подпишись на мой канал в telegram

1
ΠΠ°Ρ‡Π°Ρ‚ΡŒ Π΄ΠΈΡΠΊΡƒΡΡΠΈΡŽ