การใช้ค่าคงที่ของอินเทอร์เฟซคืออะไร?


124

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

คำตอบ:


191

การใส่สมาชิกแบบคงที่ลงในอินเทอร์เฟซ (และการใช้งานอินเทอร์เฟซนั้น) เป็นแนวทางปฏิบัติที่ไม่ดีและยังมีชื่อเรียกอีกอย่างคือConstant Interface Antipatternโปรดดูที่Effective Java , Item 17:

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

มีอินเทอร์เฟซคงที่หลายอย่างในไลบรารีแพลตฟอร์ม java เช่นjava.io.ObjectStreamConstants. อินเทอร์เฟซเหล่านี้ควรถือเป็นความผิดปกติและไม่ควรเลียนแบบ

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

public final class Constants {

    private Constants() {
        // restrict instantiation
    }

    public static final double PI = 3.14159;
    public static final double PLANCK_CONSTANT = 6.62606896e-34;
}

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

import static Constants.PLANCK_CONSTANT;
import static Constants.PI;

public class Calculations {

    public double getReducedPlanckConstant() {
        return PLANCK_CONSTANT / (2 * PI);
    }
}

12
โอเค แต่จะเกิดอะไรขึ้นถ้าคุณมีอินเทอร์เฟซที่ไม่เพียง แต่สำหรับคำจำกัดความคงที่ ดังนั้นฉันจึงมีอินเทอร์เฟซบางอย่างที่ใช้งานโดยหลายคลาสมันมีการประกาศวิธีการ แต่ฉันต้องการเพิ่มค่าทั่วไปเช่นขนาดด้วย มันเป็นรูปแบบที่ไม่ดีจริงๆในกรณีนี้ โดยทั่วไปฉันยอมรับว่าการสร้างอินเทอร์เฟซสำหรับค่าคงที่เท่านั้นเป็นปฏิปักษ์
Łukasz Rzeszotarski

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

12
ไม่ไม่ไม่คำพูดนั้นใน Effective Java นั้นเกี่ยวกับอย่างอื่น! การสร้างค่าคงที่เฉพาะอินเทอร์เฟซเป็นทางเลือกที่ดีกว่าสำหรับคลาสที่มีค่าคงที่เหล่านั้น จาวาที่มีประสิทธิภาพกล่าวว่า: "การที่ชั้นเรียนใช้ค่าคงที่ภายในเป็นรายละเอียดการนำไปใช้งาน" แต่ที่นี่ไม่เป็นเช่นนั้น เรากำลังพูดถึงค่าคงที่ 'ทั่วโลก' และใครต้องการใช้อินเทอร์เฟซที่ไม่มีการประกาศเมธอดในนั้น?
ACV

6
ฉันเห็นด้วยกับ ACV หากอินเทอร์เฟซคงที่ไม่ได้เป็นส่วนหนึ่งของโมดูล API ที่ส่งออกหรือเมื่อไม่มีการใช้งานที่ไหนเลยฉันไม่เห็นปัญหา การใช้คลาส const ขั้นสุดท้ายนั้นน่าเกลียด: คุณต้องมีตัวสร้างส่วนตัวซึ่งรวมโค้ดไว้เนื่องจากไม่มีประโยชน์
Lawrence

2
คำตอบนี้ไม่ได้นำเสนอประเด็นหลักจากหนังสือ "Effective Java" อย่างถูกต้องเนื่องจาก "ลดระดับ" ประเด็นหลักโดยใส่ไว้ในวงเล็บ: "(และใช้อินเทอร์เฟซนั้น)" แต่จะเน้นจุดของค่าคงที่ในอินเทอร์เฟซ (ซึ่งก็ใช้ได้เว้นแต่คุณจะใช้อินเทอร์เฟซดังกล่าว) ไม่ใช่คำตอบที่ไม่ดีโดยทั่วไปเพราะถ้าคุณอ่านส่วนที่ยกมาอย่างละเอียดคุณจะเห็นว่าผู้เขียน "Effective Java" หมายถึงอะไร แต่ฉันคิดว่ามันทำให้เข้าใจผิด ในความคิดของฉันส่วน "และการใช้งานอินเทอร์เฟซนั้น" ควรเป็นแบบอักษรตัวหนาเพื่อเน้นย้ำ
krm

17

" รูปแบบอินเทอร์เฟซคงที่เป็นการใช้อินเทอร์เฟซที่ไม่ดี "

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

ฉันเขียนการโต้แย้งการตอบสนองต่อสมมติฐานดังกล่าวที่นี่: วิธีใดที่ดีที่สุดในการนำค่าคงที่ใน Java ไปใช้ อธิบายถึงความไม่มีมูลฐานของสมมติฐานนี้

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

