การเขียนโปรแกรมแบบวัตถุวิธีในภาษาซีชาร์ป (OOP with C#) ตอนที่ 1

การเขียนโปรแกรมแบบวัตถุวิธีในภาษาซีชาร์ป (OOP with C#) การออกแบบและเขียนโปรแกรมแบบวัตถุวิธี (Object Oriented Programming: OOP ออพเจ็กต์โอเรียนเท็ดโปรแกรมมิง) ตั้งอยู่บนหลักการสามประการที่เปรียบได้กับสามเสาหลัก ประกอบด้วย หลักการเอนแคปซูเลชัน (Encapsulation) อินเฮียริแตนซ์ (Inheritance) และโพลิมอร์ฟิสซึม (Polymorphism) หากท่านเข้าใจหลักการทั้งสามนี้ ก็เท่ากับว่าท่านเข้าใจหัวใจของ OOP ทั้งหมดแล้ว
การเขียนโปรแกรมแบบวัตถุวิธีในภาษาซีชาร์ป OOP
ทักษะ (ระบุได้หลายทักษะ)

การออกแบบและเขียนโปรแกรมแบบวัตถุวิธี
(Object Oriented Programming: OOP ออพเจ็กต์โอเรียนเท็ดโปรแกรมมิง)

ตั้งอยู่บนหลักการสามประการที่เปรียบได้กับสามเสาหลัก ประกอบด้วย หลักการเอนแคปซูเลชัน (Encapsulation) , อินเฮียริแตนซ์ (Inheritance) และ โพลิมอร์ฟิสซึม (Polymorphism) หากท่านเข้าใจหลักการทั้งสามนี้ ก็เท่ากับว่าท่านเข้าใจหัวใจของ OOP ทั้งหมดแล้ว

บทความตอนนี้ผู้เขียนจะอธิบายหลักการเอนแคปซูเลชันเบื้องต้น โดยจะอธิบายความหมาย วิธีใช้งาน และ วิธีเขียนโค้ดในภาษาซีชาร์ปเพื่อใช้หลักการนี้ การทำเอนแคปซูเลชัน ทำได้โดยการนิยามคลาส และ เรียกใช้สมาชิกของคลาส ผู้เขียนจะแสดงโค้ดที่เขียนโดยไม่ใช้หลักการ OOP เปรียบเทียบกับ โค้ดงานเดียวกันแต่เขียนตามหลักการ OOP เพื่อให้ท่านเห็นภาพเปรียบเทียบได้อย่างชัดเจน

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

คำว่าข้อมูลในที่นี้หมายถึงตัวที่ทำหน้าที่เก็บข้อมูล อาทิ ตัวแปรธรรมดา อาเรย์ ลิงค์ลิสต์ สตรัคเจอร์ คิว และโครงสร้างข้อมูลอื่น ๆ ส่วนคำว่าโค้ดหมายถึงฟังก์ชัน (อย่างฟังก์ชันในภาษาซี) หรือเมธอดในภาษาจาวาและซีชาร์ป ในภาษาที่ไม่ได้ถูกออกแบบมาให้เขียนโปรแกรมแบบ OOP การนำข้อมูลและโค้ดมารวมไว้เป็นหน่วยเดียวกันไม่สามารถทำได้หรือทำได้แต่ไม่สะดวกนัก เช่นภาษาซี ขณะที่ภาษาซึ่งถูกออกแบบมาให้เป็น OOP โดยตรงอย่างภาษาซีชาร์ปสามารถทำได้ง่ายมาก

โปรดพิจารณาโค้ดต่อไปนี้

ตัวอย่างโค้ดภาษาซีที่เขียนแบบไม่เป็น OOP

โปรแกรมนี้เป็นตัวอย่างโค้ดที่ควบคุมการทำงานเครื่องจักร จะเห็นว่ามีทั้งส่วนที่เป็นโค้ด คือฟังก์ชัน run (บรรทัดที่ 14 ถึง 18) และฟังก์ชัน stop (บรรทัดที่ 19 ถึง 23) และมีส่วนที่เป็นข้อมูลคือตัวแปรชื่อ isRun (ถูกประกาศไว้ในบรรทัดที่ 6 และถูกเปลี่ยนแปลงค่าในบรรทัดที่ 16 และ 21)

นี่เป็นตัวอย่างโค้ดในภาษาซีที่เขียนแบบไม่เป็น OOP และไม่ได้ใช้หลักการเอนแคปซูเลชัน ข้อมูลและโค้ดปนกันอยู่อย่างกระจัดกระจาย ไม่ได้ผนึกไว้เป็นก้อนเดียวกัน

เมื่อต้องการควบคุมเครื่องจักรเราจะใส่โค้ดไว้ใน main (บรรทัดที่ 8 ถึง 13) เพื่อเรียก run และ stop ซึ่งทั้งสองฟังก์ชันนี้จะเปลี่ยนแปลงค่าตัวแปร isRun ที่เป็นตัวแปรโกบัล (global variable ตัวแปรสาธารณะ) ซึ่งเป็นการออกแบบที่ไม่ดีนัก เพราะการใช้ตัวแปรโกบัลในลักษณะนี้ทำให้เราไม่รู้ว่าในขณะหนึ่งๆ ตัวแปร isRun ถูกโค้ดใดเปลี่ยนแปลงค่าไปบ้าง ยากแก่การดีบักโปรแกรม

หากเราต้องการเขียนโปรแกรมนี้ขึ้นใหม่โดยออกแบบให้เป็น OOP เราจะต้องนำส่วนโค้ด (คือฟังก์ชัน run และ stop) และส่วนดาต้า (คือตัวแปร isRun) มาผนึกไว้เป็นก้อนเดียวกัน นั่นคือเขียนขึ้นใหม่โดยใช้หลักการเอนเคปซูเลชันดังนี้

ตัวอย่างโค้ดภาษาซีชาร์ปที่เขียนแบบ OOP
ในโค้ดนี้จะเห็นว่าเรานิยามคลาสชื่อ Control (บรรทัดที่ 20 ถึง 32)  ภายในนั้นมีโค้ดส่วนที่เป็นโปรแกรม (คือฟังก์ชัน run และ stop) ซึ่งทำหน้าที่ประมวลผล และส่วนดาต้า (คือตัวแปร isRun) ซึ่งทำหน้าที่เก็บสถานะของออพเจ็กต์
ในภาษาซีเราเรียกฟังก์ชัน run และ stop ว่าฟังก์ชัน แต่ในภาษาซีชาร์ป เราจะเรียกฟังก์ชันลักษณะนี้ว่าเมธอด (Method) เมธอด run และ stop มีถานะเป็นสมาชิกของคลาส Control ดังนั้นจึงกล่าวได้ว่าโค้ด run และ stop เป็น “เมธอดสมาชิก” (Method member) ของคลาส Control
 

เมธอดสมาชิก

โปรดสังเกตว่าโค้ดส่วนประกาศ เมธอด run (บรรทัดที่ 24) และ stop (บรรทัดที่ 28) มีคำว่า public นำหน้าอยู่ คำนี้ทำหน้าที่บอกให้รู้ว่าโค้ดภายนอกคลาสนี้ จะมองเห็นและสามารถเรียกใช้งานเมธอดทั้งสองนี้ได้ คำว่า public เป็นคีย์เวิร์ดของภาษาซีชาร์ป นี่คือสิ่งที่เรียกว่า “แอกเซสโมดิไฟเออร์” (Access modifier ตัวกำหนดระดับสิทธิการเข้าถึง) ของคลาส และสมาชิกของคลาส และสิ่งอื่น ๆ (อาทิ อีนัม และดิลิเกต)
 
แอกเซสโมดิไฟเออร์มีหลายระดับ ในกรณีที่แอกเซสโมดิไฟเออร์เป็นแบบ public หมายถึงว่าสิ่งนั้นมีระดับป้องกันการเข้าถึงต่ำที่สุด นั่นคือโค้ดใด ๆ ก็สามารถเรียกใช้สิ่งนั้นได้โดยไม่มีเงื่อนไขจำกัดใด ๆ ในขณะที่แอกเซสโมดิไฟเออร์แบบ private จะหมายถึงว่าสิ่งนั้นมีระดับป้องกันการเข้าถึงสูงที่สุด นั่นคือโค้ดใด ๆ จะมองไม่เห็น หรือไม่สามารถเรียกใช้สิ่งนั้นได้เลย ยกเว้นโค้ดที่อยู่ภายในคลาสเดียวกันเท่านั้น
 
ต่อไปให้พิจารณาตัวแปร isRun ในภาษาซีชาร์ปเราจะเรียกตัวแปรลักษณะนี้ว่าดาต้าฟิลด์ (Data field) หรือฟิลด์เฉยๆ ก็ได้ ในโค้ดนี้ฟิลด์ isRun มีถานะเป็นสมาชิกของคลาส Control ดังนั้นจึงกล่าวได้ว่าฟิลด์ isRun เป็น “ฟิลด์สมาชิก” (Field member) ของคลาส Control
 

ฟิลด์สมาชิก

โปรดสังเกตว่าฟิลด์ isRun มีแอกเซสโมดิไฟเออร์เป็นแบบ private จึงมีผลให้โค้ดใด ๆ ก็ตามจะมองไม่เห็น หรือไม่สามารถเข้าถึงตัวแปรนี้ได้เลย ยกเว้นโค้ดที่อยู่ภายในคลาส Control เท่านั้น การเขียนเช่นนี้เป็นการกระทำโดยเจตนา เพราะในหลักการเอนแคปซูเลชัน เราไม่ต้องการให้โค้ดภายนอกมองเห็น หรือสามารถเปลี่ยนแปลงสถานะของตัวแปรภายในออพเจ็กต์ได้โดยตรง
 
เพราะเหตุใดเราจึงไม่ต้องการให้โค้ดภายนอกมองเห็นหรือเปลี่ยนแปลงสถานะของตัวแปรภายในออพเจ็กต์? คำตอบคือในโครงการขนาดใหญ่ มีคลาสจำนวนมาก จะมีนักเขียนโค้ดหลายคนแยกกันเขียนคลาสแต่ละตัว มีผลให้บ่อยครั้งที่ผู้ (เขียนโค้ดเพื่อ) เรียกใช้คลาส (เพื่อไปสร้างออพเจ็กต์) ไม่ใช่โปรแกรมเมอร์คนที่นิยามคลาสนั้น ผู้เรียกใช้คลาสจึงอาจไม่รู้แน่ชัดว่าการเปลี่ยนแปลง สถานะของตัวแปรภายในออพเจ็กต์จะส่งผลกระทบอะไรบ้าง
 
อีกเหตุผลหนึ่งที่เราไม่ต้องการให้โค้ดภายนอกมองเห็นหรือเปลี่ยนแปลงสถานะของตัวแปรภายในออพเจ็กต์คือ ผู้นิยามคลาสอาจไม่อยู่แล้ว (ลาออกไปแล้ว หรือคลาสถูกนำไปใช้ในสภาพแวดล้อมที่ผู้นิยามคลาสไม่ปรากฏ เช่นเราเรียกใช้คลาสของดอตเน็ตเฟรมเวิร์ค) ผู้ที่เรียกใช้คลาสจึงไม่อาจรู้ได้ว่าตัวแปรแต่ละตัวในคลาสทำหน้าที่อะไรบ้าง และอาจส่งผลกระทบอะไรบ้าง
 

หลักการกล่องดำและเชื่อมหลวม

อีกเหตุผลหนึ่งคือ ในการนิยามคลาส เราต้องการให้คลาสมีภาวะเป็น “กล่องดำ” (black box) หมายถึงผู้ใช้ไม่จำเป็นต้องรู้การทำงานภายในของคลาสก็สามารถนำคลาสไปสร้างออพเจ็กต์ใช้งานได้ ผู้ใช้เพียงรู้ว่าคลาสนั้นทำหน้าที่อะไร ใช้ทำอะไรได้บ้าง และจะส่งข้อมูลให้หรือรับข้อมูลออกอย่างไร ในกรณีกลับกัน หากผู้ใช้คลาสต้องเปลี่ยนแปลงสถานะของตัวแปรภายในออพเจ็กต์ ผู้ใช้ก็จำเป็นจะต้องรู้การทำงานภายในคลาสซึ่งเป็นสิ่งที่เราต้องการหลีกเลี่ยงตั้งแต่แรก
อีกเหตุผลหนึ่งคือถ้าเราเขียนโค้ดให้มีส่วนที่เปลี่ยนแปลงสถานะของตัวแปรภายในออพเจ็กต์ หากต้องการเปลี่ยนไปใช้คลาสอื่น ๆ ที่มีลักษณะการทำงานแบบเดียวกัน หรือดีกว่าเราจะทำไม่ได้ทันที จำเป็นต้องแก้ไขโค้ดเสียก่อน นั่นคือโค้ดของเราเชื่อมกับคลาสอื่นอย่างแน่นซึ่งไม่ดี การเขียนโปรแกรมที่ดีควรใช้หลักการเชื่อมหลวม (Loose coupling) เพราะจะทำให้โค้ดของเราไม่ผูกติดกับคลาสอื่น ๆ เมื่อต้องการเปลี่ยนไปใช้คลาสอื่นจะทำได้ง่ายกว่า
 
หลักการ Loose Coupling นี้คู่กับหลักการ High Cohesion เป็นหลักการย่อยของการออกแบบและเขียนโปรแกรมแบบวัตถุวิธีที่นักเขียนโค้ดจำเป็นต้องรู้ ผู้เขียนจะนำเรื่องนี้มาอธิบายโดยละเอียดในโอกาสต่อไป
 

พรอพเพอร์ตี

โค้ดบรรทัดที่ 23 คือนิยามของพรอพเพอร์ตี (property) เป็นสมาชิกของคลาสอีกแบบหนึ่ง (นอกเหนือจากเมทอดและฟิลด์ที่กล่าวถึงไปแล้ว) พรอพเพอร์ตีเป็นสิ่งที่มีเฉพาะในภาษาซีชาร์ป ถูกสร้างขึ้นเพื่อให้โค้ดดูกระชับสวยงามกว่าการใช้เมธอดเกต-เซต อย่างในภาษาจาวา อันที่จริงแล้วพรอพเพอร์ตีก็คือเมธอด แต่เป็นชนิดพิเศษ ทำหน้าที่ให้เราสามารถส่งและรับข้อมูลระหว่างโค้ดของเรากับคลาสได้ ด้วยเหตุนี้บางครั้งพรอพเพอร์ตีจึงถูกเรียกว่าตัวเชื่อมต่อ (interface อินเตอร์เฟส โปรดอย่าสับสนระหว่างคำว่าอินเตอร์เฟสในที่นี้กับอินเตอร์เฟสคลาส เพราะเป็นคนละเรื่องกัน)
 
ในการเขียนโปรแกรมตามหลักการเอนแคปซูเลชัน เมื่อเราต้องการจะอ่านหรือเปลี่ยนแปลงค่าดาต้าฟิลด์ของออพเจ็กต์ เราจะไม่กระทำโดยตรงกับดาต้าฟิลด์ แต่เราจะทำผ่านพรอพเพอร์ตี เหตุผลที่ทำเช่นนั้นเพราะ
ซ่อนรายละเอียด: เราไม่ต้องการรู้รายละเอียดภายในของออพเจ็กต์ เช่นชื่อของดาต้าฟิลด์
ปลอดภัยกว่า: เพราะเราสามารถใส่โค้ดคัดกรองข้อมูลไว้ภายในพรอพเพอร์ตีได้ด้วย
โปรดสังเกตว่าฟิลด์ isRun และพรอพเพอร์ตี IsRun มีชื่อคล้ายกัน ต่างกันเพียงแค่ตัวอักษรตัวแรก การเขียนเช่นนี้เป็นการกระทำโดยเจตนา หลักการตั้งชื่อพรอพเพอร์ตีและฟิลด์คือ พรอพเพอร์ตีและฟิลด์ที่คู่กันจะต้องใช้ชื่อเดียวกัน แต่อักษรตัวแรกของชื่อฟิลด์จะใช้อักษรตัวเล็ก ขณะที่อักษรตัวแรกของชื่อพรอพเพอร์ตีจะใช้อักษรตัวใหญ่
 
ซินเทกซ์ของพรอพเพอร์ตีที่เห็นในโค้ดนี้เป็นแบบใหม่ที่เริ่มมีใช้ตั้งแต่ในเวอร์ชันหกขึ้นไป ในวงเล็บปีกกามีตัวกระทำ => ซึ่งปรกติจะใช้เป็นตัวกระทำแบบเลมบ์ดา แต่ในที่นี้ถูกนำมาใช้ในฐานะ expression-bodied member ที่ผมจะอธิบายในตอนต่อ ๆ ไป ส่วนในตอนนี้ข้อเพียงให้ท่านเข้าใจว่ามันเป็นสิ่งที่ช่วยให้เขียนโค้ดส่วนเกตเซตได้สั้นกระชับ
 
ตามปรกติแล้วเราจะใช้พรอพเพอร์ตีคู่กันกับฟิลด์ แต่มีพรอพเพอร์ตีชนิดหนึ่งที่ท่านไม่จำเป็นต้องนิยามร่วมกันกับฟิลด์ นั่นคือออโตเมติกพรอพเพอร์ตี (Automatic property) ซึ่งเป็นพรอพเพอร์ตีแบบย่นย่อ จะใช้เมื่อเราต้องการรับส่งข้อมูลกับคลาสโดยไม่มีโค้ดคัดกรองหรือประมวลผลใด ๆ ในพรอพเพอร์ตีเลย แม้ออโตเมติกพรอพเพอร์ตีจะช่วยให้โค้ดกระชับขึ้นแต่ก็ต้องใช้ด้วยความระมัดระวัง ผมจะพูดถึงเรื่องนี้อีกทีในรายละเอียดในตอนต่อ ๆ ไป
 

ไคลแอนด์โปรแกรม

สรุปว่าโค้ดบรรทัดที่ 20 ถึง 32 คือนิยามคลาสชื่อ Control เป็นคลาสที่ใช้สำหรับสร้างออพเจ็กต์ (คือไม่ใช่คลาสแบบสเตติกที่เรียกใช้ได้โดยตรง) คลาสนี้มีสมาชิกสี่ตัว เป็นดาต้าฟิลด์หนึ่งตัว พรอพเพอร์ตีหนึ่งตัว และเมธอดสองเมธอด สมาชิกทุกตัวเป็นแบบ public (ยกเว้น isRun) และตัวคลาสเองก็เป็น public ด้วย
ต่อไปดูโค้ดบรรทัดที่ 9 ถึงบรรทัดที่ 19 ซึ่งเป็นนิยามคลาส Program คลาสนี้คือโปรแกรมส่วนที่มีโค้ดเรียกใช้คลาส Control เพื่อนำมาสร้างเป็นออพเจ็กต์ การสร้างออพเจ็กต์จากคลาสมีรายละเอียดปลีกย่อยอีกมากที่ผมจะพูดถึงตอนต่อ ๆ ไป สำหรับในตอนนี้ขอให้ทราบว่าการทำเช่นนี้คือหลักการเอนแคปซูเลชัน อันเป็นหัวข้อของบทความนี้
 
การที่โค้ดส่วน Program มีฐานะเป็นผู้เรียกใช้คลาส จึงได้ชื่อว่าเป็นโค้ดส่วนผู้ใช้ หรือโค้ดส่วนไคลแอนท์ (client) การเขียนโปรแกรมแบบ OOP ท่านจะต้องเขียนโค้ดส่วนไคลแอนท์เพื่อเรียกใช้คลาสจากดอตเน็ตเฟรมเวิร์ค หรือจากเหล่งอื่น ๆ เสมอ และในขณะเดียวกันท่านก็ต้องนิยามคลาสเอง และเรียกใช้คลาสเหล่านี้จากโปรแกรมส่วนไคลแอนท์ด้วยเช่นกัน และโปรดทราบว่าโค้ดของออพเจ็กต์ก็มักเรียกใช้คลาสอื่นสร้างออพเจ็กต์ด้วย ดังนั้นคลาสใด ๆ อาจเป็นโค้ดส่วนไคลแอนท์ได้ด้วยเหมือนกัน
โค้ดบรรทัดที่ 13 ประกาศตัวแปรชื่อ myControl ซึ่งเป็นตัวแปรที่เราจะใช้ทำหน้าที่อ้างอิงไปยังออพเจ็กต์ที่เรากำลังจะสร้าง สำหรับผู้ที่เขียนภาษาซีขอให้เข้าใจว่าตัวแปรนี้ มีภาวะคล้ายๆ ออพเจ็กต์พอยน์เตอร์ คือทำหน้าที่เก็บค่าอ้างอิงของออพเจ็กต์ ส่วนตัวออพเจ็กต์เองเรามองไม่เห็น อยู่ที่ไหนก็ไม่รู้ เรียกใช้โดยตรงก็ไม่ได้ เมื่อต้องการใช้งานจะต้องอ้างถึงผ่านตัวแปรนี้
 

การสร้างออพเจ็กต์

โปรดสังเกตว่าตัวแปร myControl มีดาต้าไทป์เป็น Control ซึ่งก็คือคลาสที่เรานิยามไว้ข้างล่าง จะเห็นว่าเมื่อนิยามคลาสแล้วมันจะมีสภาพเหมือนเป็นไทป์หนึ่งเช่นเดียวกับดาต้าไทป์พื้นฐานของภาษาซีชาร์ป อาทิ int, char, bool ฯลฯ ดังนั้นการนิยามคลาสก็คือการนิยามไทป์ เราสามารถนำมาใช้งานและการปฏิบัติต่อมันได้เหมือนกันกับดาต้าไทป์พื้นฐานแทบจะทุกประการ (มีกรณียกเว้นบ้างดังจะกล่าวถึงในภายหลัง)
โปรสังเกตคำว่า new คำ ๆ นี้เป็นคีย์เวิร์ด เป็นตัวกระทำ (operator) ซึ่งทำหน้าที่สร้างออพเจ็กต์ เมื่อพบคำสั่งนี้ ตัวแปลภาษา (compiler คอมไพเลอร์) จะสร้างออพเจ็กต์โดยจัดสรรเนื้อที่ในหน่วยความจำส่วนที่เป็นฮีพ (heap) เพื่อใช้เก็บข้อมูลและสถานะของออพเจ็กต์ 
 
ถัดจากคำว่า new คือ ConTrol() นี่คือการเรียกใช้เมธอดชื่อ Control ที่เราไม่ได้นิยามไว้ แต่คอมไพเลอร์แอบสร้างไว้ให้ (ไม่ปรากฏในซอร์สโค้ด) มันคือเมธอดพิเศษเรียกว่าคอนสทรักเตอร์ (constructor)   โค้ดบรรทัดที่ 14 เป็นตัวอย่างการเรียนใช้เมธอด run โค้ดบรรทัดที่ 15 เป็นตัวอย่างการใช้งานพรอพเพอร์ตี IsRun ซึ่งจะทำหน้าที่ไปดึงค่ามาจากฟิลด์ isRun อีกทอดหนึ่ง
 
การซ่อนความซับซ้อน จากตัวอย่างโค้ดที่ยกมานี้ ท่านจะเห็นว่าหลักการเอนแคปซูเลชันคือการ ขีดวง เพื่อให้โค้ดแต่ละส่วนแยกกันอย่างชัดเจน โดยให้โค้ดหลาย ๆ ส่วนที่ประกอบขึ้นเป็นงานย่อยผนึกไว้เป็นก้อนเดียวกัน เพื่อให้เรียกใช้งานได้ง่าย นำกลับมาใช้ใหม่ได้ง่าย และนำไปต่อยอดได้ง่าย (ต่อยอดได้อย่างไรจะพูดถึงในตอนอินเฮียริแตนซ์)
 
ในภาษาซีชาร์ปเอนแคปซูเลชันจะทำโดยใช้การนิยามคลาส ในบทความนี้ผมยกตัวอย่างโค้ดที่เขียนแบบไม่เป็น OOP คือเขียนปนกับไปหมดระหว่างโค้ดส่วนหลักกับโค้ดส่วนคุมเครื่องจักร และผมได้แสดงตัวอย่างโค้ดที่เขียนแบบ OOP คือนำโค้ดส่วนควบคุมเครื่องจักรมาใส่ไว้ในคลาส จากนั้นโปรแกรมหลักจะสามารถนำคลาสไปใช้สร้างออพเจ็กต์ได้ โดยออพเจ็กต์จะมีภาวะเหมือนเป็นเครื่องจักรเครื่องหนึ่ง
 
หลักการซ่อนความซับซ้อน (information hiding) เป็นอีกหลักการที่มักถูกพูดถึงควบคู่ไปกับหลักการเอนแคปซูเลชัน จนบางครั้งก็สับสนปะปนว่าเป็นสิ่งเดียวกัน บางคนก็มองว่าเอนแคปซูเลชันเป็นวิธีซ่อนความซับซ้อนอย่างหนึ่ง จะอย่างไรก็ตามประเด็นของทั้งสองหลักการคือเราต้องการให้การเขียนโค้ดที่ยาวและซับซ้อนมาก ๆ ในโครงการขนาดใหญ่สามารถทำได้อย่างรวดเร็วและมีประสิทธิภาพ
 
การผนึกโค้ดส่วนที่มีหน้าที่สัมพันธ์กันไว้เป็นหน่วยเดียวกัน (ในตัวอย่างของบทความนี้คือคลาส) ช่วยให้โค้ดไม่ไปปะปนกับส่วนอื่น ๆ ที่ไม่เกี่ยวข้อง จึงสามารถอัพเกรด ปรับเปลี่ยน แก้ไข ทดสอบ นำกลับมาใช้ใหม่ ต่อยอด ได้ง่าย รวดเร็วกว่า และมีโอกาสผิดพลาดน้อยกว่าการเขียนโค้ดแบบไม่เป็นเอนแคปซูเลชัน หลักการเอนแคปซูเลชัน จึงช่วยให้การพัฒนาซอฟต์แวร์มีประสิทธิภาพมากขึ้น