วิธีที่ดีที่สุดในการใช้ค่าคงที่ใน Java คืออะไร? [ปิด]


372

ฉันเคยเห็นตัวอย่างเช่นนี้:

public class MaxSeconds {
   public static final int MAX_SECONDS = 25;
}

และควรให้ฉันมีคลาส Constants เพื่อตัดค่าคงที่ในประกาศค่าคงที่สุดท้าย ฉันรู้จริง ๆ แล้ว Java ไม่มีเลยและสงสัยว่านี่เป็นวิธีที่ดีที่สุดในการสร้างค่าคงที่หรือไม่



คำตอบ:


403

นั่นเป็นที่ยอมรับอย่างสมบูรณ์แม้กระทั่งมาตรฐาน

(public/private) static final TYPE NAME = VALUE;

โดยที่TYPEtype NAMEเป็นชื่อในตัวพิมพ์ใหญ่ทั้งหมดที่มีเครื่องหมายขีดล่างสำหรับช่องว่างและVALUEเป็นค่าคงที่

ฉันขอแนะนำว่าอย่าใส่ค่าคงที่ในคลาสหรืออินเทอร์เฟซของตนเอง

ในฐานะที่เป็นหมายเหตุด้าน: ตัวแปรที่มีการประกาศครั้งสุดท้ายและสามารถเปลี่ยนแปลงได้ยังคงสามารถเปลี่ยนแปลงได้; อย่างไรก็ตามตัวแปรไม่สามารถชี้ไปที่วัตถุอื่นได้

ตัวอย่างเช่น:

public static final Point ORIGIN = new Point(0,0);

public static void main(String[] args){

    ORIGIN.x = 3;

}

นั่นเป็นสิ่งถูกกฎหมายและORIGINจะเป็นจุดที่ (3, 0)


19
คุณสามารถ 'นำเข้า MaxSeconds.MAX_SECONDS คงที่' เพื่อที่คุณจะได้ไม่ต้องสะกด MaxSeconds.MAX_SECONDS
Aaron Maenpaa

23
ความคิดเห็นก่อนหน้าเกี่ยวกับการนำเข้าคงที่ใช้กับ Java 5+ เท่านั้น บางคนรู้สึกว่าชวเลขไม่คุ้มค่ากับความสับสนที่อาจเกิดขึ้นเมื่อค่าคงที่มาจากการอ่านรหัสยาว ๆ MaxSeconds.MAX_SECONDS อาจจะง่ายต่อการติดตามแล้วมองขึ้นไปที่การนำเข้า
MetroidFan2002

5
เนื่องจากคุณสามารถเปลี่ยน objetc อย่างที่ jjnguy แสดงให้เห็นได้ดีที่สุดถ้า constatns ของคุณเป็นวัตถุที่ไม่เปลี่ยนรูปหรือเป็นแบบดั้งเดิม / สตริงธรรมดา
marcospereira

14
หากคุณกำลังอ่านคำถามนี้โปรดอ่านคำตอบสองข้อข้างล่างนี้ก่อนที่คุณจะตอบคำถามนี้อย่างจริงจังเกินไปแม้ว่าจะได้รับการยอมรับก็เป็นการโต้เถียงถ้าไม่ผิด
orbfish

3
@jjnguy คุณไม่ผิด แต่ถ้าฉันอ่านเฉพาะคำถามและคำตอบคู่แรกของคุณฉันจะรู้สึกว่า "ชั้น Constants" นั้น "เป็นที่ยอมรับอย่างสมบูรณ์อาจเป็นมาตรฐาน" ที่คิดเป็นผิด
Zach Lysobey

235

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

  • หากคุณสามารถเข้าถึง Java 5+ ให้ใช้ enums เพื่อกำหนดค่าคงที่เฉพาะสำหรับพื้นที่แอปพลิเคชัน ทุกส่วนของพื้นที่แอปพลิเคชันควรอ้างถึง enums ไม่ใช่ค่าคงที่สำหรับค่าคงที่เหล่านี้ คุณอาจประกาศ enum คล้ายกับที่คุณประกาศชั้นเรียน Enums อาจเป็นคุณลักษณะที่มีประโยชน์มากที่สุด (และเนื้อหาเท่านั้น) ของ Java 5+
  • หากคุณมีค่าคงที่ที่ใช้ได้กับคลาสเฉพาะหรือหนึ่งในคลาสย่อยเท่านั้นให้ประกาศว่าพวกเขาได้รับการคุ้มครองหรือเป็นสาธารณะและวางไว้ในชั้นบนสุดในลำดับชั้น ด้วยวิธีนี้คลาสย่อยสามารถเข้าถึงค่าคงที่เหล่านี้ (และถ้าคลาสอื่นเข้าถึงพวกเขาผ่านทางสาธารณะค่าคงที่ไม่เพียงถูกต้องกับคลาสที่เฉพาะเจาะจง ... ซึ่งหมายความว่าคลาสภายนอกที่ใช้ค่าคงที่นี้อาจจะแน่นเกินไป คลาสที่มีค่าคงที่)
  • หากคุณมีอินเทอร์เฟซที่มีพฤติกรรมที่กำหนด แต่ค่าที่ส่งคืนหรือค่าอาร์กิวเมนต์ควรเป็นสิ่งที่ยอมรับได้โดยสมบูรณ์ในการกำหนดค่าคงที่บนอินเทอร์เฟซนั้นเพื่อให้ผู้ใช้รายอื่นสามารถเข้าถึงได้ อย่างไรก็ตามหลีกเลี่ยงการสร้างอินเทอร์เฟซเพียงเพื่อเก็บค่าคงที่: มันสามารถกลายเป็นไม่ดีเท่าคลาสที่สร้างเพียงเพื่อเก็บค่าคงที่

12
เห็นด้วยอย่างยิ่ง ... สิ่งนี้สามารถบันทึกเป็นรูปแบบการต่อต้านแบบคลาสสิกสำหรับโครงการขนาดใหญ่
Das