นี่คือประเด็นที่ฉันแสดงต่อสมมติฐาน

  • พื้นฐานในการถือสมมติฐานนี้คือความต้องการวิธีการและกฎข้อ จำกัด เพื่อรับมือกับผลกระทบของนิสัยและวิธีการที่ไม่ดีของซอฟต์แวร์

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

  • แก้ปัญหาพื้นฐาน

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

ปัญหาพื้นฐาน

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

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

มีอุปสรรคสำคัญสองหรือสามประการในการจัดระเบียบข้อมูล

  1. การขาดการรับรู้ถึงความต้องการของ "normalization" แบบจำลองข้อมูล

  2. ข้อความของ EF Codd เกี่ยวกับการทำให้ข้อมูลเป็นมาตรฐานมีข้อบกพร่องมีข้อบกพร่องและคลุมเครือ

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

การใช้ค่าคงที่ของอินเทอร์เฟซเป็นแนวทางปฏิบัติที่ดี

อย่าสร้างกฎเกณฑ์หรือออกคำสั่งให้ fatwa ต่อต้านมันเพียงเพราะคุณชอบนิสัยการเขียนโปรแกรมแบบ hit-and-run แบบเฉพาะกิจ

อย่าห้ามการครอบครองปืนด้วยเหตุผลที่ว่ามีคนที่ไม่รู้วิธีจัดการปืนหรือมีแนวโน้มที่จะใช้ปืนในทางที่ผิด

หากกฎที่คุณสร้างขึ้นมีไว้สำหรับมือใหม่ในการเขียนโปรแกรมที่ไม่สามารถเขียนโค้ดได้อย่างมืออาชีพและคุณนับตัวเองเป็นหนึ่งในนั้นจงกล่าวเช่นนั้น - อย่าประกาศว่า fatwa ของคุณสามารถใช้ได้กับโมเดลข้อมูลที่ทำให้เป็นมาตรฐานอย่างถูกต้อง

เหตุผลโง่ ๆ - อินเทอร์เฟซไม่ได้ตั้งใจโดยผู้ดิ้นรนของภาษา Java ที่จะใช้ในลักษณะนั้น?

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

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

การใช้ Enum Constants เป็นวิธีปฏิบัติที่น่าสยดสยอง

ต้องมีการเขียนโค้ดพิเศษเพื่อแม็พพารามิเตอร์เป็นค่า ข้อเท็จจริงที่ว่าผู้ก่อตั้ง Java ไม่ได้จัดเตรียมการแม็ปค่าพารามิเตอร์โดยที่คุณไม่ได้เขียนว่าโค้ดการแมปแสดงค่าคงที่ของ Enum นั้นเป็นเพียงการใช้ภาษา Java โดยไม่ได้ตั้งใจ

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

ค่าคงที่คือสัญญา API

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

ดังนั้นอินเทอร์เฟซจึงเป็นวิธีที่สมบูรณ์แบบในการดำเนินการตามสัญญาของค่าคงที่

ข้อสันนิษฐานแปลก ๆ - จะเกิดอะไรขึ้นหากอินเทอร์เฟซถูกนำไปใช้โดยไม่ได้ตั้งใจ

ได้. ทุกคนสามารถใช้อินเทอร์เฟซใด ๆ โดยไม่ได้ตั้งใจโดยไม่ได้ตั้งใจ ไม่มีสิ่งใดขวางทางโปรแกรมเมอร์ที่ไม่ได้ตั้งใจเช่นนั้นได้

ออกแบบและทำให้แบบจำลองข้อมูลของคุณเป็นปกติเพื่อป้องกันการรั่วไหล

อย่าวางคำสั่งที่เข้มงวดเพื่อปกป้องการปฏิบัติที่ไม่ดีที่สันนิษฐานไว้ก่อนซึ่งทำให้เกิดการรั่วไหลของพารามิเตอร์ที่ไม่มีการผูกมัด / หลงทางไปยัง API แก้ไขปัญหาพื้นฐานแทนการตำหนิค่าคงที่ของอินเทอร์เฟซ

การไม่ใช้ IDE ถือเป็นการปฏิบัติที่ไม่ดี

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

อย่าวางข้อ จำกัด เกี่ยวกับโปรแกรมเมอร์เพื่อนเพียงเพราะคุณมีความหลงใหลในการบำเพ็ญตบะลึกลับกับการเขียนโปรแกรมแบบไม่ใช้ IDE

