Tutorial

เริ่มต้นการเขียนโปรแกรมแบบ OOP ง่าย ๆ ด้วย Python

By Arnon Puitrakul - 14 มกราคม 2021

เริ่มต้นการเขียนโปรแกรมแบบ OOP ง่าย ๆ ด้วย Python

วันนี้เราลองมาย้อนดู Concept ที่เป็นพื้นฐานที่คนที่เรียนทางคอมพิวเตอร์มา น่าจะได้เรียนกันในปีแรก ๆ เลย นั่นคือ Concept ของ OOP หรือ Object-Oriented Programming หรือ ภาษาไทยเราเรียกว่า การเขียนโปรแกรมเชิงวัตถุ ซึ่งเป็น Concept ที่ใช้ในการเขียนโปรแกรมแบบนึงที่เกิดมานานมากแล้ว และก็ยังคงใช้งานอยู่ในทุก ๆ วันนี้ ซึ่ง วันนี้เราจะพามารีวิวด้วยภาษาชั้นสูงนิดนึงอย่าง Python

บทความนี้เขียนมาเพื่อเป็นพื้นฐานสำหรับคนที่อาจจะยังไม่เคยเรียนมาก่อน หรือ ยังไม่เข้าใจเท่าไหร่ ไม่เหมาะกับคนที่ Advance นาจา

ทำไม เราต้องใช้ OOP ?

เป็นคำถามที่ดี ว่าทำไมเราต้องมาเรียนรู้ Concept ตรงนี้ ทั้ง ๆ ที่ในโลกของการเขียนโปรแกรม การออกแบบโปรแกรม มี Pattern อื่น ๆ ให้เราเรียนเยอะมาก ถ้าเราเคยเขียนโปรแกรมมาก่อน เราอาจจะคุ้นเคย และ เข้าใจว่า จริง ๆ แล้วการเขียนโปรแกรมคือ การแก้ปัญหา ซึ่งหลาย ๆ ครั้งส่วนใหญ่ เรามักจะใช้วิธีที่ซอยปัญหาออกเป็นส่วนเล็ก ๆ และค่อย ๆ แก้มัน

ย้อนกลับไปเมื่อเราเขียนโปรแกรมใหม่ ๆ ปัญหา ที่เราแก้ อาจจะมีขนาดเล็กมาก จบใน 20 บรรทัด หรือไม่เยอะมาก พอที่เราจะ Track ได้อย่างง่ายดาย พอปัญหาที่ใหญ่ขึ้นมาหน่อย เราอาจจะต้องมีการใช้ Code เดิมซ้ำ ๆ หลาย ๆ จุด ง่ายที่สุดคือ เราก็ Copy มันไปแปะเลยสิ แต่ปัญหามันไม่ได้จบแค่นั้น เพราะถ้าเราต้องกลับมาแก้ Code ชุดนั้นใหม่ แล้วยังไง เราก็ต้องไปตามแก้ทั้งหมด ไม่ใช่เรื่องตลกเลยละ เหมือนกับการอึทิ้งไว้ พอวันนึงจะต้องใช้ที่นี้ ก็ต้องมาไล่เก็บที่อึทิ้งไว้ เป็น Technical Debt ที่ไม่ควรจะเกิดขึ้น

ทำให้เกิด Concept ของการ Reuse Code ขึ้นมา เริ่มต้นง่าย ๆ เราอาจจะเขียนเป็น Function แล้วยัดค่าเข้าไป เราก็จะสามารถ Reuse Code ได้ พอหลาย ๆ จุด เข้ามาเรียก Function ที่เราทำขึ้นมา ถ้าเราต้องแก้ Function นั้นที มันไม่ใช่เรื่องง่ายเลย เพราะมันผูกกับส่วนอื่น ๆ ของโปรแกรมอีกเพียบ แก้ที อันที่เราอยากเปลี่ยนอาจจะถูก แต่ Function อื่น ๆ ที่ต่ออาจจะพังไปเลยก็ได้ ทำให้เราก็ต้องเขียน Function ใหม่ไปเรื่อย ๆ จนสุดท้าย มันก็พันกันเป็นเหมือนเส้น Spaghetti หรือเราเรียก Code พวกนี้ว่า Spaghetti Code นั่นเอง

