الگوی طراحی state در جاوا اسکریپت

الگوی طراحی state در جاوا اسکریپت نوشته شده در   javascript 2 دسامبر , 2018 توسط  عباس حسینی

تا به حال به ساختار منظم کارکرد چراغ های راهنمایی در خیابان ها توجه کرده اید ! چراغ هایی که بین سه حالت زرد، نارنجی و قرمز تغییر حالت میدهند

شما روزانه از الگوی state بهره برده اید بدون آنکه از مطلع باشید در ادامه خواهید دید که ارتباط چراغ های راهنمایی با الگوی طراحی state چیست

تعریف الگوی طراحی state در جاوا اسکریپت

javascript state pattern الگویی است که در آن رفتار یک شی متناسب با state آن تغییر میکند مثلا چراغ راهنمایی را در نظر بگیرد وقتی state یک چراغ به سبز تغییر میکند رنگ آن نیز متناسب با آن تغییر حالت میدهد

قطعا این سوال در ذهن شما شکل گرفته که تغییر state یک شی چگونه باعث تغییر رفتار آن میشود در پاسخ باید بگویم که اگر به تعاریف شی گرایی بازگردیم هر شی یک سری رفتار و ویژگی هایی دارد .

مثلا یک شخص را در نظر بگیرد وقتی شخصی به خواب میرود انتظار بی حرکت بودن را از او داریم و وقتی شخص بیدار است طبیعتا انتظار داریم در حال حرکت باشد

الگوی طراحی state جاوا اسکریپت

اگر به نمودار این الگو دقت کنید دو عنصر اصلی در آن حضور دارند که با توجه به مثال چراغ راهنمایی توضیحاتی درباره هر یک میدهم :

context : به یکی از state ها اشاره دارد و به آنها اجازه میدهد که در state داخلی اش تغییر ایجاد کنند – در این مثال context همان چراغ راهنمایی است که در ابتدا state سبز را میگیرد و به آن اجازه میدهد که state اش را مثلا به نارنجی یا قرمز تغییر دهد

client  : عملی است که منجر به تغییر state میشود که در اینجا متد next یعنی حالت بعدی میباشد
state : در این مثال چراغ قرمز، سبز و نارنجی میباشد

در شکل بالا به یک چیز دقت ویژه کنید که نکته کلیدی پیاده سازی این الگو است هر state میتواند در currentState مربوطبه context  تغییر ایجاد کند

الگوی state تغییری در مفهوم شی ایجاد نمیکند بلکه روشی برای پیاده سازی این فعل و انفعالات به ما پشنهاد داده است که در ادامه بررسی خواهیم کرد

نحوه پیاده سازی الگوی طراحی state در جاو اسکریپت

برای پیاده سازی state pattern در جاوا اسکریپت من قصد دارم مثال چراغ راهنمایی را توضیح دهم و آن را پیاده سازی کنم

فرض کنید میخواهیم چراغ راهنمایی ای پیاده سازی کنیم که وقتی state آن به سبز ، قرمز و نارنجی تغییر میکند رنگ چراغ نیز متناسب با آن state تغییر حالت میدهد

خب بدون استفاده از این الگو اولین چیزی که به ذهن شما میرسد چیزی شبیه به این است


if (this.status == 'green') {
    //light is green
} else if (this.status == 'orange') {
    //light is orange
} else if (this.status == 'red') {
    //light is red
}

اما خب استفاده از این روش مشکلاتی دارد اول اینکه به ازای هر شرط باید پیاده سازی جدا داشته باشید و وابستگی بین state چراغ راهنمایی به وجود می آید و البته با توجه به بالا رفتن تعداد state ها شرط های موجود هم به همان میزان افزایش پیدا میکند بنابراین الگوی state به ما میگوید که هر state به صورت کلاس جدا گانه ای پیاده سازی شود

برای شروع نیاز به یک context داریم که در اینجا کلاس TrafficLight میباشد و نکته ای که وجود دارد خود این کلاس باید دارای دو متد باشد

اول متد change که قرار است برای تغییر  currentState آن استفاده شود و متد start که نقش client را ایفا کرده و تعیین میکند که چه عملی باید صورت گیرد


class TraficLight {
    constructor (light){
      this.currentState = new GreenState(this);
    }
    change (nextState){
      this.currentState = nextState
    }
    start (){
      setInterval (()=>{
        this.currentState.next()
      },۱۰۰۰)
    }
  }
  

و در ادامه سه کلاس GreenState و RedState و OrangState وجود دارند که هرکدام از کلاس State به ارث برده و دارای یک متد به نام next میباشند که قرار است در آینده توسط کلاینت مورد استفاده قرار گیرد تا منجر به تغییر currentState در context (چراغ راهنمایی) بشوند


class State {}

class OrangeState extends State{
  constructor (light) {
    super()
    this.status = 'orange';
    this.light = light
  }
  next() {
    this.light.change(new RedState( this.light))
  }
}

class RedState extends State {
  constructor (light) {
   super()
    this.status = 'red'
    this.light = light
  }  
  next() {
    this.light.change( new GreenState( this.light))
  }
}

class GreenState extends State {
  constructor (light) {
    super()
    this.status = 'green';
    this.light = light;
  }  
  next() {
    this.light.change(new OrangeState( this.light)) ;
    
  }
}

در ادامه نیز حالت تکمیلی آن را میتوانید مشاهده کنید

See the Pen Javasccript State Pattern by abbas hosseini (@abizebel) on CodePen.

موارد استفاده از الگوی state در جاوا اسکریپت

استفاده از این الگو به ما کمک میکند که در ابتدا state های احتمالی را پیش بینی کرده و همچنین نحوه سوئیچ کردن هر یک را بررسی و به عنوان یک state مجزا پیاده سازی کنیم و نهایتا هر state به صورت جدا کپسوله شده و مورد استفاده قرار میگیرد

به تعیین تمام state های احتمالی enumeration و به تصمیم گیری برای نحوه سئیچ state ها به یکدیگر transition میگویند

لیست الگوهای طراحی GOF در جاو اسکریپت

 

Creational Patterns

 

Structural Patterns

 

Behavioral Patterns