มาสร้าง interface ในภาษา Python ภายใน 5 นาทีกันเถอะ
เคยสงสัยกันไหมครับว่าในการเขียนโปรแกรมแบบ OOP (Object Oriented Programming) ในภาษาอื่น เช่น ภาษา Java มีการสร้างสิ่งที่เรียกว่า interface ซึ่งเป็นโครงร่างของ Class ให้ Concrete Class หรือคลาสรูปธรรม พูดง่ายๆก็คือคลาสทั่วไปที่เราใช้งานกันปกติมา implements ไป แล้วในภาษา Python ที่เป็นภาษา OOP อยู่แล้วมีไหม ทำไมไม่ค่อยเห็นคนใช้กันเลย คำตอบก็คือมีครับ แล้วมันมีวิธีการสร้างอย่างไร ว่าแล้วก็ตามไปอ่านกันเลยครับ
การสร้าง Interface ด้วย library abc
ในการสร้าง interface ในภาษา Python สามารถทำได้หลายวิธี แต่จะทำผ่านการใช้งาน library บางตัว ในหัวข้อนี้ผมจะใช้ library abc ในการสร้าง interface ครับ เอาละครับมีวิธีการสร้างอย่างไรบ้าง ลองมาดูตัวอย่างด้านล่างได้เลยครับ
ตัวอย่างการสร้าง interface
from abc import ABC, abstractmethod
class fly_behavior(ABC):
@abstractmethod
def fly():
pass
class Duck(fly_behavior):
def fly(self):
print("I can fly")
if __name__ == '__main__':
red_duck = Duck()
red_duck.fly()
ผลลัพธ์การรัน
I can fly
คำอธิบาย
- ขั้นแรกเราจะต้องนำเข้า library abc ก่อน โดยในที่นี้เราจะใช้แค่บาง Class จาก library abc เท่านั้น ผมจึงใช้ from abc import ABC, abstractmethod
- จากนั้นทำการสืบทอดคลาส ABC ให้กับคลาสที่เราต้องการจะให้เป็น interface ในที่นี้เราต้องการให้คลาส fly_behavior เป็น interface เราจึงต้องให้ fly_behavior สืบทอดคลาส ABC เข้าไป
- ในคลาส fly_behavior มีเมธอด 1 เมธอด คือ fly() ซึ่งเราจะให้เมธอด fly ตัวนี้แหละที่เป็น abstract method หรือก็คือเมธอดที่ต้องให้เอาไป implement ให้กับคลาสรูปธรรม (concrete class) โดยเราสามารถบอกให้ Python รู้ได้ว่านี่คือ abstract method นะ โดยการใส่ @abstractmethod ไว้บนหัวของเมธอดนั้น แต่จะทำแบบนี้ได้ต้อง import เข้ามาก่อน ตามโค้ดด้านบนเลยครับ และเนื่องจากเป็น abstract method เราจึงไม่ต้องใส่โค้ดอะไรลงไปในนี้ ให้ใช้คำสั่ง pass ใส่ลงไปในฟังก์ชันแทน
- สร้างคลาส Duck ขึ้นมา ซึ่งคลาสนี้จะเป็นคลาสรูปธรรม (Concrete Class) นั่นเอง ทีนี้เราจะให้คลาส Duck ของเราไปสืบทอด หรือถ้าในภาษา Java จะใช้ศัพท์ว่า implemented เจ้า interface ของเราก็คือ คลาส fly_behavior นั่นเองครับ
- จากนั้นให้เราทำการ override เมธอด fly และใส่ในส่วนของการทำงานก็จะเป็นอันเสร็จพิธีครับผม
ประโยชน์ของ interface
ในการเขียนโปรแกรมที่ซับซ้อนขึ้นไปนั้น เช่น การทำแอพพลิเคชันใหญ่ๆที่มีฟังก์ชันมากๆ แล้วถ้าแอพของเรามีฟีเจอร์ (Feature) เพิ่มมากขึ้นเรื่อยๆล่ะ ถ้าเราใช้การสืบทอดปกติ เราจะต้องเข้าไปแก้ไขคลาสเดิมทุกครั้งจริงไหมครับ ทีนี้ถ้าเราใช้การแยกคลาสที่เป็นพฤติกรรมออกไป แล้วไปทำเป็น interface แล้วค่อยมา implement ทีหลังล่ะ เช่น เราต้องการสร้างคลาสนกหลากหลายประเภทเลย ไม่ว่าจะเป็นนกกระจิบ เป็ด เหยี่ยว ซึ่งต่างก็มีพฤติกรรมการบิน (Fly Behavior) ซึ่งมีเหมือนๆกัน แต่จะต่างกันตรงที่เป็ดไม่สามารถบินได้ แต่เหยี่ยวหรือนกตัวอื่นอาจจะบินได้ ซึ่งมัน vary ตามชนิดของนก แต่มีพฤติกรรมแบบเดียวกัน ซึ่งมี 2 สภาวะ ก็คือ บินได้ กับ บินไม่ได้ ถ้าเจอปัญหาแบบนี้เราสามารถแยกพฤติกรรมการบิน (Fly Behavior) ออกเป็น interface ได้ ซึ่งหลักการนี้เป็นหนึ่งในการเขียนโปรแกรมแบบ Program to interface ที่เป็นส่วนนึงของหลักการ Design Pattern โดยเราจะไม่ลงลึกในหลักการมากนะครับ
ตัวอย่างการใช้งานจริง
from abc import abstractmethod,ABC
#interface
class Beverage(ABC):
@abstractmethod
def brew():
pass
#Factory
class Barista():
def order(self,x):
if x == "Coffee":
return Coffee()
elif x == "Champagne":
return Champagne()
class Coffee(Beverage):
#override
def brew(self):
print("Brew Coffee")
class Champagne(Beverage):
#override
def brew(self):
print("Brew Champagne")
if __name__ == '__main__':
barista = Barista()
order1 = barista.order("Coffee")
order1.brew()
order2 = barista.order("Champagne")
order2.brew()
ผลลัพธ์การรัน
Brew Coffee
Brew Champagne
คำอธิบาย
จากโค้ดด้านบนเป็นการเขียนให้เข้ากับหลัก Factory Method โดยหลักการของมันก็คือ เราสร้างคลาส Barista ให้เป็นเสมือนโรงงานผลิต object ของคลาสต่างๆ ได้แก่ คลาส Coffee และ Champagne โดยเราทำการสร้าง interface Beverage ขึ้นมา เนื่องจากเรามีพฤติกรรมที่เหมือนกันก็คือ brew เราจึงแยกไปเป็น interface แล้วนำมา implement ให้กับคลาส Coffee และ Campagene จากนั้นเวลาเราจะเรียกใช้งานเราจะเรียกใช้งานผ่านเมธอด order ของ instance ที่สร้างจากคลาส Barista นั่นเองครับ
Note ในภาษา OOP ถ้าเราสร้าง interface ขึ้นมา แล้วทำการ implement ให้กับ concrete class ไหนก็ตาม instance หรือ object ที่สร้างจาก concrete class นั้น สามารถมี Type เป็น interface ที่ implement มาให้ concrete class นั้นได้
สรุป
ในการสร้าง interface ในภาษา Python นั้นสามารถทำได้หลายวิธี เนื่องจากมี library ที่ใช้สำหรับการสร้าง interface อยู่มากมาย เช่น abc , zope interface อื่นๆ ประโยชน์ของการสร้าง interface นั่นมีมากมาย ไม่ว่าจะเป็นความสามารถในการเพิ่ม Feature ใหม่ได้ โดยที่ไม่ต้องรื้อหรือแก้ไขโค้ดเก่า หรือที่เรียกกันว่าการเขียนโปรแกรมแบบ Program to interface นั่นเอง และยังสามารถช่วย Developer ในการ maintenance หรือรักษา software ได้ง่ายอีกด้วย สำหรับบทความนี้ผมก็ขอจบลงแต่เพียงเท่านี้ หวังว่านักอ่านทุกท่านจะได้ความรู้ไปเป็นอย่างดี สำหรับวันนี้ผมก็ขอลาไปก่อน เจอกันบทความหน้า สวัสดีครับ
See you next time!!
References
https://docs.python.org/3/library/abc.html
https://www.python-course.eu/python3_abstract_classes.php