30
ปิดหัวข้อ แต่ ... Generics แน่นอนจะไม่สมบูรณ์แบบ แต่ฉันคิดว่าคุณสามารถทำให้เป็นกรณีที่ดีงามสำหรับพวกเขาเป็นคุณสมบัติที่มีประโยชน์ของ Java 5 :)
มาร์ติน McNulty

3
@ ŁukaszL คำถามนั้นมีพื้นฐานมาจากความเห็นจริง ๆ (เมื่อใดก็ตามที่ "ดีที่สุด" เกิดขึ้นโดยทั่วไปเป็นเรื่องของความเห็น) ดังนั้นคำตอบคือคำตอบที่ถูกต้องสำหรับคำถามนี้ ฉันได้รับคำตอบเกี่ยวกับสิ่งที่ (ใช่ฉันเชื่อว่าเป็นดังนั้นใช่มันเป็นความคิดเห็นเพราะอีกครั้ง "ดีที่สุด" การเปลี่ยนแปลงตามเวลาและตามความเห็นโดยทั่วไป) วิธีที่ดีที่สุดในการใช้ค่าคงที่ใน Java คือ
MetroidFan2002

1
ไม่มีตัวเลือกใด ๆ ด้านบนให้ตัวแปรโกลบอลที่แท้จริงแก่คุณ จะทำอย่างไรถ้าฉันมีบางสิ่งที่ใช้ทุกที่ แต่ไม่ใช่ enum ฉันจะทำเงิน enum ของสิ่งเดียวได้ไหม?
markthegrea

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

120

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

ถ้าค่าคงที่นั้นเชื่อมโยงกับคลาสหรืออินเทอร์เฟซที่มีอยู่อย่างยิ่งคุณควรเพิ่มพวกมันไปยังคลาสหรืออินเทอร์เฟซ ตัวอย่างเช่นคลาสดั้งเดิมที่เป็นตัวเลขทั้งหมดในกล่องเช่น Integer และ Double ส่งออกค่าคงที่ MIN_VALUE และ MAX_VALUE หากค่าคงที่ดูได้ดีที่สุดในฐานะสมาชิกประเภทที่ระบุคุณควรส่งออกด้วยค่า ชนิดenum มิฉะนั้นคุณควรส่งออกค่าคงที่ด้วยคลาสยูทิลิตี้ที่ไม่น่าเชื่อถือ

ตัวอย่าง:

// Constant utility class
package com.effectivejava.science;
public class PhysicalConstants {
    private PhysicalConstants() { }  // Prevents instantiation

    public static final double AVOGADROS_NUMBER   = 6.02214199e23;
    public static final double BOLTZMANN_CONSTANT = 1.3806503e-23;
    public static final double ELECTRON_MASS      = 9.10938188e-31;
}

เกี่ยวกับหลักการตั้งชื่อ:

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


23
หากคุณกำลังจะเรียกสิ่งที่ไม่ดีคุณอาจจะอธิบายว่าทำไมคุณถึงคิดว่ามันเป็นเช่นนั้น?
GlennS

14
นี่คือโพสต์เก่า แต่ดีกว่าที่จะใช้abstractสัญกรณ์สำหรับชั้นเรียนแทนการสร้างส่วนตัว
Xtreme Biker

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

7
@XtremeBiker การทำเครื่องหมายคลาสabstractแทนตัวสร้างส่วนตัวไม่ได้ป้องกันการสร้างอินสแตนซ์ได้อย่างสมบูรณ์เพราะเราสามารถซับคลาสย่อยและอินสแตนซ์คลาสย่อยได้ (ไม่ใช่ว่าเป็นความคิดที่ดี แต่ก็เป็นไปได้) @ToolmakerSteve คุณไม่สามารถคลาสย่อยที่มี Constructor ส่วนตัว (อย่างน้อยก็ไม่ต้องไม่มีแฮ็คเสียขนาดใหญ่) เนื่องจาก Constructor ของคลาสย่อยนั้นต้องเรียก Constructor ของ Superclass (ตอนนี้ส่วนตัว) ดังนั้นการทำเครื่องหมายจึงfinalไม่จำเป็น (แต่อาจชัดเจนกว่า)
นำเข้า

3
ยิ่งแย่ไปกว่านั้นคือการใช้คลาสเพียงเพื่อรักษาค่าคงที่ หากคุณไม่ต้องการสร้างวัตถุของคลาสนั้นทำไมคุณต้องใช้คลาสปกติตั้งแต่แรก?
MaxZoom

36

ใน Effective Java (รุ่นที่ 2) ขอแนะนำให้คุณใช้ enums แทนที่จะเป็น int คงที่สำหรับค่าคงที่

มีการเขียนที่ดีเกี่ยวกับ enums ใน Java ที่นี่: http://java.sun.com/j2se/1.5.0/docs/guide/language/enums.html

โปรดทราบว่าในตอนท้ายของบทความนั้นคำถามถูกวางไว้:

ดังนั้นเมื่อใดที่คุณควรใช้ enums

ด้วยคำตอบของ:

เมื่อใดก็ตามที่คุณต้องการค่าคงที่ชุดหนึ่ง


21

เพียงหลีกเลี่ยงการใช้อินเทอร์เฟซ:

public interface MyConstants {
    String CONSTANT_ONE = "foo";
}

public class NeddsConstant implements MyConstants {

}

มันเป็นสิ่งล่อใจ แต่ละเมิดการห่อหุ้มและเบลอความแตกต่างของคำจำกัดความของชั้นเรียน


1
แน่นอนว่าการนำเข้าคงที่เป็นที่นิยมมากกว่า
Aaron Maenpaa

1
การปฏิบัตินี้เป็นการใช้อินเทอร์เฟซแปลก ๆ ซึ่งมีจุดประสงค์เพื่อระบุการให้บริการของคลาส
Rafa Romero

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

ที่จริง ... มันละเมิด encapsulation ผมชอบที่จะใช้ระดับคงที่สุดท้ายที่ดูวัตถุมากขึ้น oriently และที่นิยมมากกว่าอินเตอร์เฟซหรือ enum หมายเหตุ: Enum สามารถหลีกเลี่ยงได้ในกรณีที่ไม่จำเป็นต้องใช้ Android
2560