เฟรมเวิร์ก 2 เฟรมถูกออกแบบมาเพื่อช่วยให้โปรแกรมเมอร์สามารถฝึกฝนนิสัยที่ไม่ดีได้อย่างมีประสิทธิภาพ

OSGI เป็นกรอบ และคำสั่งต่อต้านค่าคงที่ของอินเตอร์เฟสก็เช่นกัน

จึงได้ข้อสรุป ...

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

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


30
คะแนนทั้งหมดของคุณสามารถทำได้โดยไม่ต้องล้อเล่นเสียดสีอารมณ์ Stackoverflow ไม่ใช่แพลตฟอร์มบล็อก
tkruse

1
"ฉันไม่สนใจว่าความตั้งใจดั้งเดิมของบรรพบุรุษผู้ก่อตั้งมีต่อรัฐธรรมนูญของสหรัฐอเมริกาอย่างไรฉันไม่สนใจเกี่ยวกับความตั้งใจที่ไม่ได้เขียนไว้ซึ่งไม่ได้เขียนไว้ฉันสนใจเฉพาะสิ่งที่ประมวลตามตัวอักษรในรัฐธรรมนูญที่เป็นลายลักษณ์อักษรและฉันจะใช้ประโยชน์จากสิ่งเหล่านี้ได้อย่างไร การทำงานที่มีประสิทธิผลของสังคม” - นั่นไม่ใช่เรื่องดี?
Blessed Geek

"ต้องเขียนโค้ดพิเศษเพื่อแม็พพารามิเตอร์เป็นค่าความจริงที่ว่าผู้ก่อตั้ง Java ไม่ได้จัดเตรียมการแมปค่าพารามิเตอร์โดยที่คุณไม่เขียนว่าโค้ดการแมปแสดงให้เห็นว่า Enum Constants นั้นเหมือนกับการใช้ภาษา Java โดยไม่ได้ตั้งใจ" คุณจะได้รับการแมปค่าพารามิเตอร์โดยไม่ต้องเขียนโค้ดเพิ่มเติมได้อย่างไร
GabrielOshiro

ใช้ค่าคงที่ของอินเทอร์เฟซ ตรง
Blessed Geek

9

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

เหตุใดจึงต้องใช้ Interface Constant

เพียงเปรียบเทียบ:

public final class Constants {

    private Constants() {
        // restrict instantiation
    }

    public static final double PI = 3.14159;
    public static final double PLANCK_CONSTANT = 6.62606896e-34;
}

VS

public interface Constants {

    double PI = 3.14159;
    double PLANCK_CONSTANT = 6.62606896e-34;
}

การใช้งานเดียวกัน. รหัสน้อยกว่ามาก

ปฏิบัติไม่ดี?

ฉันคิดว่าคำตอบของ @Pascal Thivent มีการเน้นที่ไม่ถูกต้องนี่คือเวอร์ชันของฉัน:

การใส่สมาชิกแบบคงที่ลงในอินเทอร์เฟซ ( และการนำอินเทอร์เฟซนั้นไปใช้ ) เป็นแนวทางปฏิบัติที่ไม่ดี

คำพูดจาก Effective Java มีสมมติฐานของอินเทอร์เฟซคงที่ที่ผู้อื่นนำไปใช้ซึ่งฉันคิดว่าไม่ควร (และจะไม่เกิดขึ้น)

เมื่อคุณสร้างอินเทอร์เฟซแบบคงที่ที่มีชื่อว่าผู้Constantsอื่นไม่ควรนำไปใช้งาน (แม้ว่าจะเป็นไปได้ในทางเทคนิคซึ่งเป็นปัญหาเดียวที่นี่)

จะไม่เกิดขึ้นในไลบรารีมาตรฐาน

ไลบรารีมาตรฐานไม่สามารถใช้การออกแบบในทางที่ผิดได้ดังนั้นคุณจะไม่เห็นสิ่งใดเลย

อย่างไรก็ตามสำหรับโครงการในชีวิตประจำวันของนักพัฒนาปกติใช้อินเตอร์เฟซคงเป็นจำนวนมากได้ง่ายขึ้นเพราะคุณไม่จำเป็นต้องกังวลเกี่ยวกับstatic, final,empty constructorฯลฯ และมันจะไม่ทำให้เกิดปัญหาใด ๆ การออกแบบที่ไม่ดี ข้อเสียอย่างเดียวที่ฉันคิดได้ก็คือมันยังคงมีชื่อของ "อินเทอร์เฟซ" แต่ไม่มีอะไรมากไปกว่านั้น

การถกเถียงที่ไม่สิ้นสุด

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