ทำให้เราต้องมองว่าวิธีการออกแบบโปรแกรม และ การเขียนโปรแกรม เพื่อให้เราจัดการกับปัญหาของเราได้ง่ายขึ้น ลดการพันกันระหว่าง Module ให้แต่ละชิ้นแยกออกจากกันได้ง่ายขึ้น ถ้าส่วนนี้มีปัญหา เราแก้ไป มันก็จะไม่ไปกระทบกับอีกส่วน ทนทานต่อการแก้ไข แต่ต้องมีความยืดหยุ่นมากพอที่ทำให้เราดูแล Code ได้อย่างง่ายดาย นี่แหละคือประโยชน์ของ OOP คือ เราออกแบบทุกอย่างเป็น Class และ Object ก็เหมือนเราแยกแต่ละปัญหาเป็น Module ที่เราสามารถแก้ไขได้โดยที่ไม่กระทบกับส่วนอื่นมาก แถมยังทำให้เราสามารถ Reuse Code ได้อย่างมีประสิทธิภาพมากขึ้นผ่าน Concept ที่เรียกว่า Inheritance และ เพิ่มความยืดหยุ่นในการ Reuse Code ด้วย Concept ที่เรียกว่า Polymorphism สั้น ๆ คือ ทำให้เราสามารถเขียนโปรแกรม ที่ดูแลได้ง่ายขึ้น นั่นแหละ

Class & Object

2 คำแรกที่เราอยากจะพามาทำความรู้จัก และ เป็น 2 คำที่คนที่เรียนใหม่ ๆ หลาย ๆ คนมักจะสับสนกันเยอะมากนั่นคือคำว่า Class และ Object ในการออกเขียนโปรแกรมแบบ OOP ตามชื่อเลย เราจะมองทุกอย่างเป็นก้อน เป็นของชิ้นนึง อาจจะ งง เราลองยกตัวอย่างง่าย ๆ เหมือนถ้าเราจะสร้างบ้านสักหลัง ในบ้านของเราก็จะแบ่งเป็นห้อง ๆ แล้วในแต่ละห้อง เราก็จะมีของต่าง ๆ อยู่

แต่ในการสร้างบ้านสักหลังขึ้นมา ไม่ใช่ว่าอยู่ ๆ เราจะเอาไม้ตี ๆ รวมกันแล้วจะกลายเป็นบ้านเลย มันก็ต้องเขียนแบบบ้านขึ้นมาก่อน ว่าบ้านหลังนี้ ควรจะมีขนาดเท่าไหร่ มีสีอะไร ใช้กระเบื้องอะไรเท่าไหร่ เพื่อให้เวลาเราจะสร้างบ้าน เราจะได้ไปซื้อของถูก และ ได้สร้างออกมาได้ตรงที่เราต้องการนั่นเอง ถ้าเทียบกับ OOP แปลนบ้านก็น่าจะเป็น Class และบ้านที่สร้างขึ้นมาจากแปลนนั้นก็จะเป็น Object นั่นเอง (การเปรียบเทียบอาจจะไม่ตรง 100% เราพยายามทำให้เข้าใจง่ายนะ อย่าพึ่งทุบเรา)

class House :
	
    def __init__ (self) :
    	# Constructor Here

ใน Python เราสามารถสร้าง Class ได้จากคำสั่งด้านบน คือ Class แล้วตามด้วยชื่อ Class ที่เราต้องการ ในที่นี้คือ House แต่เราจะเห็นว่า เอ๊ะ ทำไมเราถึงสร้าง Function แปลก ๆ ขึ้นมาตัวนึงด้วยที่ชื่อ __init__ เราเรียก Function ตัวนี้ว่า Constructor หรือคนก่อสร้าง เป็น Function ที่จะทำงานเมื่อ Object ถูกสร้างขึ้นมา โดยทั่วไป เรามักจะใช้ในการ Init ค่าต่าง ๆ ที่เราจะใช้ใน Class นอกจากนั้น มันยังมี Function ที่ทำงานตรงกันข้ามกันด้วยคือ Deconstructor

def __del__ () :
	# Deconstructor Here