19

ฉันใช้วิธีการดังต่อไปนี้:

public final class Constants {
  public final class File {
    public static final int MIN_ROWS = 1;
    public static final int MAX_ROWS = 1000;

    private File() {}
  }

  public final class DB {
    public static final String name = "oups";

    public final class Connection {
      public static final String URL = "jdbc:tra-ta-ta";
      public static final String USER = "testUser";
      public static final String PASSWORD = "testPassword";

      private Connection() {}
    }

    private DB() {}
  }

  private Constants() {}
}

ตัวอย่างเช่นฉันใช้Constants.DB.Connection.URLเพื่อให้ได้ค่าคงที่ ดูเหมือนว่า "object oriently" มากกว่านี้สำหรับฉัน


4
ที่น่าสนใจ แต่ยุ่งยาก ทำไมคุณไม่สร้างค่าคงที่ในชั้นเรียนให้สัมพันธ์กับพวกเขามากที่สุดตามที่คนอื่นแนะนำ ตัวอย่างเช่นในรหัสฐานข้อมูลอื่นคุณมีคลาสพื้นฐานสำหรับการเชื่อมต่อของคุณหรือไม่? เช่น "ConnectionBase" จากนั้นคุณสามารถใส่ค่าคงที่ตรงนั้น รหัสใด ๆ ที่ทำงานกับการเชื่อมต่ออาจมีการนำเข้าอยู่แล้วซึ่งสามารถพูดได้ว่า "ConnectionBase.URL" แทนที่จะเป็น "Constants.DB.Connection.URL"
ToolmakerSteve

3
@ToolmakerSteve แล้วค่าคงที่ทั่วไปที่หลายคลาสสามารถใช้ได้นั้นเป็นอย่างไร ตัวอย่างเช่นสไตล์เว็บเซอร์วิส URL ฯลฯ ... ?
Daniel Gomez Rico

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

17

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

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

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


+1 สำหรับคำเตือนที่ยอดเยี่ยมนี้ (หากคุณไม่สามารถรับประกันได้ว่ามันเป็นค่าคงที่ถาวรให้พิจารณาผู้ทะเยอทะยานแทนเนื่องจาก big_peanut_horse กล่าวถึง) ใช้กับ const ใน C # ตามวิธี: msdn.microsoft.com/en-us/library/e6w8fe1b.aspx
Jon Coombs

13

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

ค่าคงที่ควรเป็นคลาสที่ "เป็นเจ้าของ" คุณมีค่าคงที่ที่เรียกว่า TIMEOUT หรือไม่? อาจเป็นไปได้ที่คลาส Communications () หรือ Connection () ของคุณ MAX_BAD_LOGINS_PER_HOUR? เข้าสู่ผู้ใช้ () และอื่น ๆ และอื่น ๆ.

การใช้งานอื่น ๆ ที่เป็นไปได้คือไฟล์ Java .properties เมื่อสามารถกำหนด "ค่าคงที่" ในเวลาทำงานได้ แต่ผู้ใช้อาจไม่สามารถเปลี่ยนแปลงได้อย่างง่ายดาย คุณสามารถทำแพ็กเกจเหล่านี้ใน. jars ของคุณและอ้างอิงพวกมันด้วย Class resourceLoader


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

6

นั่นคือวิธีที่จะไป

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



5

ฉันชอบใช้ getters มากกว่าค่าคงที่ ผู้public int getMaxConnections() {return 10;}ทะเยอทะยานเหล่านั้นอาจคืนค่าคงที่เช่นแต่สิ่งใดก็ตามที่ต้องการค่าคงที่จะผ่านทะลุ

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

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


5
การอ้างอิงชั้นเรียนที่อ้างอิงซ้ำเป็นเรื่องยากในศตวรรษที่ 21 และคุณไม่ควรใช้โมเดล accessor / mutator (getter / setter) สำหรับสิ่งอื่นนอกเหนือจากการเข้าถึงและการกลายพันธุ์ตัวแปรสมาชิก คงมีความหมายแนวคิดที่จะ immediates ในธรรมชาติในขณะที่ทะเยอทะยาน setters / มี (ทั้ง) หมายถึงการจัดการของรัฐ นอกจากนี้คุณเพียงแค่ขอให้เกิดความสับสน: ผู้คนจะไม่คาดหวังว่าผู้ทะเลาะจะให้ผลตอบแทนที่คงที่เพียงอย่างเดียว

5

