มีคำที่ใช้หรือไม่เมื่อมีการประกาศตัวแปรภายในสู่สาธารณะและสามารถเข้าถึงได้


10

หากมีคนเขียนโค้ดเพื่อให้ตัวแปร $ _fields ภายในสามารถเข้าถึงได้โดยไม่ต้องใช้วิธี getter / setter มีคำที่เหมาะสมที่ใช้อธิบายหรือไม่

บางสิ่งบางอย่างสุภาพพอที่จะใช้กับการจัดการ :)


9
ขาดการห่อหุ้ม?
Oded

@Oded ฉันคิดว่าคุณพูดถูก - การขาด / การห่อหุ้มไม่ดีอธิบายได้ดี
PeterB

สองวลีที่ฉันคิดในขณะที่พยายามตอบคำถามนี้คือ "สิ่งที่ทำให้เป็นนามธรรมรั่ว" และ "การกำหนดขอบเขตแบบหลวม" - แต่ละคนอ้างถึงอะไร (นอกหัวของฉัน)?
PeterB

1
สิ่งที่เป็นนามธรรมคือเมื่อคุณพยายามที่จะทำให้นามธรรมเป็นแนวคิด แต่มันก็ไม่ได้ผล - แนวคิดพื้นฐานยังคงรั่วไหลออกมา (ORMs ผ่าน SQL และเว็บเฟรมเวิร์กผ่าน HTTP / HTML มีแนวโน้มที่จะเป็นนามธรรมรั่วไหล)
Oded

@PeterB - เพื่อเพิ่มคำอธิบายของ Oded ดูสิ่งนี้: joelonsoftware.com/articles/LeakyAbstractions.html
Joris Timmermans

คำตอบ:


30

การเปิดเผยให้สมาชิกที่เป็นส่วนตัวนั้นไม่เคยเป็นสิ่งที่ดีในสังคมที่สุภาพ ...

การปฏิบัตินี้คือการขาดการห่อหุ้ม / ยากจน


6
+1, เอาละ, คุณจะไม่ให้เอกชนของคุณอยู่ในออฟฟิศหรือเปล่า?
StuperUser

6
-1: การห่อหุ้มเกิดขึ้นจริงและเกิดขึ้นได้ดี แต่มันไม่ได้จัดทำเป็นเอกสารโดยใช้ซอร์สโค้ดตามวิธีที่ยอมรับกันโดยทั่วไป บางภาษา (เช่น Python) ขาดตัวแปรส่วนตัวอย่างแท้จริง
S.Lott

6
@Oded: Encapsulation คือการออกแบบแนวคิด ภาษาที่ต่างกันมีการนำแนวคิดไปใช้ต่างกัน ภาษาที่มีการประกาศส่วนตัวอนุญาตให้นำไปใช้งานหนึ่งอย่าง ภาษาโปรแกรมการทำงานที่มีวัตถุไร้รัฐอาจมีการนำไปใช้ที่แตกต่างกัน Python (ซึ่งขาดprivate) ยังมีการนำไปใช้อีกแนวคิดของการห่อหุ้ม
S.Lott

1
@S Lott; Oded - การห่อหุ้มนั้นดีและอาศัยรหัสซึ่งตัวแปรส่วนตัวมักเข้าถึงได้โดยตรงจากคลาสอื่นคือการห่อหุ้มที่ไม่ดี ในหลามคุณทำเช่นนี้โดยการเข้าถึงชื่อ mangled ตัวแปรส่วนตัวของชั้นอื่นหรือละเว้นการประชุมของคำนำหน้าขีดเดียว ( แต่ถ้าทะเยอทะยานของคุณจะทำพฤติกรรมอื่น ๆ จริงๆควรใช้__ชื่อ mangling) ภาษาอื่นอาจมีการห่อหุ้มที่ไม่ดีเช่นการสะท้อนใน Java และตัวชี้ทางคณิตศาสตร์ใน C ++ เพื่อให้ได้ตัวแปรส่วนตัว Python ไม่ได้สร้างรูปแบบให้ยุ่งยาก
dr jimbob

2
@drjimbob: รหัส Python ไม่ค่อยใช้__ชื่อ mangling หากไม่มี__มันการออกแบบยังคงสะท้อนให้เห็นถึงการห่อหุ้มที่ดี การอ้างว่า "สาธารณะ" หมายถึง "การขาดการห่อหุ้ม / การห่อหุ้มไม่ดี" ผิด แนวคิดนี้ยังคงอยู่ รหัสแหล่งที่มาขาดการตกแต่งที่เหมาะสม
S.Lott

