เรื่องของตัว S (Single Responsibility) ในหลักการ SOLID

Screen Shot 2560-08-23 at 12.04.58 AM.png

หลังจากที่ผมได้เกริ่นเกี่ยวกับหลักการ SOLID ไปแล้วนั้น วันนี้เราจะมาลองดูกันกับตัวแรกของเรา ซึ่งก็คือตัว S ซึ่งย่อมากจาก Single Responsibility หรือแปลว่า หลักการทำหน้าที่เดียวพอ ซึ่งผมจะขอใช้ตัวอย่างด้วย TypeScript ครับ

Single Responsibility Principle (SRP) นั้นกล่าวถึงการออกแบบ Class ในภาษา Object Oriented เพื่อที่จะทำให้ Class นั้นดูแลและจัดการได้สะดวกมากขึ้น

เริ่มต้น ผมมี Class ตัวอย่างที่ชื่อว่า SmartPhone

class SmartPhone {
   // properties
   private apps : Array<string>;
   private contacts : Array<string>;
   private phoneNumber : string;
   private phoneModel : string;
   private screenWidth : number;
   private screenHeigth : number;

   // methods
   public call( telNum : number){
   }
   public ring(){
   }
   public installApp(appName : string){
      this.apps.push(appName);
   }
   public launchApp(appName : string){
      let app = this.apps.filter(element => element === appName);
   }
   public addContact(contact : string){
      this.contacts.push(contact);
   }
   public getScreenPixel() : number {
      return this.screenWidth * this.screenHeigth;
   }
   public getModel() : string {
      return this.phoneModel;
   }
}

ซึ่งจาก Code ตัวอย่างนี้จะเห็นได้ว่า Class SmartPhone นี้ก็ออกแบบมาตามหลัก OO ระดับหนึ่ง ซึ่งถ้าเรามาดูรายละเอียดดีๆนั้นจะเห็นว่ามันมี 3 ส่วนด้วยกัน

  1. การจัดการ Apps
  2. การจัดการ Contact
  3. ข้อมูลของตัว SmartPhone เอง

แต่จะเห็นว่า Code นี้ยังไม่ได้ใช้หลักการของ SRP เลย ดังนั้นสิ่งที่เราต้องทำคือ เราจะมาลองเปลี่ยน Code ให้สอดคล้องกับหลักการนี้ ขั้นตอนนี้เราเรียกว่า การ Refactor 

สิ่งที่ต้องทำก็คือจะใช้เทคนิคการ  Refactor ที่ชื่อว่า Extract Class ก็คือเป็นการแยก Code ในส่วนของ Properties และ Methods ที่น่าจะรวมกันเป็น Class ใหม่ได้ออกมา

ดังนั้นเราเราจะได้ Class ใหม่มาเพิ่มอีก 3 Class คือ Apps และ Contacts

  1. Class Apps จะเอาการเก็บข้อมูล Array และ Methods การ install กับ launch มาไว้ใน Class นี้
class Apps {
   private apps : Array<string>;
   public install(appName : string){
      this.apps.push(appName);
   }
   public launch(appName : string){
      let app = this.apps.filter(element => element === appName);
   }
}

2. Class Contacts จะเอาไว้จัดการเกี่ยวกับ Contact List

class Contacts {
   private contacts : Array<string>;
   public add(contact : string){
      this.contacts.push(contact);
   }
}

3. Class PhoneInfo เราจะเอามาเก็บข้อมูลทั่วไปเช่น เบอร์โทร ชื่อรุ่น ขนาดหน้าจอ

class PhoneInfo {
   private phoneNumber : string;
   private phoneModel : string;
   private screenWidth : number;
   private screenHeigth : number;
   constructor(model : string){
      this.phoneModel = model;
      this.screenWidth =5;
      this.screenHeigth =10;
   }

   public getModel() : string {
      return this.phoneModel;
   }

   public getScreenPixel() : number {
      return this.screenWidth *this.screenHeigth;
   }
}

ซึ่งเมื่อมาถึงตรงนี้แล้วเราก็ต้องทำการแก้ Class หลักของเราก็คือ Class SmartPhone ให้มาเรียกใช้งานทั้ง 3 Classes นี้

// Smart Phone V2
class SmartPhone {
   private apps : Apps; // เรียกใช้ Class Apps
   private info : PhoneInfo; // เรียกใช้ Class PhoneInfo
   private contacts : Contacts; // เรียกใช้ Class Contacts

   constructor(){
      this.apps =new Apps();
      this.info =new PhoneInfo('S10');
      this.contacts =new Contacts();
   }

   public call( telNum : number){
   }

   public ring(){
   }

   public installApp(appName : string){
       this.apps.install(appName); // เรียกใช้ Method ของ Class Apps
   }

   public launchApp(appName : string){
      this.apps.launch(appName);// เรียกใช้ Method ของ Class Apps
   }

   public addContact(contact : string){
      this.contacts.add(contact);// เรียกใช้ Method ของ Class Contacts
   }

   public getScreenPixel() : number {
      return this.info.getScreenPixel();// เรียกใช้ Method ของ Class PhoneInfo
   }

   public getModel() : string {
       return this.info.getModel();// เรียกใช้ Method ของ Class PhoneInfo
   }
}

หลังจากทำการ Refactor เสร็จก็จะเห็นได้ว่า Class SmartPhone Verion 2 นั้นจะเป็นระเบียบมากขึ้น ไม่ต้องมาเก็บตัวแปรที่เป็น String หรือ Array ที่ไม่เกี่ยวข้องอะไรกับตัว Class นี้เองเลย แต่จะย้ายไปเก็บใน Class ย่อยๆแทนเพื่อที่จะให้ Code นั้นเหมาะสมกับ Class แต่ละ Class จริงๆ

เท่านี้เพื่อนๆก็จบหลักสูตร Single Responsibility Principle กันแล้วครับ หวังว่าจะเป็นประโยชน์กับทุกคน แล้วเจอกันตอนหน้าด้วยหลักการตัว O 🙂

4 thoughts on “เรื่องของตัว S (Single Responsibility) ในหลักการ SOLID”

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s