ฉันยอมรับว่าการใช้ส่วนต่อประสานไม่ใช่วิธีที่จะไป หลีกเลี่ยงรูปแบบนี้ยังมีรายการของตัวเอง (# 18) ในโบลชมีผลบังคับใช้ Java

อาร์กิวเมนต์ Bloch ขัดแย้งกับรูปแบบอินเทอร์เฟซคงที่คือการใช้ค่าคงที่เป็นรายละเอียดการใช้งาน

public|private static final TYPE NAME = VALUE;รูปแบบเป็นวิธีที่ดีในการประกาศคง โดยส่วนตัวแล้วฉันคิดว่าเป็นการดีกว่าที่จะหลีกเลี่ยงการแยกชั้นเรียนให้เป็นที่อยู่ของคุณ แต่ฉันไม่เคยเห็นเหตุผลที่จะไม่ทำสิ่งนี้นอกเหนือไปจากความชอบส่วนตัวและสไตล์

หากค่าคงที่ของคุณสามารถสร้างแบบจำลองที่ดีให้พิจารณาโครงสร้างenum ที่มีอยู่ใน 1.5 หรือใหม่กว่า

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


ค่าคงที่บางอย่างอาจใช้เรียก API ตัวอย่างเช่นดูอินเตอร์เฟส org.springframework.transaction.TransactionDefinition มีรายการค่าคงที่เช่น int PROPAGATION_REQUIRED = 0;
borjab

ฉันรู้ว่านี่เก่า แต่ลิงก์ไปยัง Effective Java ของ Bloch เสีย คุณสามารถให้การอ้างอิงอื่นหรือสนับสนุนอื่นที่ "ใช้อินเทอร์เฟซไม่ใช่วิธีไป" โปรด
Nelda.techspiress

4

จากความคิดเห็นข้างต้นฉันคิดว่านี่เป็นวิธีที่ดีในการเปลี่ยนระดับค่าคงที่ของโลกที่ล้าสมัย

public class Constants {

    private Constants() {
        throw new AssertionError();
    }

    public interface ConstantType {}

    public enum StringConstant implements ConstantType {
        DB_HOST("localhost");
        // other String constants come here

        private String value;
        private StringConstant(String value) {
            this.value = value;
        }
        public String value() {
            return value;
        }
    }

    public enum IntConstant implements ConstantType {
        DB_PORT(3128), 
        MAX_PAGE_SIZE(100);
        // other int constants come here

        private int value;
        private IntConstant(int value) {
            this.value = value;
        }
        public int value() {
            return value;
        }
    }

    public enum SimpleConstant implements ConstantType {
        STATE_INIT,
        STATE_START,
        STATE_END;
    }

}

ดังนั้นฉันสามารถอ้างถึงพวกเขาชอบ:

Constants.StringConstant.DB_HOST

4
ทำไม? การปรับปรุงนั้นเป็นอย่างไร? ตอนนี้การอ้างอิงทุกอย่างเป็นเรื่องยุ่งยาก (ค่าคงที่ Stringring คงที่) IMHO คุณกำลังจะไปที่ถนนที่เป็นหลุมเป็นบ่อ
ToolmakerSteve

3

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


1
หรือฉีดเข้าไปในคลาสนั้นผ่านทางตัวสร้าง
WW

2

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

public, so that they are accessible from everywhere
static, so that they can be accessed without any instance. Since they are constants it
  makes little sense to duplicate them for every object.
final, since they should not be allowed to change

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

String myConstant = IMyInterface.CONSTANTX;

แต่ฉันจะเลือกระหว่างสองสามวิธีที่แตกต่างกันขึ้นอยู่กับการแลกเปลี่ยนเล็กน้อยและขึ้นอยู่กับสิ่งที่คุณต้องการ:

1.  Use a regular enum with a default/private constructor. Most people would define 
     constants this way, IMHO.
  - drawback: cannot effectively Javadoc each constant member
  - advantage: var members are implicitly public, static, and final
  - advantage: type-safe
  - provides "a limited constructor" in a special way that only takes args which match
     predefined 'public static final' keys, thus limiting what you can pass to the
     constructor

2.  Use a altered enum WITHOUT a constructor, having all variables defined with 
     prefixed 'public static final' .
  - looks funny just having a floating semi-colon in the code
  - advantage: you can JavaDoc each variable with an explanation
  - drawback: you still have to put explicit 'public static final' before each variable
  - drawback: not type-safe
  - no 'limited constructor'

3.  Use a Class with a private constructor:
  - advantage: you can JavaDoc each variable with an explanation
  - drawback: you have to put explicit 'public static final' before each variable
  - you have the option of having a constructor to create an instance
     of the class if you want to provide additional functions related
     to your constants 
     (or just keep the constructor private)
  - drawback: not type-safe

4. Using interface:
  - advantage: you can JavaDoc each variable with an explanation
  - advantage: var members are implicitly 'public static final'
  - you are able to define default interface methods if you want to provide additional
     functions related to your constants (only if you implement the interface)
  - drawback: not type-safe

2

วิธีที่ดีที่สุดในการใช้ค่าคงที่ใน Java คืออะไร?

วิธีการหนึ่งที่เราควรหลีกเลี่ยง : การใช้อินเตอร์เฟสเพื่อกำหนดค่าคงที่

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

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


เพื่อลดความซับซ้อนเรามีวงกว้าง 4 แนวทางที่ถูกต้อง

ด้วยstatic final String/Integerสนาม:

  • 1) ใช้คลาสที่ประกาศค่าคงที่ภายใน แต่ไม่เพียงเท่านั้น
  • 1 ตัวแปร) การสร้างชั้นเรียนเพื่อประกาศค่าคงที่เท่านั้น

ด้วยJava 5 enum:

  • 2) ประกาศ enum ในคลาสวัตถุประสงค์ที่เกี่ยวข้อง (เช่นคลาสซ้อนกัน)
  • 2 ตัวแปร) การสร้าง enum เป็นคลาสสแตนด์อโลน (ดังนั้นกำหนดไว้ในไฟล์คลาสของตัวเอง)

TLDR: วิธีไหนที่ดีที่สุดและตำแหน่งของค่าคงที่

ในกรณีส่วนใหญ่วิธีการ enum อาจจะดีกว่าstatic final String/Integerวิธีการและโดยส่วนตัวฉันคิดว่าstatic final String/Integerวิธีควรใช้เฉพาะในกรณีที่เรามีเหตุผลที่ดีที่จะไม่ใช้ enums
และเกี่ยวกับที่ที่เราควรประกาศค่าคงที่ความคิดคือการค้นหาว่ามีคลาสที่มีอยู่เดียวที่เป็นเจ้าของการทำงานร่วมกันที่เฉพาะเจาะจงและแข็งแกร่งด้วยค่าคงที่ หากเราพบชั้นเรียนดังกล่าวเราควรจะใช้มันเป็นผู้ถือคงที่ มิฉะนั้นค่าคงที่ควรจะเกี่ยวข้องกับไม่มีคลาสใดคลาสหนึ่งโดยเฉพาะ


static final String/ static final Integerกับenum

การใช้ Enums นั้นเป็นวิธีที่จะพิจารณาอย่างจริงจัง
Enums มีข้อได้เปรียบที่ยอดเยี่ยมมากกว่าStringหรือIntegerคงที่
พวกเขาตั้งข้อ จำกัด การรวบรวมที่แข็งแกร่ง หากคุณกำหนดวิธีการที่ใช้พารามิเตอร์ enum คุณสามารถส่งผ่านค่า enum ที่กำหนดในคลาส enum (หรือ null) เท่านั้น
ด้วย String และ Integer คุณสามารถแทนที่พวกมันด้วยค่าชนิดใด ๆ ที่เข้ากันได้และการคอมไพล์จะใช้ได้แม้ค่าจะไม่คงที่ที่กำหนดในฟิลด์static final String/static final Integer

