มันเป็นการปฏิบัติที่ไม่ถูกต้องหรือไม่ที่จะมีส่วนต่อประสานเพื่อกำหนดค่าคงที่หรือไม่?


40

ฉันกำลังเขียนคลาสชุดทดสอบ Junit ใน Java มีค่าคงที่หลายค่าเช่นสตริงที่ฉันต้องการในคลาสทดสอบที่แตกต่างกัน ฉันกำลังคิดเกี่ยวกับอินเทอร์เฟซที่กำหนดพวกเขาและทุกชั้นทดสอบจะใช้มัน

ประโยชน์ที่ฉันเห็นมี:

  • เข้าถึงค่าคงที่ได้ง่าย: MY_CONSTANTแทนThatClass.MY_CONSTANT
  • แต่ละค่าคงที่กำหนดเพียงครั้งเดียว

วิธีนี้ค่อนข้างดีหรือไม่ดี? ฉันรู้สึกว่าใช้แนวคิดของอินเตอร์เฟสแบบไม่เหมาะสม

คุณสามารถตอบโดยทั่วไปเกี่ยวกับอินเทอร์เฟซ / ค่าคงที่ แต่ยังเกี่ยวกับการทดสอบหน่วยหากมีบางสิ่งที่พิเศษเกี่ยวกับมัน


คำตอบสำหรับ "มันเป็นวิธีปฏิบัติที่ไม่ดีที่มีอินเทอร์เฟซกำหนด X?" เป็น X อะไรที่ไม่ใช่ "ลายเซ็นของวิธีการ" มักจะแน่นอน "ใช่"
T. Sar - Reinstate Monica

คำตอบ:


79

Joshua Bloch ให้คำแนะนำกับเรื่องนี้ในหนังสือของเขาJava ที่มีประสิทธิภาพ :

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

คุณสามารถรับเอฟเฟกต์เดียวกันกับคลาสปกติที่กำหนดค่าคงที่แล้วใช้ import static com.example.Constants.*;


13

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

ค่าคงที่ SOMETIMES เป็นรายละเอียดการใช้งาน บางครั้งพวกเขาไม่ได้ ตามปกติวิศวกรต้องใช้สมองของเขาในการตัดสินใจว่าจะทำอย่างไรและไม่ต้องพึ่งพารูปแบบหรือการปฏิบัติแบบกวาด


7

ผมไม่คิดว่ามันเป็นสิ่งที่ดีที่มีอินเตอร์เฟซเท่านั้นสำหรับค่าคงที่

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

ยกตัวอย่างเช่นอินเตอร์เฟส java.awt.Transparency มันมีค่าคงที่ OPAQUE, BITMASK และ TRANSLUCENT แต่ยังมีเมธอด getTransparency ()

หากผู้ออกแบบใส่ค่าคงที่เหล่านั้นไว้ที่นั่นก็เพราะเขา / เธอคิดว่ามันจะมีเสถียรภาพพอที่จะเป็นส่วนหนึ่งของส่วนต่อประสานได้เนื่องจาก getTransparency () นั้น


2

คิดว่ามันเป็นมุมมองที่ได้รับความนิยมส่วนใหญ่ในสถานที่ที่มีการออกแบบตามสัญญาเป็นหลัก
การเชื่อมต่อเป็นสัญญา การวางค่าคงที่ในส่วนต่อประสานหมายถึงคลาสทุกคลาสที่ปฏิบัติตามสัญญายอมรับค่า / แนวคิดที่ระบุโดยค่าคงที่


1
ส่วนต่อประสานเป็นสัญญาสาธารณะ ค่าคงที่เป็นความกังวลส่วนตัวอินเทอร์เฟซสาธารณะอย่างน้อยที่สุดควรเปิดเผยชื่อของพวกเขา นั่นเป็นสิ่งที่ดีที่สุดสำหรับชั้นนามธรรม
jwenting

กรณีในจุด: javax.naming.Context, javax.ims.Session และอินเทอร์เฟซเช่นร้อย ...
CMR

2
@ jwenting เช่นกันส่วนต่อประสานสาธารณะสามารถทำได้"at most expose their names"โดยไม่ต้องเปิดเผยค่าหรือไม่
CMR

นั้นขึ้นอยู่กับภาษาการเขียนโปรแกรมที่ฉันเดา ในกรณีของ Java, no.
jwenting

2

บริษัท ที่ฉันทำงานโดยใช้ค่าคงที่1 ที่นำเข้ามาอย่างต่อเนื่อง ฉันไม่รู้สึกว่าได้รับอันตรายใด ๆ

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

สิ่งที่ยอดเยี่ยมเกี่ยวกับอินเทอร์เฟซคือมันช่วยให้คุณได้รับประโยชน์จากการทำงานอย่างใดอย่างหนึ่ง - นำเนมสเปซทั้งหมดที่คุณต้องการหรือไม่มีเลย (และเข้าถึงได้อย่างชัดเจนด้วยMyInterface.CONSTANT) ค่อนข้างเหมือนกันimport static MyInterface.*แต่เห็นได้ชัดเจนขึ้นเล็กน้อย


1: หากคุณไม่คุ้นเคยกับ Java ฉันไม่ได้หมายถึงimportคำหลักฉันแค่หมายถึงการนำทางimplements MyConstantsInterface


1

ฉันมาจากพื้นหลังที่ได้รับอิทธิพลส่วนใหญ่จาก 'Ada way' และ '.Net way' ฉันจะบอกว่าไม่ว่ามันอาจจะไม่ดีที่สุดที่จะประกาศค่าคงที่ภายในส่วนต่อประสาน มันเป็นเทคนิคที่ไม่ได้รับอนุญาตใน c #

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

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

สำหรับคำแนะนำทางเทคนิคเพิ่มเติม: download.oracle.com/javase/1.5.0/docs/guide/language/static-import.html


การเพิ่มลิงก์เพิ่มเติมที่อ้างอิงถึงการนำเข้าแบบคงที่ (1.5): 1. Wikipedia 2. Oracle Docs ที่อ้างอิง @Justinc
Abhijeet

1
So when should you use static import? Very sparingly! Only use it when you'd otherwise be tempted to declare local copies of constants, or to abuse inheritance (the Constant Interface Antipattern). In other words, use it when you require frequent access to static members from one or two classes. If you overuse the static import feature, it can make your program unreadable and unmaintainable, polluting its namespace with all the static members you import. เอกสารอ้างอิงจากOracle Docs
Abhijeet

1

ไม่มันไม่ใช่วิธีปฏิบัติที่ไม่ดีโดยทั่วไป

ประเด็นก็คือค่าคงที่เป็นสิ่งประดิษฐ์อื่น ๆ ควรได้รับการแนะนำภายใต้กฎของการมองเห็นน้อยที่สุดและระดับนามธรรมที่เหมาะสม

ใช้ไวยากรณ์เพียงเพราะคุณสามารถเป็นปัญหาจริง

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