"การใส่สมาชิกแบบคงที่ลงในอินเทอร์เฟซ (และการนำอินเทอร์เฟซนั้นไปใช้) ถือเป็นการปฏิบัติที่ไม่ดี" ไม่มัน
ฝนตก

โมดิฟายเออร์publicยังสามารถละเว้นได้เนื่องจากเป็นอินเทอร์เฟซทำให้double PI = 3.14159;การใช้งานConstants.PIไม่จำเป็นต้องใช้คลาสที่ใช้Constantsอินเทอร์เฟซนี้! ฉันคิดว่าวิธีการเชื่อมต่อนั้นสะอาดกว่าในแง่ของการใช้งาน IMHO
krozaine

อัปเดต @krozaine ขอบคุณสำหรับการแจ้งเตือน ข้อมูลอ้างอิงสำหรับทุกคนที่มีข้อสงสัย: "ค่าคงที่ทั้งหมดที่กำหนดไว้ในอินเทอร์เฟซเป็นแบบสาธารณะโดยปริยายคงที่และขั้นสุดท้าย" - docs.oracle.com/javase/tutorial/java/IandI/interfaceDef.html
Nakamura

6

Joshua Bloch "ภาษา Java ที่มีประสิทธิภาพ - คู่มือภาษาการเขียนโปรแกรม":

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


1
คุณได้เพิ่มมูลค่าที่ไม่ได้กล่าวไปแล้วอย่างแท้จริง
Donal Fellows

3

ซึ่งจะมีประโยชน์หากคุณมีค่าคงที่ทั่วไปที่จะใช้ในคลาสที่ใช้อินเทอร์เฟซ

นี่คือตัวอย่าง: http://www.javapractices.com/topic/TopicAction.do?Id=32

แต่โปรดทราบว่าแนวทางปฏิบัติที่แนะนำคือการใช้การนำเข้าแบบคงที่แทนค่าคงที่ในอินเทอร์เฟซ นี่คือข้อมูลอ้างอิง: http://www.javapractices.com/topic/TopicAction.do?Id=195


2

มีคำตอบที่สะท้อนใจมาก

แต่ฉันมีความคิดบางอย่างเกี่ยวกับคำถามนี้ (อาจจะผิด)

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


ควรใช้ในคลาสการใช้งานเหล่านั้น
ฝนตก

2

สองประเด็นเกี่ยวกับอินเทอร์เฟซ:

  • อินเทอร์เฟซอธิบายชุดย่อยของสิ่งที่วัตถุที่ใช้งานได้ (นี่คือสัญชาตญาณ)

  • อินเทอร์เฟซอธิบายค่าคงที่ทั่วไปตามด้วยอ็อบเจ็กต์ที่นำไปใช้

    • ค่าคงที่ทั่วไปเหล่านี้มีไว้เพื่อให้ลูกค้าทราบเพื่อทราบข้อมูลเพิ่มเติมเกี่ยวกับวัตถุเหล่านี้
    • ดังนั้นConstants Interfaceจึงใช้งานง่ายในการกำหนดค่าคงที่ทั่วโลกเนื่องจากอินเทอร์เฟซใช้เพื่ออธิบายวัตถุบางอย่างไม่ใช่วัตถุทั้งหมด / ไม่มีวัตถุ (พิจารณาความหมายของglobal )

ดังนั้นฉันคิดว่าถ้าไม่ใช้Constants Interfaceสำหรับค่าคงที่ทั่วโลกก็ยอมรับได้:

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

ตัวอย่าง:

interface Drawable {

    double GOLDEN_RATIO = 1.618033988;
    double PI = 3.141592653;
    ...

    // methods
    ...
}

public class Circle implements Drawable {
    ...
    public double getCircumference() {
        return 2 * PI * r;
    }
}

void usage() {

    Circle circle = new Circle(radius: 3.0);
    double maxRadius = 5.0;

    if ( circle.getCircumference() < 2 * Circle.PI * maxRadius ) {
        ...
    }

}

ในตัวอย่างนี้:

  • จากCircle implements Drawableนั้นคุณรู้ทันทีว่าCircleอาจเป็นไปตามค่าคงที่ที่กำหนดไว้Drawableมิฉะนั้นพวกเขาจะต้องเลือกชื่อที่แย่กว่าเนื่องจากชื่อที่ดีPIและGOLDEN_RATIOถูกนำไปแล้ว!
  • เฉพาะDrawableวัตถุเหล่านี้เท่านั้นที่สอดคล้องกับเฉพาะPIและGOLDEN_RATIOกำหนดไว้ในDrawableนั้นอาจมีวัตถุที่มีDrawableความแม่นยำของ pi และอัตราส่วนทองคำไม่แตกต่างกัน