ตัวอย่างเช่นค่าคงที่ด้านล่างสองค่าที่กำหนดในคลาสเป็นstatic final Stringฟิลด์:

public class MyClass{

   public static final String ONE_CONSTANT = "value";
   public static final String ANOTHER_CONSTANT = "other value";
   . . .
}

นี่คือวิธีการที่คาดว่าจะมีหนึ่งในค่าคงที่เหล่านี้เป็นพารามิเตอร์:

public void process(String constantExpected){
    ...    
}

คุณสามารถเรียกใช้วิธีนี้ได้:

process(MyClass.ONE_CONSTANT);

หรือ

process(MyClass.ANOTHER_CONSTANT);

แต่ไม่มีข้อ จำกัด ในการรวบรวมทำให้คุณไม่สามารถเรียกใช้วิธีนี้ได้:

process("a not defined constant value");

คุณจะมีข้อผิดพลาดเฉพาะที่รันไทม์และเมื่อคุณทำการตรวจสอบค่าส่ง

ด้วย enum การตรวจสอบไม่จำเป็นเนื่องจากไคลเอ็นต์สามารถส่งค่า enum ในพารามิเตอร์ enum เท่านั้น

ตัวอย่างเช่นที่นี่สองค่าที่กำหนดไว้ในคลาส enum (คงที่ดังนั้นออกจากกล่อง):

public enum MyEnum {

    ONE_CONSTANT("value"), ANOTHER_CONSTANT(" another value");

    private String value;

    MyEnum(String value) {
       this.value = value;
    }
         ...
}

นี่คือวิธีการที่คาดว่าจะมีหนึ่งในค่า enum เหล่านี้เป็นพารามิเตอร์:

public void process(MyEnum myEnum){
    ...    
}

คุณสามารถเรียกใช้วิธีนี้ได้:

process(MyEnum.ONE_CONSTANT);

หรือ

process(MyEnum.ANOTHER_CONSTANT);

แต่การรวบรวมจะไม่อนุญาตให้คุณเรียกใช้ด้วยวิธีนี้:

process("a not defined constant value");

เราจะประกาศค่าคงที่ที่ไหน?

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

ตัวอย่างเช่นในไลบรารี JDK ค่าคงที่เอ็กซ์โพเนนเชียลและ pi จะถูกประกาศในคลาสที่ประกาศไม่เพียง แต่การประกาศคงที่ ( java.lang.Math)

   public final class Math {
          ...
       public static final double E = 2.7182818284590452354;
       public static final double PI = 3.14159265358979323846;
         ...
   }

ลูกค้าที่ใช้ฟังก์ชั่นคณิตศาสตร์พึ่งพาบ่อยครั้งในMathชั้นเรียน ดังนั้นพวกเขาอาจพบว่าค่าคงที่ง่ายพอและสามารถจดจำตำแหน่งEและPIนิยามในวิธีที่เป็นธรรมชาติมาก

หากแอปพลิเคชันของคุณไม่มีคลาสที่มีอยู่ที่มีการทำงานร่วมกันที่เฉพาะเจาะจงและแข็งแกร่งกับค่าคงที่วิธีที่ 1 ตัวแปร) และ 2 ตัวแปร) ปรากฏขึ้นง่ายขึ้น
โดยทั่วไปแล้วมันไม่สะดวกในการใช้ค่าคงที่หากสิ่งเหล่านี้ถูกประกาศในคลาสหนึ่งที่จัดการกับมันในขณะที่เรามีคลาสอื่น ๆ อีก 3 หรือ 4 คลาสที่จัดการพวกมันได้มากและไม่มีคลาสใดที่ดูเป็นธรรมชาติมากกว่าคนอื่น ค่าคงที่ของโฮสต์
ที่นี่การกำหนดคลาสที่กำหนดเองเพื่อเก็บค่าคงที่เท่านั้นทำให้รู้สึก
ตัวอย่างเช่นในไลบรารี JDK, java.util.concurrent.TimeUnitenum จะไม่ถูกประกาศในคลาสที่ระบุเนื่องจากไม่มีคลาสเฉพาะของ JDK หนึ่งคลาสเท่านั้นและปรากฏเป็นรูปแบบที่ใช้งานง่ายที่สุดในการเก็บมัน:

public enum TimeUnit {
    NANOSECONDS {
      .....
    },
    MICROSECONDS {
      .....
    },
    MILLISECONDS {
      .....
    },
    SECONDS {
      .....
    },
      .....
}      

หลายชั้นเรียนที่ประกาศในjava.util.concurrentการใช้งานพวกเขา BlockingQueue, ArrayBlockingQueue<E>, CompletableFuture, ExecutorService... และจริงๆไม่มีหนึ่งของพวกเขาดูเหมือนว่าเหมาะสมในการถือ enum


1

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

public class OfficePrinter {
    public static final String STATE = "Ready";  
}

มีแอปพลิเคชั่นมากมายที่ค่าคงที่บ่งบอกถึงการเลือกจาก n-tuple (เช่นการแจงนับ ) ของตัวเลือก ในตัวอย่างของเราเราสามารถเลือกกำหนด Enumerated Type ที่จะ จำกัด ค่าที่ได้รับมอบหมาย (เช่นการปรับปรุงความปลอดภัยประเภท ):

public class OfficePrinter {
    public enum PrinterState { Ready, PCLoadLetter, OutOfToner, Offline };
    public static final PrinterState STATE = PrinterState.Ready;
}

1

คลาสค่าคงที่ทั่วไปหนึ่งเดียวเป็นความคิดที่ไม่ดี ค่าคงที่ควรจัดกลุ่มพร้อมกับคลาสที่เกี่ยวข้องกับเหตุผลมากที่สุด

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


1

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


1

อะไรคือความแตกต่าง

1