Function นี้จะถูกเรียกเมื่อ เราสั่งลบ Object ออกไปก่อนที่ GC มาเอาออกจาก Memory ไป เราอาจจะกำหนดหรือไม่กำหนดก็ได้ ตัวอย่างเช่น ถ้าเราบอกว่า เป็น Class House และ เรากำลังจะรื้อถอนบ้านหลังนี้ออกไป เราอาจจะกำหนดให้ Deconstructor ของบ้านไปเรียก Function ของหมู่บ้านว่า มีบ้านหลังนึงกำลังจะโดน ทุบ นะให้อัพเดทจำนวนบ้านด้วย จริง ๆ มันยังมี Function พวกนี้อีกหลายตัวเลย เดี๋ยวจะไปเล่าข้างล่าง ๆ หน่อยละกัน

4 Concepts in OOP

การที่เราจะบอกว่า การเขียนโปรแกรมแบบนี้มันเป็น OOP จริง ๆ เราจะมี 4 Concept ที่นำมาใช้กันนั่นคือ Encapsulation, Abstraction, Inheritance และ Polymorphism

ถ้าไม่มี 4 Concept นี้เราก็ไม่สามารถบอกได้ว่ามันเป็น OOP แท้ซะทีเดียว ตัวอย่างเช่น Struct ในภาษา C ที่เราสามารถยัดตัวแปรต่าง ๆ ใส่ลงไปใน Struct และเรียกใช้ในก้อนเดียวกันได้ ถามว่า ทำไมเราไม่บอกว่าภาษา C เป็น OOP ก็เพราะมันขาดทั้ง 4 Concept ที่เราว่ามาเลยไงละ เราลองมาดูทีละ Concept กัน

Encapsulation

อันแรกคือ Encapsulation ตามชื่อมันเลยคือ การ เก็บข้อมูลของ Object นั้น ๆ ไว้ข้างใน ทำให้คนอื่นที่อยู่ข้างนอกไม่สามารถ อ่าน หรือ แก้ไข ข้อมูลได้เอง ถ้าจะทำจริง ๆ ก็ต้องทำผ่าน Function ที่เราเขียนไว้ ทำให้เราสามารถควบคุม การเปลี่ยนแปลงของข้อมูลได้อย่างเบ็ดเสร็จ ตัวอย่างเช่น เรามี Object ของบัญชีธนาคารอยู่ เราคงไม่อยากให้ใครก็ไม่รู้มาเปลี่ยนชื่อเจ้าของบัญชีแน่ ๆ ใช่ม่ะ

เราก็จัดการ Encapsulate ค่านี้ไว้ใน Object ทำให้ข้างนอก Object ไม่สามารถเข้ามาแก้ได้เลย แต่ถ้าเราทำแค่นั้น เราก็จะไม่สามารถเข้าถึงชื่อเจ้าของบัญชี เพื่ออ่าน แล้วเอาออกมาดูได้ เราก็จำเป็นที่จะต้องสร้างอาจจะเป็น Function ตัวนึงเพื่อให้มันคืนค่าชื่อเจ้าของบัญชีกลับไปให้คนที่เรียก นั่นทำให้คนนอกไม่สามารถเข้ามาแก้ไขค่าได้เลย หรือถ้าเป็นตัวอย่างอื่น ๆ ที่เราบอกว่า สามารถแก้ไขได้ ก็คือ เราเขียน Function ที่รับค่าที่ต้องการ ใส่เข้าไปใน Function ซึ่งใน Function เราก็สามารถเขียน Validation Function ลงไป หรือ เราอาจจะ Reject ตาม Condition ต่าง ๆ ได้ในที่เดียว โดยที่เราไม่ต้องเขียน Function เช็คพวกนี้หลาย ๆ ที่ตามจุดต่าง ๆ ของ Code ก็ทำให้มันเป็นระเบียบมากขึ้นนั่นเอง

class Account :
	def __init__ (self, account_name) :
    	self.account_name = account_name
        self.amount = 0

เราลองสร้าง Class ที่ชื่อ Account แทนบัญชีขึ้นมา โดยที่ใน Constructor เรากำหนดให้มีการใส่ ชื่อบัญชีเข้าไป เพื่อใส่ในรายละเอียดของบัญชี พร้อมกับ เรากำหนดให้เงินในบัญชีเป็น 0 แหงละ ถ้าเราเปิดบัญชีมาใหม่เลย มันก็ไม่ควรจะมีเงินอยู่

