มันเป็นกลิ่นรหัสหรือไม่ถ้าวิธีส่วนตัวเรียกว่า public หรือไม่?


25

มันเป็นกลิ่นรหัสที่จะเรียกวิธีสาธารณะในวิธีส่วนตัวของอินสแตนซ์วัตถุเดียวกันหรือไม่?


AAMOI คุณมีตัวอย่างที่เฉพาะเจาะจงหรือไม่?
ocodo

ไม่ปัจจุบัน เพิ่งจำกรณีที่ฉันพูดคุยกับเพื่อนร่วมงานของฉัน ต้องการรับความคิดเห็นบางส่วนที่นี่เช่นกัน
Eimantas

5
โดยปกติฉันสามารถหาคำย่อตามบริบท แต่ AAMOI แน่นอนฉันต้องมองหา
Carson Myers

@Carson - คุณเจออะไรเหรอ?
Eimantas

4
ในฐานะที่เป็นเรื่องที่น่าสนใจ
Carson Myers

คำตอบ:


33

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


ฉันเห็นด้วย. บางวิธีมีฟังก์ชั่นการใช้งานที่มีประโยชน์สำหรับทั้งภายในและสำหรับผู้โทรภายนอก ธงสีแดงอาจเป็นได้ว่าวิธีสาธารณะนั้นมีความเฉพาะเจาะจงกับการนำไปใช้ภายใน แต่ถึงแม้จะไม่ใช่ทุกคลาสก็มีเจตนาที่จะซ่อนภายใน ฉันมักมีเลเยอร์ "เครื่องมือ" โครงสร้างข้อมูลที่อยู่ภายใต้เลเยอร์ชนิดคอนเทนเนอร์นามธรรมเช่น - ฉันสามารถใช้รหัสโครงสร้างข้อมูลบางอย่างสำหรับโครงสร้างข้อมูลอื่น ๆ
Steve314

20

กลิ่นรหัส? ใช่ไม่ใช่เรื่องเลวร้าย แต่เป็นตัวบ่งชี้ที่ดีว่าชั้นเรียนอาจมีความรับผิดชอบมากเกินไป

ใช้เป็นสัญญาณว่าชั้นเรียนอาจต้องแตกออกเป็นวัตถุต่าง ๆ วิธีส่วนตัวไม่ควรเรียกวิธีสาธารณะของวัตถุเดียวกันอย่างแน่นอนในการออกแบบ OO ที่สะอาด

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

เช่นเดียวกับกลิ่นของรหัสทั้งหมดนี่คือแรงจูงใจสำหรับการตรวจสอบรหัสเพิ่มเติมหาเหตุผลเข้าข้างตนเองและอาจ refactor แต่ไม่ใช่สาเหตุของการเตือนภัย


5
+1 สำหรับ 'ไม่ใช่สาเหตุของการเตือน' บ่อยครั้งที่เราเห็น 'กลิ่น' และเข้าสู่โหมดการปรับเปลี่ยนทันทีโดยไม่ต้องคิด
Michael K

+1 สำหรับ SRP ฉันเพิ่งวิ่งเข้าไปในกรณีที่มัณฑนากรไม่ทำงานเพราะคลาสตกแต่งถูกเรียกฟังก์ชั่นสาธารณะของตัวเองโดยข้ามมัณฑนากร วิธีแก้ปัญหา: แบ่งชั้นเรียนออกเป็นสองส่วนและฉีดการพึ่งพาที่ตกแต่ง
Jon Hulka

18

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


ทำไม? หากวิธีการสาธารณะที่เขียนทับนำไปสู่ความประหลาดใจอันไม่พึงประสงค์มันเป็นเรื่องสำคัญที่เรียกว่าวิธีการหรือไม่
281377

4
ใช่แล้ว. หากการแทนที่วิธีสาธารณะหนึ่งวิธีนั้นเป็นวิธีสาธารณะอีกวิธีหนึ่งฉันสามารถแทนที่วิธีอื่นนั้นได้เช่นกัน ถ้ามันเป็นการแบ่งวิธีส่วนตัวฉันสามารถ ....
Kim

5
ความประหลาดใจอันไม่พึงประสงค์ที่เกิดจากการเอาชนะวิธีการสาธารณะเป็นกลิ่นรหัสในตัวเอง กลิ่นเหม็นของรหัสจริง
Larry Coleman

Kim: ถ้าวิธีนี้เป็นแบบสาธารณะคุณต้องสมมติว่าคลาสอื่นเรียกวิธีนั้นเช่นกัน ...
281377

@ แลร์รี่: แน่นอน! วิธีการส่วนตัว (ซึ่งมักจะมีข้อสมมติฐานเฉพาะการนำไปใช้) การเรียกใช้วิธีการแบบสาธารณะทำให้มีโอกาสมากขึ้นที่การแทนที่วิธีการแบบสาธารณะจะทำให้สิ่งต่าง ๆ เสียหาย
Kim

5

ฉันไม่คิดว่าเราสามารถแยกแยะได้

ทุกอย่างขึ้นอยู่กับบริบทเป็นอย่างมาก

ฉันอาจจะมีวิธีการสาธารณูปโภคในชั้นเรียนที่ใช้โดยชั้นเรียนอื่น ๆ และยังมีวิธีการส่วนตัวในชั้นเรียนเดียวกัน