public interface MyGlobalConstants {
    public static final int TIMEOUT_IN_SECS = 25;
}

2

public class MyGlobalConstants {
    private MyGlobalConstants () {} // Prevents instantiation
    public static final int TIMEOUT_IN_SECS = 25;
}

และใช้ MyGlobalConstants.TIMEOUT_IN_SECSทุกที่ที่เราต้องการค่าคงที่นี้ ฉันคิดว่าทั้งสองเหมือนกัน


1
เรื่องนี้ดูเหมือนจะเป็นความคิดเห็นเป็นหลักในการตอบสนองต่อคำตอบ bincob ให้ ฉันคิดว่าพวกเขาทำตัวคล้ายกันมาก แต่ประเด็นของ bincob ก็คือพวกเขาไม่ได้กำหนดอินเตอร์เฟสใด ๆ และข้อเสนอแนะคือการเพิ่มค่าคงที่ให้กับคลาสจริงไม่ใช่เพื่อสร้างคลาสโครงกระดูก MyGlobalConstants (ถึงแม้ว่าสิ่งนี้จะทำให้รู้สึกเป็นครั้งคราวให้ใช้ "คลาสคงที่" โดยมีค่าคงที่แบบคงที่และตัวสร้างส่วนตัวเพื่อป้องกันการสร้างอินสแตนซ์ดู java.lang.math) พิจารณาใช้ enum
Jon Coombs

การใส่ "final" ในการประกาศคลาสจะป้องกันไม่ให้คลาสย่อย (ใน C # คุณสามารถทำ "คงที่" ซึ่งหมายถึง "สุดท้ายนามธรรม" จึงไม่จำเป็นสำหรับการสร้างภาคเอกชนอย่างชัดเจนไม่มี.)
จอนคูมบ์ส

ใช่ @JonCoombs แต่ "final" ไม่ได้ป้องกันการสร้างอินสแตนซ์โดยตรง และชวาไม่อนุญาตทั้งในขั้นตอนสุดท้ายและนามธรรมให้ปรากฏร่วมกันสำหรับชั้นเรียนดังนั้นผู้สร้างส่วนตัวที่ปรากฏอย่างไม่มีที่สิ้นสุดเพื่อป้องกันทั้งการสร้างอินสแตนซ์และการทำคลาสย่อย ฉันไม่รู้เลยว่าทำไม "final abstract" ไม่ได้รับอนุญาตนอกเหนือจากเมื่อมองแวบแรกดูเหมือนจะขัดแย้งกับวิธีการอ่าน: "คุณไม่สามารถ subclass แต่คลาสนี้มีความหมายว่า subclassed"

0

ฉันจะไม่เรียกชั้นเรียนเดียวกัน (นอกเหนือจากตัวเรือน) เป็นค่าคงที่ ... ฉันจะมีอย่างน้อยหนึ่งคลาสของ "การตั้งค่า" หรือ "ค่า" หรือ "ค่าคงที่" ซึ่งค่าคงที่ทั้งหมดจะมีชีวิตอยู่ ถ้าฉันมีจำนวนมากฉันจะจัดกลุ่มให้อยู่ในคลาสค่าคงที่แบบลอจิคัล (UserSettings, AppSettings ฯลฯ )


การมีชั้นเรียนที่เรียกว่าค่าคงที่คือสิ่งที่ฉันวางแผนไว้นั่นเป็นเพียงตัวอย่างเล็ก ๆ ที่ฉันพบ
mk

0

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

public interface MyGlobalConstants {
    public static final int TIMEOUT_IN_SECS = 25;
}

แต่อย่านำไปใช้ เพียงแค่อ้างถึงพวกเขาโดยตรงในรหัสผ่าน classname ครบถ้วน


จุดเกี่ยวกับการประกาศพวกเขาในอินเทอร์เฟซ (และไม่นำไปใช้) คือคุณสามารถพลาด "สาธารณะคงที่สุดท้าย"
Tom Hawtin - tackline

9
อินเทอร์เฟซสำหรับการกำหนดสัญญาพฤติกรรมไม่ใช่กลไกอำนวยความสะดวกสำหรับการถือครองค่าคงที่
John Topley

@ JohnTopley ใช่ แต่มันใช้งานได้ ;)
trusktr

0

สำหรับค่าคงที่ Enum เป็นตัวเลือกที่ดีกว่า IMHO นี่คือตัวอย่าง

คลาส myClass สาธารณะ

public enum myEnum {
    Option1("String1", 2), 
    Option2("String2", 2) 
    ;
    String str;
            int i;

            myEnum(String str1, int i1) { this.str = str1 ; this.i1 = i }


}

0

วิธีหนึ่งที่ฉันทำได้คือการสร้างคลาส 'Global' ด้วยค่าคงที่และทำการนำเข้าแบบคงที่ในคลาสที่ต้องการเข้าถึงค่าคงที่


0

static finalคือการตั้งค่าของฉันฉันจะใช้เฉพาะenumถ้ารายการนั้นนับได้แน่นอน


0

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

Enums เป็นตัวเลือกที่ดีในการแสดงช่วงของค่า แต่ถ้าคุณเก็บค่าคงที่แบบสแตนด์อโลนโดยเน้นค่าสัมบูรณ์ (เช่น TIMEOUT = 100 ms) คุณสามารถไปหาstatic finalวิธีได้


0

ฉันเห็นด้วยกับสิ่งที่คนพูดมากที่สุดดีที่สุดคือใช้ enums เมื่อจัดการกับค่าคงที่ แต่ถ้าคุณเขียนโปรแกรมใน Android มีทางออกที่ดีกว่า: IntDef หมายเหตุ

@Retention(SOURCE)
@IntDef({NAVIGATION_MODE_STANDARD, NAVIGATION_MODE_LIST,NAVIGATION_MODE_TABS})
public @interface NavigationMode {}
public static final int NAVIGATION_MODE_STANDARD = 0;
public static final int NAVIGATION_MODE_LIST = 1;
public static final int NAVIGATION_MODE_TABS = 2;
...
public abstract void setNavigationMode(@NavigationMode int mode);
@NavigationMode
public abstract int getNavigationMode();

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


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