account_a = Account('John Wick')
print(account_a.amount)

ถ้าเราลองสร้าง Account ขึ้นมาสักตัว แล้วเราลองสั่งให้โปรแกรมแสดงยอดเงินของบัญชีนั้นขึ้นมา คิดว่ามันจะเรียกได้มั้ย ลองเดาดู

ถ้าลองแล้วจะเห็นว่า มันทำได้ มันขึ้นว่าเป็น 0 ซึ่งแน่นอน เพราะเรากำหนดลงไปแล้วว่าให้มันเริ่มต้นเป็น 0 แต่เอ๊ะ มันก็ผิดกับ Concept ของการทำ Encapsulation สิ ทำไมเราเรียกมันได้ละ ใน Python เราสามารถกำหนดให้ Function หรือตัวแปรต่าง ๆ Encapsulate หรือเรียกจากข้างนอกไม่ได้ ด้วยการใช้ Underscore 2 ตัวนำหน้าชื่อ เช่น

class Account :
	def __init__ (self, account_name) :
    	self.__account_name = account_name
        self.__amount = 0
    
    def get_amount (self) :
    	return self.__amount

จาก Code ด้านบน จะเห็นว่า เราเติม Underscore ลงไปก่อนชื่อตัวแปรด้วย ทีนี้ลองเอา Code ตัวนี้ไปเขียน แล้วลองเรียกเหมือนเมื่อกี้ดู เราจะเห็นเลยว่ามันเรียกไม่ได้ นั่นก็เป็นเพราะเรา Encapsulate เอาไว้นั่นเอง ถามว่าถ้าเราต้องการค่าจริง ๆ ละ เราจะต้องทำยังไง อย่างที่บอกเราก็อาจจะเขียนเป็น Function เพื่อ Return ค่านั้นกลับไป เราเรียก Function พวกนี้ว่า Getter

print(account_a.get_amount())

เวลาเราเรียก เราก็สามารถเรียกแบบด้านบนได้เลย จะเห็นได้ว่า เราสามารถเรียกได้ แต่พอเราจะแก้ค่า เราก็จะแก้ไม่ได้ นี่แหละคือประโยชน์ของการทำ Getter Function หรือกลับกัน Setter Function คือ Function ที่รับค่าเข้าไปเปลี่ยนแปลงค่าอะไรบ้างอย่างใน Object นั่นเอง

Inheritance

Inheritance หรือ ภาษาไทย เราแปลว่า การสืบทอด ใช่แล้วตามชื่อของมันเลย คือ เราสามารถสืบทอด Class ได้ หมายความว่า ถ้าเราบอกว่า Class B ได้รับการสืบทอดมาจาก Class A หมายความว่า อะไรที่ A มี B ก็จะมีด้วย แต่ไม่ได้บอกว่า B มี และ A ต้องมีได้ เพราะ B อาจจะได้รับการเขียนเพิ่มอะไรบางอย่างเข้าไป เรายกตัวเองเดิมคือ บัญชีธนาคาร ละกัน เวลาเราไปฝาก มันก็จะมี 2 แบบให้เราเลือกด้วยกันคือ ออมทรัพย์ หรือ ฝากประจำ ไม่ว่ามันจะเป็นบัญชีแบบไหน มันก็มีวิธีการฝากและถอนที่เหมือนกันหมด คือทำแบบบัญชีปกติเลย

class Account :
	def __init__ (self, account_name) :
    	self.__account_name = account_name
        self.__amount = 0
    
    def deposit (self, deposit_amount) :
    	self.__amount += deposit_amount
    
    def withdraw (self, withdraw_amount) :
		if withdraw_amount < self.__amount :
			self.__amount -= withdrew_amount
        else:
        	print('Money is not sufficient')