ฉันเข้าใจคำตอบของคุณผิดหรือว่าคุณเข้าใจจุดประสงค์ของอินเทอร์เฟซผิด? อินเทอร์เฟซไม่ควรเป็นส่วนย่อย อินเทอร์เฟซคือสัญญาซึ่งไม่ว่าผู้ใดก็ตามที่สมัครเข้าร่วมสัญญาจะต้องให้การโต้ตอบที่ระบุโดยสัญญานั้น การใช้อินเทอร์เฟซที่ถูกต้องเท่านั้นคือการใช้เพื่อประกาศ / ปฏิบัติตามสัญญา
Blessed Geek

@BlessedGeek คุณทำตามสัญญาแล้วความสามารถที่อธิบายไว้ในสัญญาเป็นส่วนย่อยของสิ่งที่คุณทำได้
ฝนตก

1

javax.swing.SwingConstantsอินเตอร์เฟซที่เป็นตัวอย่างที่มีเขตข้อมูลแบบคงที่ซึ่งจะใช้ในหมู่เรียนแกว่ง ๆ สิ่งนี้ช่วยให้คุณใช้สิ่งต่างๆเช่น

  • this.add(LINE_START, swingcomponent);
  • this.add(this.LINE_START, swingcomponent); หรือ
  • this.add(SwingComponents.LINE_START, swingcomponent);

อย่างไรก็ตามอินเทอร์เฟซนี้ไม่มีเมธอด ...


1

ฉันเจอคำถามนี้และคิดว่าจะเพิ่มบางอย่างที่ไม่ได้กล่าวถึง โดยทั่วไปแล้วผมเห็นด้วยกับคำตอบของปาสคาลที่นี่ อย่างไรก็ตามฉันไม่คิดว่าค่าคงที่บนอินเทอร์เฟซจะเป็นปฏิปักษ์แบบ "เสมอไป"

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

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


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

@Daniel: ฉันเพิ่มคะแนนความคิดเห็นของคุณ แต่ตอนนี้ฉันมีคำอธิบายที่ดีสำหรับคำถามของคุณ: "ไม่มีข้อผูกมัดใด ๆ ที่บังคับให้ผู้บริโภค API ของคุณใช้ค่าคงที่นั้นจริงๆ" แต่ตอนนี้ลูกค้าไม่สามารถใช้ CONSTANT_NAME ได้อีกต่อไปเนื่องจากเป็น ใช้แล้วซึ่งเป็นสัญญาณที่ดีสำหรับฉัน!
ฝนตก

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

-1

ฉันใช้ค่าคงที่ของอินเทอร์เฟซเมื่อจัดการกับค่าคงที่ที่ใช้ร่วมกันระหว่างคลาส

public interface TestConstants
{
    String RootLevelConstant1 = "RootLevelConstant1";

    interface SubGroup1
    {
        String SubGroupConstant1 = "SubGroup1Constant1";
        String SubGroupConstant2 = "SubGroup1Constant2";
    }

    interface SubGroup2
    {
        String SubGroupConstant1 = "SubGroup2Constant1";
        String SubGroupConstant2 = "SubGroup2Constant2";
    }
}

การจัดกลุ่มเป็นสินทรัพย์ขนาดใหญ่โดยเฉพาะอย่างยิ่งกับค่าคงที่จำนวนมาก

ในการใช้งานคุณเพียงแค่ผูกมันเข้าด้วยกัน:

System.out.println(TestConstants.SubGroup1.SubGroupConstant1);
System.out.println(TestConstants.SubGroup2.SubGroupConstant1);
System.out.println(TestConstants.RootLevelConstant1);

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

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

1
ทำไมในชั้นเรียนถึงทำอะไรได้บ้างในอินเทอร์เฟซ ?? ฉันจะป้องกันไม่ให้ผู้คนใช้อินเทอร์เฟซใด ๆ โดยไม่ได้ตั้งใจได้อย่างไรคือคำถาม ทำไมคุณถึงเลือกค่าคงที่ของอินเทอร์เฟซ?
Blessed Geek

-2

ควรประกาศฟิลด์ในอินเทอร์เฟซเพื่อให้แชร์ได้ง่ายขึ้นและสามารถอ้างอิงได้โดยไม่ต้องมีการเชื่อมต่อเพิ่มเติม

ที่มา: รูปแบบการเข้ารหัสเครื่องมือสำหรับนักพัฒนา Java


อาจจะก่อน java6 แต่ส่วนใหญ่ไม่เกี่ยวข้องในวันนี้
tkruse

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