10

นอกจากการขาดการห่อหุ้มที่เอ่ยถึงแล้วโดย Oded ขึ้นอยู่กับภาษาการเขียนโปรแกรมและกระบวนทัศน์ของมันก็อาจจะเป็น"ข้อมูลเก่าธรรมดา" (ที่ไม่จำเป็นต้องเป็น antipattern หรือกลิ่นรหัส)



2

มันเรียกว่าถุงสมบัติ

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


2

เรียกว่า "ไม่ปฏิบัติตามมาตรฐานการเข้ารหัสเฉพาะ"

OP เขียนว่า:

ตัวแปรภายใน $ _fields สามารถเข้าถึงได้โดยไม่ต้องใช้วิธี getter / setter

นั่นอาจขัดกับมาตรฐานของคุณและ (อาจ) เป็นกลิ่นรหัส แต่มันก็ไม่ได้เป็นเพียงการห่อหุ้มที่ไม่ดี การเปิดเผยตัวแปรภายใน (เช่นเดียวกับใน "การใช้งานภายในเท่านั้น") เหนือทะเยอทะยานและผู้ตั้งค่าสู่โลกภายนอกจะยิ่งแย่ลงไปอีก

คำถามคือควร$_fieldsจะสามารถเข้าถึงได้สำหรับโลกภายนอก?

ถ้าเป็นเช่นนั้นเรามีกรณีที่คุณจะเพิ่มวิธีการ getter / setter วิธีการเหล่านี้ไม่ได้ห่อหุ้มอะไรเลยนอกจากความจริงที่ว่า$_fieldsเป็นตัวแปรบางชนิด ทั้งนี้ขึ้นอยู่กับภาษาของคุณคุณอาจยังคงรั่วไหลประเภท (รายละเอียดการใช้งาน) ไปยังด้านนอก ไม่ว่าคุณต้องการ getters / setters เสมอหรือเฉพาะเมื่อ "จำเป็น" เป็นปัญหามาตรฐานการเข้ารหัส

หาก$_fieldsควรจะไม่สามารถเข้าถึงได้แล้วดีไม่เข้าถึงได้ ไม่ว่าคุณควรป้องกันไม่ให้ผู้อื่นเข้าถึงในระดับภาษา (ส่วนตัวและเพื่อน) หรือไม่ (ซึ่งอาจช่วยให้การดีบักในบางสถานการณ์) ง่ายขึ้นอีกครั้ง - เป็นปัญหามาตรฐานการเข้ารหัส

ปัญหาของการห่อหุ้มนั้นตั้งฉากกับสิ่งนี้ทั้งหมด การละเมิด encapsulation เป็นไปได้อย่างแน่นอนกับ getters และ setters มันง่ายกว่าที่จะแอบเข้าไปเพราะระฆังปลุกของคนส่วนใหญ่จะไม่ดังเมื่อพวกเขาเห็นกลุ่มผู้ทะเยอทะยานและผู้เซทเทอร์ - รหัสที่ดูเหมือนจะเป็นไปตามแนวทางปฏิบัติที่ดีที่สุด รหัสที่ดีมากอาจแนะนำการอ้างอิงมากขึ้นในรายละเอียดการดำเนินงานภายในกว่าที่เรียกว่าตัวแปรที่เกิดขึ้นไม่ได้ที่จะระบุว่าเป็น$_fieldsprivate

ฉันเป็นแฟนตัวยงของการเปรียบเทียบที่ไม่ดี: การเรียกว่าการห่อหุ้มที่ไม่ดีนั้นเหมือนกับการโทรหาคนที่ถือปืนเป็นฆาตกร



-2

ถ้าวิธี setter / getter ของคุณไม่มีอะไรมากไปกว่านั้น

void setfoo(bar){foo=bar;}
foo getfoo{return foo;}

จากนั้นการสร้างตัวแปร pubic เพียงแค่บันทึกการพิมพ์นอกเคสที่มีความแตกต่าง


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

@Plutor: ถ้านั่นคือทั้งหมดที่วัตถุจะเคยทำ (เช่นเพราะมันหมายถึงข้อความที่ส่งไปยังกระบวนการอื่นหรือบันทึกในฐานข้อมูล) จากนั้นก็ตกลง สิ่งเหล่านั้นเป็นสิ่งที่ควรอนุรักษ์ไว้เป็นอย่างยิ่ง
Donal Fellows
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.