หลังจากที่ผมได้เกริ่นเกี่ยวกับหลักการ 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 ส่วนด้วยกัน
- การจัดการ Apps
- การจัดการ Contact
- ข้อมูลของตัว SmartPhone เอง
แต่จะเห็นว่า Code นี้ยังไม่ได้ใช้หลักการของ SRP เลย ดังนั้นสิ่งที่เราต้องทำคือ เราจะมาลองเปลี่ยน Code ให้สอดคล้องกับหลักการนี้ ขั้นตอนนี้เราเรียกว่า การ Refactor
สิ่งที่ต้องทำก็คือจะใช้เทคนิคการ Refactor ที่ชื่อว่า Extract Class ก็คือเป็นการแยก Code ในส่วนของ Properties และ Methods ที่น่าจะรวมกันเป็น Class ใหม่ได้ออกมา
ดังนั้นเราเราจะได้ Class ใหม่มาเพิ่มอีก 3 Class คือ Apps และ Contacts
- 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”