ตัวอย่างนี้ เราสร้าง Class ที่เป็นบัญชีออกมา โดยที่เรากำหนด Constructor เหมือนกับตัวอย่างเมื่อครู่เลย แต่เราเพิ่ม 2 Function เข้าไปคือ Function สำหรับการถอน และ ฝากเข้าไป ทีนี้ ถ้าเราบอกว่าเราอยากจะสร้างบัญชีแบบ ออมทรัพย์ ถ้าเราไม่ใช้ Inheritance Concept เราก็ต้อง Copy Account Class ทั้งหมด และเปลี่ยนชื่อเป็นออมทรัพย์ ซึ่งนั่นทำให้เรามี Code ซ้ำกันไม่ดีแน่ ๆ ทำให้การทำ Inheritance ช่วยให้เราประหยัดเวลาทั้งการเขียน และ การดูแล Code มากขึ้นนั่นเอง

class SavingAccount (Account) :
	def __init__ (self, account_name) :
    	super().__init__(account_name)

ใน Python เราก็สามารถ Inherit Class ได้ด้วยการกำหนดอยู่ข้าง ๆ ชื่อของ Class ลงไปได้เลย พร้อมกับ ถ้า Constructor ของ Class ที่เราสืบทอดมา มันต้องการ Argument เราก็ต้องบอกมันไปเหมือนกัน ถ้าเราสร้าง Class SavingAccount ขึ้นมา แล้วลองเรียก Function withdraw เราก็จะเห็นเลยว่า เราเรียกได้ด้วย ทั้ง ๆ ที่ เราไม่ได้กำหนดลงไปใน SavingAccount เลยแม้แต่บรรทัดเดียว เพราะมันได้รับการสืบทอดลงมาแล้วจาก Account นั่นเอง

Abstraction

Abstraction เป็น Concept ที่อธิบายให้เข้าใจง่ายยากจัง ฮ่า เรายกตัวอย่างละกัน เราบอกว่า เรามี Class ที่อธิบายถึง รถ อยู่ แต่ถ้าเรามองเข้าไปในรถ ปัจจุบันมันก็มีทั้งรถที่ใช้น้ำมัน และ รถที่ใช้ไฟฟ้า สิ่งที่แตกต่างกันคือ เชื้อเพลิงที่ใช้ และวิธีการขับเคลื่อน แต่สิ่งที่เหมือนกันคือ รถ เป็น รถ มันต้องสามารถ Start เครื่อง, ดับเครื่อง และ ขับออกไปได้ ซึ่งในรถแต่ละแบบก็จะมีวิธีที่ไม่เหมือนกันนั่นเอง

class Car :
    def start_engine (self) :
    	pass
    
    def stop_engine (self) :
    	pass
   	
    def move (self) :
    	pass

ใน Class รถ เราก็ต้องบอกไว้แค่ว่า การที่คุณจะเป็นรถได้ คุณจะต้อง Start เครื่อง, ดับเครื่อง และ ขับออกไปได้ แต่ไม่ได้บอกว่า การที่จะทำ 3 อย่างนี้ เราจะต้องทำยังไงบ้าง ให้รถแต่ละแบบไปบอกวิธีกันเอาเอง เราบอกแค่ว่าต้องมี แต่ไม่ได้บอกว่าทำยังไงนั่นเอง

ใน Python เราว่า เขาทำ Concept ตรงนี้ออกไม่ชัดเจนเท่ากับภาษาอื่น ๆ การทำ Abstrction ใน Python เขียนด้วยการสร้าง Function ที่ไม่บอกว่าทำอะไรลงไป ก็คือ Pass แล้วปล่อยจบ Function ไปเลย เมื่อเทียบกับภาษาอื่นที่ถือความ OOP เข้มข้นอย่าง Java อันนั้น มันจะมีสิ่งที่เรียกว่า Interface มาให้เราเลย มันคือการทำ Abstraction ตรง ๆ เลยคือ ถ้าเราบอกว่าเราจะ Implement Interface นั้น ๆ มันจะบังคับให้เรา เขียน Method นั้น ๆ เลย พร้อมกับ เราจะไม่สามารถสร้าง หรือ Inherit Interface ได้เลย ทำได้แต่การเรียกผ่าน Syntax ที่ชื่อว่า Implement เท่านั้น (อันนี้ลองไปอ่านใน Java ดู) แต่ใน Python มันไม่ได้บังคับ การใช้งานก็คือ การทำเหมือน Inheritance เลย