0

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

ฉันยังไม่ได้อ่านอะไรเลย Joshua Bloch เช่นกัน

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

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

  • รักอัตลักษณ์พื้นฐานด้วยสุดใจและสุดใจ
  • รักเพื่อนบ้านเหมือนรักตนเอง

และการรวมกลุ่มของวิศวกรรมซอฟต์แวร์ในทำนองเดียวกันสามารถสรุปได้โดย

  • อุทิศตนให้กับพื้นฐานที่ไร้ดินแดนด้วยโปรแกรมและความคิดทั้งหมดของคุณ
  • และอุทิศตนเพื่อความเป็นเลิศของเพื่อนร่วมโปรแกรมของคุณตามที่คุณต้องการด้วยตัวคุณเอง

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

  • ก่อนอื่นรักตัวเอง เพราะถ้าคุณไม่รักตัวเองมากนักแนวคิด "รักเพื่อนบ้านเหมือนรักตนเอง" ไม่ได้มีน้ำหนักมากเพราะ "คุณรักตัวเองมากแค่ไหน" คือบรรทัดข้อมูลด้านบนที่คุณจะรักคนอื่น

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

กฎหมายพื้นฐานของการเขียนโปรแกรมซอฟต์แวร์

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

ค่าคงที่รูปแบบส่วนต่อประสานเป็นนิสัยที่ไม่ดี ???

ภายใต้กฎหมายว่าด้วยการเขียนโปรแกรมที่มีประสิทธิภาพและมีความรับผิดชอบพื้นฐานคำสั่งทางศาสนานี้ตกอยู่ใน?

