นักพัฒนาโต้เถียงว่า Access Modifiers เป็นฟีเจอร์ที่ซ้ำซ้อนในการเขียนโปรแกรมสมัยใหม่หรือไม่

ทีมชุมชน BigGo
นักพัฒนาโต้เถียงว่า Access Modifiers เป็นฟีเจอร์ที่ซ้ำซ้อนในการเขียนโปรแกรมสมัยใหม่หรือไม่

การถกเถียงอย่างเข้มข้นได้เกิดขึ้นในชุมชนนักเขียนโปรแกรมเกี่ยวกับว่า access modifiers ประเภท public, protected และ private เป็นฟีเจอร์ที่จำเป็นจริงหรือไม่ในภาษาเชิงวัตถุ การถกเถียงนี้มุ่งเน้นไปที่ว่าโครงสร้างการเขียนโปรแกรมที่ใช้กันอย่างแพร่หลายเหล่านี้เป็นเพียงการทำซ้ำของฟังก์ชัน interface ที่มีอยู่แล้วในภาษาส่วนใหญ่หรือไม่

ความขัดแย้งเริ่มต้นจากข้อกล่าวอ้างที่ว่า access modifiers ถูกคิดค้นขึ้นใน Simula โดยที่นักพัฒนาไม่ได้ตระหนักว่าพวกเขากำลังทำซ้ำฟีเจอร์การกำหนด interface ที่มีอยู่แล้ว ตามข้อโต้แย้งนี้ virtual methods และ subtyping มีความเพียงพอแล้วในการกำหนด interfaces ทำให้ access modifiers เป็นการเพิ่มเติมที่ไม่จำเป็นและถูกนำไปใช้ต่อในภาษาสมัยใหม่เพียงเพื่อความเข้ากันได้แบบย้อนหลัง

ผู้เขียน Library ปกป้อง Access Modifiers เพื่อการควบคุม API

นักพัฒนาหลายคนที่ทำงานกับ libraries และ frameworks ไม่เห็นด้วยอย่างยิ่งกับการมองว่า access modifiers ไม่จำเป็น พวกเขาชี้ให้เห็นถึงประโยชน์ในทางปฏิบัติในการพัฒนาซอฟต์แวร์ในโลกแห่งความเป็นจริง โดยเฉพาะเมื่อสร้าง libraries ที่ต้องการขอบเขตที่ชัดเจนระหว่าง public APIs และรายละเอียดการใช้งานภายใน

นักพัฒนา C# โดยเฉพาะให้ความสำคัญกับวิธีที่ access modifiers ช่วยให้พวกเขา refactor โค้ดด้วยความมั่นใจ เมื่อส่วนภายในของ library ถูกทำเครื่องหมายเป็น private หรือ internal นักพัฒนาจะรู้ว่าพวกเขาสามารถเปลี่ยนแปลงส่วนประกอบเหล่านี้ได้โดยไม่ทำลายโค้ดภายนอกที่ขึ้นอยู่กับ libraries ของพวกเขา สิ่งนี้กลายเป็นสิ่งสำคัญเมื่อดูแลรักษา codebase ขนาดใหญ่เป็นเวลานาน ซึ่งการเข้าใจว่าอะไรสามารถแก้ไขได้อย่างปลอดภัยเทียบกับสิ่งที่อาจทำลาย downstream applications เป็นสิ่งจำเป็น

การแนะนำการควบคุมการเข้าถึงที่ละเอียดมากขึ้น เช่น private protected modifier ของ C# แสดงให้เห็นว่านักพัฒนาบางคนต้องการการควบคุมการเข้าถึงที่ซับซ้อนมากขึ้นแทนที่จะน้อยลง modifier นี้อนุญาตให้เฉพาะ derived types ภายใน assembly เดียวกันเท่านั้นที่เข้าถึง members บางตัวได้ ให้การควบคุมที่ละเอียดต่อ inheritance hierarchies