ทำให้ เวลาเราเอา Abstract Class ใน Python ออกมาใช้ ให้ระวัง ว่าเราควรจะ Implement ทุก Function ที่กำหนดไว้ใน Abstract Class ให้หมด และอาจจะเขียนอะไรกันไว้หน่อย เผื่อเราลืมเขียน แล้วเราเรียก มันจะได้ไม่พังไปหมด

Polymorphism

และมาถึง Concept สุดท้ายคือ Polymorphism อันนี้ก็อธิบายยากเหมือนกัน ถ้าเราเอาชื่อมันมาแปล Poly ก็คือ หลาย เหมือน Polygon คือ รูปหลายเหลี่ยม หรือ Polysaccharide ไปแปลกันเอา ส่วน Morphic ก็คือ รูปร่าง เติม Suffix -ism เข้าไปก็จะกลายเป็นคำนามไป สรุปสอนภาษาอังกฤษหรืออะไร ???

ดังนั้น Polymorphism ก็คือ การมีหลายรูปลักษณ์ นั่นเอง ย้อนกลับไปที่เรื่องของการทำ Inheritance เช่น เราบอกว่า SavingAccount สืบทอดมาจาก Account นั่นทำให้ Class Account เองก็จะมีร่างอีกร่างคือ SavingAccount พูดอีกนัยคือ เราสามารถใช้งาน Account ผ่าน SavingAccount นั่นเอง

นั่นทำให้ SavingAccount มีอะไรที่ Account มีได้ เช่น การมี Method withdraw และ deposit โดยที่ไม่ต้องกำหนดลงใน SavingAccount หรือ เรายังสามารถที่จะ Override การทำงานของ Method ที่ได้รับการสืบทอดได้ด้วยเช่นกัน ง่าย ๆ เลยก็คือการสร้าง Method ที่ชื่อ และ Argument เหมือนกันใน SavingAccount ได้เลย ถ้าเราเรียก Method นั้น มันก็จะไปเรียกอันที่อยู่ใน SavingAccount นั่นเอง หรือเราเรียก Method ที่มา Override การทำงานนี้ว่า Overriding Method

ถามว่า แล้วมันดียังไงการทำแบบนี้ สมมุติว่า เรามี Method ในการคำนวณดอกเบี้ย ซึ่งแต่ละประเภทของบัญชี จะมีการคำนวณดอกเบี้ยที่ไม่เหมือนกัน อาจจะเพิ่มตรงนั้นตรงนี้ อาจจะเป็นโครงการลงทุนไม่เหมือนกัน ก็ได้ดอกเบี้ยไม่เหมือนกันอะไรก็ว่ากันไป  สุดท้ายถ้าเราสร้าง Method ในการคำนวณดอกเบี้ยให้กับ Account แล้วเราก็ไป Overload ในแต่ละ Class ที่ Inherit จาก Account มันก็ต้องเขียนหลายรอบอยู่ดี ทำไม่เราไม่เอา Method ในการคำนวณออกจาก Account เลยละ

accounts = [account_a, account_b, account_c]
total_interest = 0

for account in accounts :
	total_interest += account.get_yearly_interest()

ยกตัวอย่างง่าย ๆ เลย สมมุติว่า เรามี List ของบัญชีอยู่ ซึ่งแต่ละบัญชี เป็นคนละประเภทกัน ถ้าเราอยากรู้ว่าดอกเบี้ยทั้งหมดที่ธนาคารต้องจ่ายเท่าไหร่ ถ้าเราไม่ใส่ Method ในการคำนวณบัญชีลงไปด้วย เกิดเรา Loop ผ่าน Object ที่สร้างมาจาก Class ที่ไม่มี Method ในการคำนวณ หรือ ใช้คนละชื่อละ มันก็จะ Error ไปตามระเบียบ

ไหน ๆ ก็พูดถึง Overriding Method แล้ว มีอีกคำที่ใกล้เคียงกันคือ Overloading Method มันคือ Method ที่ชื่อเหมือนกัน แต่รับ Argument ไม่เหมือนกัน ง่าย ๆ Method ชื่อ print_name อันนึงเราอาจจะรับ ชื่อ เว้นวรรค นามสกุลมา กับอีก Method ชื่อเดียวกันเลย แต่เรารับชื่อ และ นามสกุลเป็น 2 Argument เวลาเราเรียก เราก็ต้องใส่ให้ Argument ให้ถูกเท่านั้นเอง