เพียงอ่านบทความวิกิพีเดียเกี่ยวกับค่าคงที่รูปแบบของอินเทอร์เฟซ ( https://en.wikipedia.org/wiki/Constant_interface ) และข้อแก้ตัวโง่ ๆ ที่ระบุกับค่าคงที่ของรูปแบบอินเทอร์เฟซ

  • IDE แบบ Whatif-No ใครในโลกในฐานะโปรแกรมเมอร์ซอฟต์แวร์จะไม่ใช้ IDE? พวกเราส่วนใหญ่เป็นโปรแกรมเมอร์ที่ไม่ต้องการพิสูจน์ว่ามีการเอาชีวิตรอดอย่างหลีกเลี่ยงการใช้ IDE

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

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

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

    • ทำไมคุณต้องการมีส่วนร่วมในรูปแบบของการเขียนโปรแกรมเช่นการทำมาหากินของคุณ? IOW เหตุใดจึงต้องทุ่มเทตัวเองให้เป็นนิสัยในการเขียนโปรแกรม AMBIVALENT และไม่ดี?

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

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

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

พื้นฐานคือการปรับรูปแบบข้อมูล

ไม่สำคัญว่ารูปแบบข้อมูลของคุณจะโฮสต์หรือส่งข้อมูลอย่างไร ไม่ว่าคุณจะใช้อินเทอร์เฟซหรือ enums หรืออะไรก็ตามความสัมพันธ์หรือ no-SQL ถ้าคุณไม่เข้าใจความต้องการและกระบวนการปรับรูปแบบข้อมูล

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

แม้แต่แง่มุมของการทำข้อมูลให้เป็นมาตรฐานตามที่เสนอโดย EF Codd ตอนนี้ถูกท้าทายอย่างรุนแรงและท้าทายอย่างรุนแรง เช่นคำแถลงของเขาเกี่ยวกับ 1NF ถูกวิพากษ์วิจารณ์ว่าคลุมเครือไม่ตรงแนวและเกินความเป็นจริงเช่นเดียวกับคำแถลงที่เหลือของเขาโดยเฉพาะอย่างยิ่งในการให้บริการข้อมูลที่ทันสมัยเทคโนโลยี repo และการส่งผ่าน IMO, งบ EF Codd ควรได้รับการออกแบบอย่างสมบูรณ์และชุดใหม่ของคำสั่งที่มีเหตุผลทางคณิตศาสตร์มากขึ้นได้รับการออกแบบ

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

พื้นฐานของการทำข้อมูลให้เป็นมาตรฐาน

สิ่งที่ EF Codd ไม่สามารถแสดงได้

ภายในแต่ละ data-model ที่สอดคล้องกันเหล่านี้คือลำดับของการเชื่อมโยง data-model ที่สำเร็จการศึกษาตามลำดับเพื่อให้บรรลุ

  1. ความสามัคคีและตัวตนของอินสแตนซ์ข้อมูล
    • ออกแบบความละเอียดของส่วนประกอบข้อมูลแต่ละอันโดยที่ความละเอียดของมันอยู่ในระดับที่แต่ละอินสแตนซ์ของส่วนประกอบสามารถระบุและเรียกคืนได้โดยไม่ซ้ำกัน
    • ไม่มีนามแฝงของอินสแตนซ์ นั่นคือไม่มีวิธีใดที่การระบุจะสร้างมากกว่าหนึ่งอินสแตนซ์ของส่วนประกอบ
  2. กรณีที่ไม่มี crosstalk ไม่มีความจำเป็นที่จะต้องใช้อินสแตนซ์อื่นของส่วนประกอบอย่างน้อยหนึ่งรายการเพื่อช่วยในการระบุอินสแตนซ์ของส่วนประกอบ
  3. ความสามัคคีและตัวตนของส่วนประกอบ / มิติข้อมูล
    • การแสดงตนของการลบองค์ประกอบ จะต้องมีอยู่หนึ่งคำจำกัดความที่สามารถระบุองค์ประกอบ / มิติได้โดยไม่ซ้ำกัน ซึ่งเป็นนิยามหลักขององค์ประกอบ;
    • โดยที่นิยามหลักจะไม่ส่งผลให้เปิดเผยมิติย่อยหรือส่วนประกอบสมาชิกที่ไม่ได้เป็นส่วนหนึ่งขององค์ประกอบที่ต้องการ
  4. วิธีการเฉพาะในการจัดการองค์ประกอบ จะต้องมีอยู่หนึ่งรายการและมีเพียงหนึ่งคำจำกัดความของการยกเลิกการใช้ชื่อองค์ประกอบสำหรับองค์ประกอบ
  5. มีหนึ่งอินเทอร์เฟซนิยามหรือสัญญาเดียวเท่านั้นที่ระบุส่วนประกอบหลักในความสัมพันธ์แบบลำดับชั้นของส่วนประกอบ
  6. การไม่มี crosstalk ของคอมโพเนนต์ ไม่มีความจำเป็นที่จะต้องใช้สมาชิกขององค์ประกอบอื่นเพื่อสนับสนุนการระบุที่ชัดเจนขององค์ประกอบ
    • ในความสัมพันธ์แบบพ่อแม่และลูกคำจำกัดความการระบุตัวของผู้ปกครองจะต้องไม่ขึ้นอยู่กับส่วนหนึ่งของชุดองค์ประกอบสมาชิกของเด็ก องค์ประกอบสมาชิกของตัวตนของผู้ปกครองจะต้องเป็นตัวตนของเด็กที่สมบูรณ์โดยไม่ต้องหันไปอ้างอิงเด็กใด ๆ หรือทั้งหมดของเด็ก
  7. preempt หน้าสองหรือ modal modal หลายรูปแบบข้อมูล
    • เมื่อมีคำจำกัดความของผู้สมัครสองคนที่มีองค์ประกอบมันเป็นสัญญาณที่ชัดเจนว่ามีรูปแบบข้อมูลที่แตกต่างกันสองแบบที่รวมกันเป็นหนึ่ง นั่นหมายความว่าจะมีการเชื่อมโยงกันในระดับรูปแบบข้อมูลหรือระดับฟิลด์
    • แอปพลิเคชันของเขตข้อมูลจะต้องใช้หนึ่ง - รูปแบบข้อมูลเดียวอย่างต่อเนื่อง
  8. ตรวจจับและระบุการกลายพันธุ์ขององค์ประกอบ หากคุณไม่ได้ทำการวิเคราะห์องค์ประกอบทางสถิติของข้อมูลขนาดใหญ่คุณอาจไม่เห็นหรือเห็นความจำเป็นในการรักษาการกลายพันธุ์ขององค์ประกอบ
    • รูปแบบข้อมูลอาจมีส่วนประกอบบางส่วนของมันกลายพันธุ์เป็นวัฏจักรหรือค่อยๆ
    • โหมดอาจเป็นการหมุนแบบสมาชิกหรือการหมุนวน
    • การกลายพันธุ์ของการหมุนของสมาชิกอาจเป็นการสลับสับเปลี่ยนของคอมโพเนนต์ลูกระหว่างคอมโพเนนต์ หรือสถานที่ที่จะต้องมีการกำหนดองค์ประกอบใหม่อย่างสมบูรณ์
    • การกลายพันธุ์ของ Transpositional จะแสดงให้เห็นว่าเป็นสมาชิกมิติกลายพันธุ์ในทางกลับกัน
    • แต่ละรอบการกลายพันธุ์จะต้องมีการระบุว่าเป็น modal ข้อมูล
  9. กำหนดเวอร์ชันการกลายพันธุ์แต่ละอัน เช่นนี้คุณสามารถดึงตัวแบบข้อมูลรุ่นก่อนหน้าออกมาเมื่อบางทีความต้องการที่เกิดขึ้นกับการกลายพันธุ์ของตัวแบบข้อมูลอายุ 8 ปี

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

เรายังถามว่าเราสามารถใช้ค่าคงที่ของอินเตอร์เฟสได้หรือไม่? จริงเหรอ

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

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

จากนั้นคุณกำหนดว่าจะเข้าสู่การฉีดค่าการยึดการกำหนดค่าคุณสมบัติอินเทอร์เฟซสตริงสุดท้าย ฯลฯ

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

บางทีคุณอาจต้องการรวบรวมรูปแบบข้อมูลลงใน vcs release คุณสามารถดึงข้อมูลที่เป็นรูปแบบที่ระบุได้อย่างชัดเจน

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

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

public interface CustomerService {
  public interface Label{
    char AssignmentCharacter = ':';
    public interface Address{
      String Street = "Street";
      String Unit= "Unit/Suite";
      String Municipal = "City";
      String County = "County";
      String Provincial = "State";
      String PostalCode = "Zip"
    }

    public interface Person {
      public interface NameParts{
        String Given = "First/Given name"
        String Auxiliary = "Middle initial"
        String Family = "Last name"
      }
    }
  }
}

ตอนนี้ฉันสามารถอ้างอิงป้ายกำกับที่ทำสัญญาของแอพได้เช่นกัน

CustomerService.Label.Address.Street
CustomerService.Label.Person.NameParts.Family

สิ่งนี้ทำให้เนื้อหาของไฟล์ jar สับสนหรือไม่ ในฐานะโปรแกรมเมอร์ Java ฉันไม่สนใจเกี่ยวกับโครงสร้างของโถ

สิ่งนี้นำเสนอความซับซ้อนในการแลกเปลี่ยนรันไทม์ osgi-motivated? Osgi เป็นวิธีที่มีประสิทธิภาพอย่างมากในการอนุญาตให้โปรแกรมเมอร์ดำเนินการต่อในนิสัยที่ไม่ดีของพวกเขา มีทางเลือกที่ดีกว่า osgi

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

public class PurchaseRequest {
  private interface Constants{
    String INTERESTINGName = "Interesting Name";
    String OFFICIALLanguage = "Official Language"
    int MAXNames = 9;
  }
}

บางทีแม้แต่สิ่งนี้:

public interface PurchaseOrderConstants {
  public interface Properties{
    default String InterestingName(){
       return something();
    }
    String OFFICIALLanguage = "Official Language"
    int MAXNames = 9;
  }
}

ปัญหาเดียวของค่าคงที่อินเทอร์เฟซที่ควรพิจารณาคือเมื่อใช้งานอินเตอร์เฟส

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

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

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