ประเภทของ Access Modifier ที่กล่าวถึง:

  • Public: สามารถเข้าถึงได้จากทุกที่
  • Protected: สามารถเข้าถึงได้ภายในคลาสและคลาสย่อย
  • Private: สามารถเข้าถึงได้เฉพาะภายในคลาสเดียวกันเท่านั้น
  • Internal ( C# ): สามารถเข้าถึงได้ภายใน assembly เดียวกัน
  • Private Protected ( C# ): สามารถเข้าถึงได้เฉพาะประเภทที่สืบทอดภายใน assembly เดียวกันเท่านั้น

แนวทางของ Python จุดประกายการถกเถียงระหว่างแบบแผนกับการบังคับใช้

การถกเถียงขยายไปถึงแนวทางปรัชญาที่แตกต่างกันในภาษาการเขียนโปรแกรม ความสำเร็จของ Python แม้จะขาด strict private members มักถูกอ้างถึงเป็นหลักฐานว่า access modifiers ไม่ใช่สิ่งจำเป็น อย่างไรก็ตาม การเปรียบเทียบนี้เผยให้เห็นคำถามที่ลึกซึ้งยิ่งขึ้นเกี่ยวกับว่าการควบคุมการเข้าถึงควรถูกบังคับใช้โดย compilers หรือจัดการผ่านแบบแผนทางสังคม

Python มีการใช้งานรูปแบบหนึ่งของ privacy ผ่าน name mangling ด้วย double underscores แต่สิ่งนี้สามารถหลีกเลี่ยงได้ง่าย นักพัฒนาบางคนโต้แย้งว่าแนวทางที่อ่อนนุ่มนี้ทำงานได้ดีเพราะมันส่งสัญญาณความตั้งใจโดยไม่สร้างอุปสรรคที่แข็งแกร่ง คนอื่นๆ ยืนยันว่าการบังคับใช้ในระดับภาษาอย่างชัดเจนป้องกันการใช้งานผิดโดยไม่ตั้งใจและช่วยให้ compiler optimizations ดีขึ้น

มันเป็นสัญญาทางสังคมที่คุณสามารถทำลายได้อย่างแน่นอนหากต้องการ เพียงแค่ต้องใช้งานเล็กน้อย

การถกเถียงเผยให้เห็นว่าแม้ในภาษาที่มี strict access modifiers นักพัฒนาที่มุ่งมั่นมักจะหาวิธีหลีกเลี่ยงข้อจำกัดเหล่านี้ผ่าน reflection, friend declarations หรือกลไกอื่นๆ ได้ สิ่งนี้ทำให้เกิดคำถามว่า access modifiers ให้ความปลอดภัยที่แท้จริงหรือเพียงแค่ทำหน้าที่เป็นราวกั้นสำหรับนักพัฒนาที่มีเจตนาดี

แนวทางเฉพาะตามภาษาโปรแกรมมิ่ง:

  • C++: แบบดั้งเดิมใช้ public/protected/private พร้อมกับการประกาศ friend
  • C/Java: รวมคีย์เวิร์ด sealed/final เพื่อป้องกันการสืบทอด
  • Python: ใช้หลักการตั้งชื่อ (คำนำหน้าด้วยเครื่องหมายขีดล่าง) และการปกปิดชื่อ (เครื่องหมายขีดล่างคู่)
  • Go: โมเดล package-private และ public ที่อิงตามการใช้ตัวพิมพ์ใหญ่
  • Boost Libraries: ใช้ namespace แยกต่างหากสำหรับรายละเอียดการดำเนินงาน

ประโยชน์ด้านประสิทธิภาพและเครื่องมือนอกเหนือจากการควบคุมการเข้าถึง

นอกเหนือจากข้อกังวลเรื่องการออกแบบ API แล้ว access modifiers ยังให้ประโยชน์ในทางปฏิบัติสำหรับ compilers และเครื่องมือพัฒนา Private และ internal members ให้ข้อมูลเพิ่มเติมแก่ compilers เกี่ยวกับรูปแบบการใช้งานโค้ด ช่วยให้เกิดการปรับปรุงประสิทธิภาพ เช่น method inlining ที่อาจไม่ปลอดภัยกับ public methods

สภาพแวดล้อมการพัฒนายังใช้ข้อมูล access modifier เพื่อให้ code completion และเครื่องมือ refactoring ที่ดีขึ้น เมื่อ IDE รู้ว่า members บางตัวเป็น private มันสามารถหลีกเลี่ยงการแนะนำพวกมันในบริบทที่ไม่เหมาะสมและให้ความช่วยเหลือ refactoring ที่แม่นยำมากขึ้น

นักพัฒนาบางคนเสนอว่าระบบที่ใช้ annotation สามารถแทนที่ access modifiers แบบดั้งเดิมได้ในขณะที่ให้ประโยชน์ที่คล้ายกัน Annotations เช่น @internal หรือ @private สามารถส่งสัญญาณความตั้งใจโดยไม่ต้องใช้ language keywords เฉพาะ อาจให้ความยืดหยุ่นมากขึ้นในวิธีการใช้งานการควบคุมการเข้าถึง

ปรัชญา Composition กับ Inheritance

การถกเถียงที่กว้างขึ้นสัมผัสกับคำถามพื้นฐานเกี่ยวกับรูปแบบการออกแบบเชิงวัตถุ ผู้วิพากษ์ access modifiers มักสนับสนุน composition มากกว่า inheritance โดยโต้แย้งว่าหาก inheritance เองมีปัญหา ฟีเจอร์ที่ออกแบบมาเพื่อทำให้ inheritance ปลอดภัยขึ้นก็กลายเป็นสิ่งที่ไม่จำเป็น

อย่างไรก็ตาม นักพัฒนาหลายคนเห็นคุณค่าใน inheritance สำหรับกรณีการใช้งานเฉพาะ โดยเฉพาะเมื่อ base classes ให้การใช้งานบางส่วนที่ derived classes สามารถขยายได้ ในสถานการณ์เหล่านี้ protected members เสนอทางกลางระหว่าง public APIs อย่างสมบูรณ์และรายละเอียดการใช้งานภายในแบบ private อย่างเต็มที่

การถกเถียงเน้นย้ำถึงความตึงเครียดที่เกิดขึ้นอย่างต่อเนื่องในการออกแบบซอฟต์แวร์ระหว่างความบริสุทธิ์ของแนวคิดและประโยชน์ใช้สอยในทางปฏิบัติ แม้ว่า access modifiers อาจทำซ้ำฟีเจอร์ภาษาอื่นๆ ในทางทฤษฎี แต่การยอมรับอย่างแพร่หลายและการพัฒนาอย่างต่อเนื่องแสดงให้เห็นว่าพวกมันแก้ไขปัญหาจริงที่นักพัฒนาเผชิญในการเขียนโปรแกรมประจำวัน

ว่า access modifiers เป็นเครื่องมือสำคัญสำหรับการจัดการความซับซ้อนของโค้ดหรือเป็นเพียงภาระทางประวัติศาสตร์ที่ไม่จำเป็นยังคงแบ่งแยกชุมชนการเขียนโปรแกรม โดยมีข้อโต้แย้งที่ถูกต้องในหลายด้านของคำถามการออกแบบพื้นฐานนี้

อ้างอิง: public/protected/private is an unnecessary feature