สรุป

OOP (Object-Oriented Programming) เป็น Concept การเขียนโปรแกรมที่มองทุกอย่างเป็นวัตถุ เพื่อให้เราสามารถซอยปัญหาออกเป็นชิ้นเล็ก ๆ ได้ง่ายขึ้น, ลดความซ้ำซ้อนของ Code ได้อย่างมีประสิทธิภาพ นั่นส่งผลให้ดีในเรื่องของการดูแลที่ง่าย ซึ่ง OOP ได้รับความนิยมมาอย่างช้านาน และถูกใช้ในหลาย ๆ ภาษาเช่น Java, PHP และ Python นิดหน่อยที่เราเอามาเล่าให้อ่านกันในวันนี้ ซึ่งการที่มันจะเป็น OOP ได้นั้นมันจะต้องมี 4 Concept ด้วยกันคือ Encapsulation, Abstraction, Inheritance และ Polymorphism ที่วันนี้เราเอามาเล่าหมดแล้ว อ่านแล้ว อาจจะ งง เราแนะนำให้ลองเขียนดูน่าจะทำให้เข้าใจได้ง่ายขึ้นเยอะ

Read Next...

จัดการเรื่องแต่ละมื้อ แต่ละเดย์ด้วย Obsidian

จัดการเรื่องแต่ละมื้อ แต่ละเดย์ด้วย Obsidian

Obsidian เป็นโปรแกรมสำหรับการจด Note ที่เรียกว่า สารพัดประโยชน์มาก ๆ เราสามารถเอามาทำอะไรได้เยอะมาก ๆ หนึ่งในสิ่งที่เราเอามาทำคือ นำมาใช้เป็นระบบสำหรับการจัดการ Todo List ในแต่ละวันของเรา ทำอะไรบ้าง วันนี้เราจะมาเล่าให้อ่านกันว่า เราจัดการะบบอย่างไร...

Loop แท้ไม่มีอยู่จริง มีแต่ความจริงซึ่งคนโง่ยอมรับไม่ได้

Loop แท้ไม่มีอยู่จริง มีแต่ความจริงซึ่งคนโง่ยอมรับไม่ได้

อะ อะจ๊ะเอ๋ตัวเอง เป็นยังไงบ้างละ เมื่อหลายเดือนก่อน เราไปเล่าเรื่องกันขำ ๆ ว่า ๆ จริง ๆ แล้วพวก Loop ที่เราใช้เขียนโปรแกรมกันอยู่ มันไม่มีอยู่จริง สิ่งที่เราใช้งานกันมันพยายาม Abstract บางอย่างออกไป วันนี้เราจะมาถอดการทำงานของ Loop จริง ๆ กันว่า มันทำงานอย่างไรกันแน่ ผ่านภาษา Assembly...

Monitor การทำงาน MySQL ด้วย Prometheus และ Grafana

Monitor การทำงาน MySQL ด้วย Prometheus และ Grafana

นอกจากการทำให้ Application รันได้แล้ว อีกเรื่องที่สำคัญไม่แพ้กันคือการวางระบบ Monitoring ที่ดี วันนี้เราจะมาแนะนำวิธีการ Monitor การทำงานของ MySQL ผ่านการสร้าง Dashboard บน Grafana กัน...

เสริมความ"แข็งแกร่ง" ให้ SSH ด้วย fail2ban

เสริมความ"แข็งแกร่ง" ให้ SSH ด้วย fail2ban

จากตอนที่แล้ว เราเล่าในเรื่องของการ Harden Security ของ SSH Service ของเราด้วยการปรับการตั้งค่าบางอย่างเพื่อลด Attack Surface ที่อาจจะเกิดขึ้นได้ หากใครยังไม่ได้อ่านก็ย้อนกลับไปอ่านกันก่อนเด้อ วันนี้เรามาเล่าวิธีการที่มัน Advance มากขึ้น อย่างการใช้ fail2ban...