5

ไม่ควรทำอย่างอื่นในกรณีนี้ ทำให้วิธีส่วนตัวเป็นสาธารณะหรือวิธีสาธารณะเป็นส่วนตัว? คัดลอกวางรหัสจากวิธีสาธารณะไปยังส่วนตัวหรือไม่


หรือมีวิธีสาธารณะมอบให้กับวิธีส่วนตัว (ใหม่) ซึ่งถูกเรียกโดยวิธีส่วนตัวอื่น ๆ แต่ทำไมตื๊อ
Lawrence Dol

4

ไม่ไม่มีกลิ่นเหม็นที่นี่

ถ้าเราใช้อินเตอร์เฟสของคิวกับ List มันเป็นกลิ่นเหม็นเพียงแค่เรียกฟังก์ชั่น List ที่เหมาะสมเพื่อให้สามารถใช้คิวได้อย่างง่ายดายหรือไม่?

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


2

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

  1. วิธีการสาธารณะอาจมีการทดสอบที่ไม่จำเป็นเมื่อรหัสการดำเนินการของคุณภายใน มันอาจได้รับ UserObj และต้องการทดสอบสิทธิ์ผู้ใช้เช่น

  2. หลังจากการโทรสาธารณะคุณอาจต้องการล็อควัตถุถ้าคุณใช้เธรดดังนั้นภายในคุณจะไม่ต้องการโทรกลับไปที่วิธีการสาธารณะ

  3. มีแนวโน้มที่จะแนะนำข้อผิดพลาดแบบวงกลมและลูปแบบไม่ จำกัด และข้อยกเว้นไม่จำในความคิดของฉัน

  4. ธรรมดาและเรียบง่ายการออกแบบที่ไม่ดีและ "ขี้เกียจ" วิธีการสาธารณะให้การเข้าถึงโลกภายนอก ไม่มีเหตุผลที่จะเดินกลับออกไปข้างนอกเมื่อคุณอยู่ข้างในแล้ว


1
จะเกิดอะไรขึ้นถ้ามีการเรียกใช้เมธอดสาธารณะที่มีอยู่ในคลาสอื่น ๆ ? การทำให้เป็นส่วนตัวจะเป็นการทำลาย โปรดจำไว้ว่าวิธีการสาธารณะจะถูกเรียกโดยคลาสอื่นด้วยเหตุผลอื่นไม่ใช่เฉพาะคลาสนี้ ทำไมจึงมีวิธีสาธารณะ
Michael Durrant

ฉันระบุว่า 'เนื้อหาของวิธีสาธารณะควรถูกนำไปใช้และวางในวิธีส่วนตัว ... ' วิธีสาธารณะจะยังคงอยู่ แต่ทำการโทรไปที่วิธีส่วนตัวใหม่ เช่นเดียวกับวิธีส่วนตัวอื่น ๆ ที่จำเป็นต้องใช้ฟังก์ชันการทำงานเดียวกันซ้ำ
Mark Graham

ดังนั้นคุณกำลังเพิ่มวิธีอื่นโดยไม่มีเหตุผลอื่น - ดีเพราะคุณประกาศว่าเป็น "กลิ่นรหัส" วิธีการไม่มีจุดหมายเป็นกลิ่นรหัสที่เลวร้ายยิ่ง
gnasher729

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

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

2

ลองจินตนาการถึงสิ่งที่ตรงกันข้าม คุณอยู่ในวิธีส่วนตัวและคุณต้องการฟังก์ชั่นในวิธีสาธารณะถ้าคุณไม่สามารถเรียกวิธีสาธารณะนั้นจากวิธีส่วนตัว คุณจะทำอย่างไร

  • สร้างวิธีส่วนตัวที่ซ้ำกันหรือไม่ ไม่
  • สร้างวิธีสาธารณะพิเศษสำหรับโอกาสที่เกิดขึ้น? ไม่
  • โทรหาวิธีส่วนตัวแบบพิเศษที่สามารถเรียกใช้วิธีสาธารณะได้หรือไม่ ไม่
  • สุดยอดบางอย่างที่สามารถทำได้? ไม่

คำตอบนั้นชัดเจนว่าเมื่อคุณต้องการฟังก์ชั่นในวิธีสาธารณะคุณควรจะสามารถเรียกวิธีนั้นจากวิธีการเรียนนี้หรือจากชั้นเรียนอื่น ๆ


1

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

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

ดังนั้นเพื่อตอบคำถามของคุณแน่นอนว่าไม่ใช่รหัสที่แย่หากคุณใช้อย่างถูกต้อง


1

คำถามที่คุณต้องถามตัวเองคือทำไมชั้นเรียนของคุณมีความต้องการเช่นเดียวกับลูกค้าในชั้นเรียนของคุณ โดยปกติชั้นเรียนมีความต้องการที่แตกต่างกันมากจากลูกค้า ใช่แล้วนี่เป็นข้อบ่งชี้ว่าคุณมีเช่นกัน

(a) เปิดเผยบางสิ่งต่อสาธารณะที่ควรเป็นแบบส่วนตัว หรือ

(b) พฤติกรรมของชั้นเรียนไม่แคบพอ (คิดว่าความรับผิดชอบหลักเดียว)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.