it-swarm-id.com

Apa cara terbaik untuk mengimplementasikan konstanta di Jawa?

Saya telah melihat contoh seperti ini:

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

dan mengira bahwa saya dapat memiliki kelas Konstanta untuk membungkus konstanta, menyatakan mereka final statis. Saya tahu hampir tidak ada Java sama sekali dan saya bertanya-tanya apakah ini adalah cara terbaik untuk membuat konstanta.

373
mk.

Itu bisa diterima, bahkan mungkin standar.

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

di mana TYPE adalah tipenya, NAME adalah nama dalam semua huruf besar dengan garis bawah untuk spasi, dan VALUE adalah nilai konstan;

Saya sangat merekomendasikan TIDAK menempatkan konstanta Anda di kelas atau antarmuka mereka sendiri.

Sebagai catatan: Variabel yang dideklarasikan final dan dapat diubah masih dapat diubah; Namun, variabel tidak pernah bisa menunjuk ke objek yang berbeda.

Sebagai contoh:

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

public static void main(String[] args){

    Origin.x = 3;

}

Itu legal dan Origin akan menjadi titik pada (3, 0).

403
jjnguy

Saya akan sangat menyarankan agar tidak memiliki kelas konstanta tunggal. Ini mungkin tampak ide yang bagus pada saat itu, tetapi ketika pengembang menolak untuk mendokumentasikan konstanta dan kelas tumbuh untuk mencakup lebih dari 500 konstanta yang semuanya tidak terkait satu sama lain sama sekali (terkait dengan aspek aplikasi yang sama sekali berbeda), ini umumnya berubah menjadi file konstanta yang sepenuhnya tidak dapat dibaca. Sebagai gantinya:

  • Jika Anda memiliki akses ke Java 5+, gunakan enums untuk mendefinisikan konstanta spesifik Anda untuk area aplikasi. Semua bagian dari area aplikasi harus mengacu pada enum, bukan nilai konstan, untuk konstanta ini. Anda dapat mendeklarasikan enum yang mirip dengan cara Anda mendeklarasikan sebuah kelas. Enum mungkin adalah fitur yang paling berguna (dan, bisa dibilang, hanya) dari Java 5+.
  • Jika Anda memiliki konstanta yang hanya berlaku untuk kelas tertentu atau salah satu dari subkelasnya, mendeklarasikannya sebagai terproteksi atau publik dan menempatkannya di kelas atas dalam hierarki. Dengan cara ini, subclass dapat mengakses nilai-nilai konstan ini (dan jika kelas lain mengaksesnya melalui publik, konstanta tidak hanya berlaku untuk kelas tertentu ... yang berarti bahwa kelas eksternal menggunakan konstanta ini mungkin terlalu erat digabungkan ke kelas kelas yang berisi konstanta)
  • Jika Anda memiliki antarmuka dengan perilaku yang ditentukan, tetapi nilai yang dikembalikan atau nilai argumen harus khusus, sangat dapat diterima untuk mendefinisikan konstanta pada antarmuka itu sehingga pelaksana lain akan memiliki akses ke sana. Namun, hindari membuat antarmuka hanya untuk memegang konstanta: itu bisa menjadi sama buruknya dengan kelas yang dibuat hanya untuk memegang konstanta.
235
MetroidFan2002

Ini adalah BAD PRACTICE untuk menggunakan antarmuka hanya untuk memegang konstanta (dinamai pola antarmuka konstan oleh Josh Bloch). Inilah yang dinasihati Josh:

Jika konstanta sangat terkait dengan kelas atau antarmuka yang ada, Anda harus menambahkannya ke kelas atau antarmuka. Misalnya, semua kelas primitif numerik kotak, seperti Integer dan Double, ekspor konstanta MIN_VALUE dan MAX_VALUE. Jika konstanta paling baik dilihat sebagai anggota tipe enumerasi, Anda harus mengekspornya dengan tipe enum. Jika tidak, Anda harus mengekspor konstanta dengan kelas utilitas yang tidak dapat diperbaiki.

Contoh:

// 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;
}

Tentang konvensi penamaan:

Berdasarkan konvensi, bidang tersebut memiliki nama yang terdiri dari huruf kapital, dengan kata-kata yang dipisahkan oleh garis bawah. Sangat penting bahwa bidang ini mengandung nilai primitif atau referensi ke objek yang tidak dapat diubah.

120
Marcio Aguiar

Dalam Java Efektif (edisi ke-2), Anda disarankan untuk menggunakan enum daripada int statis untuk konstanta.

Ada langgan yang baik pada enum di Jawa di sini: http://Java.Sun.com/j2se/1.5.0/docs/guide/language/enums.html

Perhatikan bahwa pada akhir artikel itu pertanyaan yang diajukan adalah:

Jadi kapan sebaiknya Anda menggunakan enum?

Dengan jawaban:

Kapan saja Anda membutuhkan konstanta yang tetap

36
shelfoo

Hindari penggunaan antarmuka:

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

public class NeddsConstant implements MyConstants {

}

Itu menggoda, tetapi melanggar enkapsulasi dan mengaburkan perbedaan definisi kelas.

21
stimpy

Saya menggunakan pendekatan berikut:

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() {}
}

Daripada, misalnya, saya menggunakan Constants.DB.Connection.URL untuk mendapatkan konstanta. Ini terlihat lebih "berorientasi objek" bagi saya.

19
albus.ua

Membuat konstanta akhir statis di kelas terpisah dapat membuat Anda mendapat masalah. Kompiler Java akan benar-benar mengoptimalkan ini dan menempatkan nilai aktual dari konstanta ke dalam kelas yang mereferensikannya.

Jika nanti Anda mengubah kelas 'Konstanta' dan Anda tidak melakukan kompilasi ulang pada kelas lain yang mereferensikan kelas itu, Anda akan berakhir dengan kombinasi nilai lama dan baru yang digunakan.

Alih-alih menganggapnya sebagai konstanta, anggap sebagai parameter konfigurasi dan buat kelas untuk mengelolanya. Biarkan nilainya menjadi non-final, dan bahkan pertimbangkan untuk menggunakan getter. Di masa mendatang, saat Anda menentukan bahwa beberapa parameter ini sebenarnya harus dapat dikonfigurasi oleh pengguna atau administrator, itu akan jauh lebih mudah dilakukan.

17
Kevin Day

Kesalahan nomor satu yang dapat Anda buat adalah menciptakan kelas yang dapat diakses secara global yang disebut dengan nama generik, seperti Konstanta. Ini hanya akan dipenuhi dengan sampah dan Anda kehilangan semua kemampuan untuk mencari tahu bagian mana dari sistem Anda yang menggunakan konstanta ini.

Sebaliknya, konstanta harus masuk ke kelas yang "memiliki" mereka. Apakah Anda memiliki konstanta yang disebut TIMEOUT? Mungkin harus masuk ke kelas Communications () atau Connection () Anda. MAX_BAD_LOGINS_PER_HOUR? Masuk ke Pengguna (). Dan seterusnya dan seterusnya.

Kemungkinan penggunaan lainnya adalah file Java .properties ketika "konstanta" dapat didefinisikan pada saat run-time, tetapi tidak mudah diubah oleh pengguna. Anda bisa mengemas ini di .jar Anda dan referensi dengan Class resourceLoader.

13
Yann Ramin

Itu cara yang tepat untuk pergi.

Umumnya konstanta tidak disimpan dalam kelas "Konstanta" yang terpisah karena tidak dapat ditemukan. Jika konstanta relevan dengan kelas saat ini, mempertahankannya di sana membantu pengembang berikutnya.

6
Jason Cohen

Saya setuju bahwa menggunakan antarmuka bukanlah cara yang tepat. Menghindari pola ini bahkan memiliki item sendiri (# 18) di Bloch's Java Efektif .

Argumen yang dibuat Bloch terhadap pola antarmuka konstan adalah bahwa penggunaan konstanta adalah detail implementasi, tetapi mengimplementasikan antarmuka untuk menggunakannya memperlihatkan bahwa detail implementasi dalam API yang diekspor.

Pola public|private static final TYPE NAME = VALUE; adalah cara yang baik untuk mendeklarasikan konstanta. Secara pribadi, saya pikir lebih baik menghindari membuat kelas terpisah untuk menampung semua konstanta Anda, tetapi saya belum pernah melihat alasan untuk tidak melakukan ini, selain preferensi dan gaya pribadi.

Jika konstanta Anda dapat dimodelkan dengan baik sebagai enumerasi, pertimbangkan struktur enum tersedia dalam 1,5 atau lebih baru.

Jika Anda menggunakan versi lebih awal dari 1,5, Anda masih dapat melakukan enumerasi typesafe dengan menggunakan kelas Java normal. (Lihat situs ini untuk lebih lanjut tentang itu).

5
Rob Dickerson

Bagaimana dengan pencacahan?

5
Sébastien D.

Saya lebih suka menggunakan getter daripada konstanta. Getter tersebut dapat mengembalikan nilai konstan, mis. public int getMaxConnections() {return 10;}, tetapi apa pun yang membutuhkan konstanta akan melalui pengambil.

Satu manfaat adalah bahwa jika program Anda melebihi konstanta - Anda merasa perlu untuk dikonfigurasi - Anda bisa mengubah cara pengambil mengembalikan konstanta.

Manfaat lainnya adalah bahwa untuk memodifikasi konstanta Anda tidak perlu mengkompilasi ulang semua yang menggunakannya. Saat Anda mereferensikan bidang akhir statis, nilai konstanta itu dikompilasi ke dalam bytecode apa pun yang merujuknya.

5
big_peanut_horse

Berdasarkan komentar di atas, saya pikir ini adalah pendekatan yang baik untuk mengubah kelas konstanta global kuno (memiliki variabel final statis publik) menjadi yang setara dengan enum dengan cara seperti ini:

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;
    }

}

Jadi saya bisa merujuk mereka seperti:

Constants.StringConstant.DB_Host
4
Lorand Bendig

Desain berorientasi objek yang baik seharusnya tidak membutuhkan banyak konstanta yang tersedia untuk umum. Sebagian besar konstanta harus dikemas dalam kelas yang membutuhkannya untuk melakukan tugasnya.

3
Bradley Harris

Ada sejumlah pendapat untuk menjawab ini. Untuk mulai dengan, konstanta di Jawa umumnya dinyatakan publik, statis dan final. Berikut alasannya:

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

Saya tidak akan pernah menggunakan antarmuka untuk accessor/objek KONSTAN hanya karena antarmuka umumnya diharapkan untuk diimplementasikan. Bukankah ini terlihat lucu:

String myConstant = IMyInterface.CONSTANTX;

Sebaliknya saya akan memilih di antara beberapa cara yang berbeda, berdasarkan pada beberapa trade-off kecil, dan itu tergantung pada apa yang Anda butuhkan:

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
djangofan

Apa cara terbaik untuk mengimplementasikan konstanta di Jawa?

Satu pendekatan yang harus kita hindari: menggunakan antarmuka untuk mendefinisikan konstanta.

Membuat antarmuka khusus untuk mendeklarasikan konstanta adalah hal terburuk: ia mengalahkan alasan mengapa antarmuka dirancang: mendefinisikan metode kontrak.

Bahkan jika antarmuka sudah ada untuk menjawab kebutuhan tertentu, menyatakan konstanta di dalamnya benar-benar tidak masuk akal karena konstanta tidak boleh menjadi bagian dari API dan kontrak yang disediakan untuk kelas klien.


ntuk mempermudah, kami memiliki 4 pendekatan yang valid.

Dengan bidang static final String/Integer:

  • 1) menggunakan kelas yang menyatakan konstanta di dalam tetapi tidak hanya.
  • 1 varian) membuat kelas yang didedikasikan untuk hanya mendeklarasikan konstanta.

Dengan Java 5 enum:

  • 2) mendeklarasikan enum di kelas tujuan terkait (sehingga kelas bersarang).
  • 2 varian) membuat enum sebagai kelas mandiri (didefinisikan dalam file kelasnya sendiri).

TLDR: Mana cara terbaik dan di mana menemukan konstanta?

Dalam kebanyakan kasus, cara enum mungkin lebih baik daripada cara static final String/Integer dan secara pribadi saya berpikir bahwa cara static final String/Integer harus digunakan hanya jika kita memiliki alasan yang baik untuk tidak menggunakan enum.
Dan tentang di mana kita harus mendeklarasikan nilai konstan, idenya adalah untuk mencari apakah ada satu kelas yang ada yang memiliki kohesi fungsional spesifik dan kuat dengan nilai konstan. Jika kita menemukan kelas seperti itu, kita harus menggunakannya sebagai pemegang konstanta. Kalau tidak, konstanta harus dikaitkan dengan tidak ada satu kelas tertentu.


static final String/static final Integer DIBANDINGKAN enum

Penggunaan Enums benar-benar cara untuk dipertimbangkan dengan kuat.
Enum memiliki keunggulan besar dibandingkan bidang konstan String atau Integer.
Mereka menetapkan batasan kompilasi yang lebih kuat. Jika Anda mendefinisikan metode yang menggunakan enum sebagai parameter, Anda hanya bisa memberikan nilai enum yang ditentukan dalam kelas enum (atau nol).
Dengan String dan Integer Anda dapat menggantinya dengan nilai apa pun dari tipe yang kompatibel dan kompilasi akan baik-baik saja meskipun nilainya bukan konstanta yang didefinisikan dalam bidang static final String/static final Integer.

Misalnya, di bawah dua konstanta yang didefinisikan dalam kelas sebagai bidang static final String:

public class MyClass{

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

Di sini metode yang mengharapkan memiliki salah satu dari konstanta ini sebagai parameter:

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

Anda dapat memohonnya dengan cara ini:

process(MyClass.ONE_CONSTANT);

atau

process(MyClass.ANOTHER_CONSTANT);

Tetapi tidak ada batasan kompilasi yang mencegah Anda dari memohonnya dengan cara ini:

process("a not defined constant value");

Anda akan memiliki kesalahan hanya pada saat runtime dan hanya jika Anda pada suatu waktu memeriksa nilai yang dikirimkan.

Dengan enum, pemeriksaan tidak diperlukan karena klien hanya bisa memberikan nilai enum dalam parameter enum.

Sebagai contoh, di sini dua nilai didefinisikan dalam kelas enum (begitu konstan di luar kotak):

public enum MyEnum {

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

    private String value;

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

Di sini metode yang mengharapkan memiliki salah satu dari nilai enum ini sebagai parameter:

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

Anda dapat memohonnya dengan cara ini:

process(MyEnum.ONE_CONSTANT);

atau

process(MyEnum.ANOTHER_CONSTANT);

Tetapi kompilasi tidak akan pernah memungkinkan Anda memohonnya dengan cara ini:

process("a not defined constant value");

Di mana kita harus mendeklarasikan konstanta?

Jika aplikasi Anda berisi satu kelas yang ada yang memiliki kohesi fungsional spesifik dan kuat dengan nilai konstan, 1) dan 2) tampak lebih intuitif.
Secara umum, ini memudahkan penggunaan konstanta jika ini dinyatakan dalam kelas utama yang memanipulasi mereka atau yang memiliki nama yang sangat wajar untuk menebak bahwa kita akan menemukannya di dalam.

Sebagai contoh di perpustakaan JDK, nilai konstanta eksponensial dan pi dideklarasikan dalam kelas yang menyatakan tidak hanya deklarasi konstan (Java.lang.Math).

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

Klien yang menggunakan fungsi matematika sering bergantung pada kelas Math. Jadi, mereka dapat menemukan konstanta dengan cukup mudah dan juga dapat mengingat di mana E dan PI didefinisikan dengan cara yang sangat alami.

Jika aplikasi Anda tidak mengandung kelas yang sudah ada yang memiliki kohesi fungsional yang sangat spesifik dan kuat dengan nilai-nilai konstan, varian 1) dan 2 varian) tampak lebih intuitif.
Secara umum, itu tidak meringankan penggunaan konstanta jika ini dinyatakan dalam satu kelas yang memanipulasi mereka sementara kami juga memiliki 3 atau 4 kelas lain yang memanipulasi mereka sebanyak dan tidak ada satu pun dari kelas-kelas ini tampaknya menjadi lebih alami daripada yang lain untuk Host nilai konstan.
Di sini, mendefinisikan kelas khusus untuk menampung hanya nilai konstan yang masuk akal.
Sebagai contoh di perpustakaan JDK, Java.util.concurrent.TimeUnit enum tidak dideklarasikan di kelas tertentu karena tidak ada satu dan hanya satu kelas spesifik JDK yang muncul sebagai yang paling intuitif untuk menampungnya:

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

Banyak kelas yang dideklarasikan dalam Java.util.concurrent menggunakannya: BlockingQueue, ArrayBlockingQueue<E>, CompletableFuture, ExecutorService, ... dan benar-benar tidak ada satu pun dari mereka yang tampaknya lebih tepat untuk mengadakan enum.

2
davidxxx

FWIW, batas waktu dalam nilai detik mungkin harus menjadi pengaturan konfigurasi (dibaca dari file properti atau melalui injeksi seperti di Spring) dan bukan konstanta.

1
Tim Howland

Apa bedanya

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;
}

dan menggunakan MyGlobalConstants.TIMEOUT_IN_SECS dimanapun kita membutuhkan konstanta ini. Saya pikir keduanya sama.

1
chandrayya

Kelas konstanta generik tunggal adalah ide yang buruk. Konstanta harus dikelompokkan bersama dengan kelas yang paling terkait dengan mereka.

Daripada menggunakan variabel apa pun (terutama enum), saya menyarankan Anda menggunakan metode. Buat metode dengan nama yang sama dengan variabel dan minta untuk mengembalikan nilai yang Anda tetapkan ke variabel. Sekarang hapus variabel dan ganti semua referensi dengan panggilan ke metode yang baru saja Anda buat. Jika Anda merasa konstanta cukup umum sehingga Anda tidak perlu membuat instance kelas hanya untuk menggunakannya, maka buat metode konstan metode kelas.

1
ab

Konstanta, apa pun jenisnya, dapat dideklarasikan dengan membuat properti yang tidak dapat diubah yang ada dalam suatu kelas (yaitu variabel anggota dengan pengubah final). Biasanya pengubah static dan public juga disediakan.

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

Ada banyak aplikasi di mana nilai konstanta menunjukkan pemilihan dari n-Tuple (mis. enumerasi) pilihan. Dalam contoh kami, kami dapat memilih untuk menentukan Jenis yang Dihitung yang akan membatasi nilai yang ditugaskan yang mungkin (mis. Ditingkatkan keamanan jenis):

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

Saya tidak akan menyebut kelas yang sama (selain dari casing) sebagai konstanta ... Saya akan memiliki minimal satu kelas "Pengaturan", atau "Nilai", atau "Konstanta", di mana semua konstanta akan hidup. Jika saya memiliki sejumlah besar dari mereka, saya akan mengelompokkannya dalam kelas-kelas logis konstan (UserSettings, AppSettings, dll.)

0
Joel Martinez

static final adalah preferensi saya, saya hanya akan menggunakan enum jika item tersebut memang dapat dihitung.

0
wulfgarpro

Adalah Kebiasaan buruk dan praktik PENGUMUMAN yang sangat buruk untuk mengutip Joshua Bloch tanpa memahami dasar dasar-nol fundamentalisme.

Saya belum membaca apa pun Joshua Bloch, begitu juga

  • dia adalah programmer yang mengerikan
  • atau orang-orang yang saya kutip dari kutipannya (Joshua adalah nama bocah lelaki yang saya anggap) hanya menggunakan bahannya sebagai naskah keagamaan untuk membenarkan perangkat lunak pengampunan keagamaan mereka.

Seperti dalam fundamentalisme Alkitab, semua hukum Alkitab dapat disimpulkan

  • Cintai Identitas Fundamental dengan segenap hati dan pikiran Anda
  • Cintailah sesamamu seperti dirimu sendiri

dan demikian pula fundamentalisme rekayasa perangkat lunak dapat disimpulkan oleh

  • mengabdikan diri Anda pada dasar-dasar nol dengan semua kekuatan dan pikiran pemrograman Anda
  • dan mengabdikan diri untuk keunggulan sesama programer Anda seperti yang Anda lakukan untuk diri sendiri.

Juga, di antara kalangan fundamentalis alkitabiah, akibat wajar yang kuat dan masuk akal diambil

  • Pertama-tama cintai dirimu sendiri. Karena jika kamu tidak terlalu mencintai dirimu sendiri, maka konsep "cintai tetanggamu seperti dirimu sendiri" tidak terlalu berpengaruh, karena "betapa kamu mencintai dirimu sendiri" adalah garis datum di mana kamu akan mencintai orang lain.

Demikian pula, jika Anda tidak menghormati diri Anda sebagai seorang programmer dan hanya menerima pernyataan dan ramalan dari beberapa guru pemrograman-TANPA TANPA mempertanyakan dasar-dasar, kutipan dan kepercayaan Anda pada Joshua Bloch (dan sejenisnya) tidak ada artinya. Dan karena itu, Anda benar-benar tidak akan menghargai sesama programmer.

Hukum dasar pemrograman perangkat lunak

  • kemalasan adalah keutamaan programmer yang baik
  • anda harus membuat kehidupan pemrograman Anda semudah, semalas dan karena itu seefektif mungkin
  • anda harus membuat konsekuensi dan isi perut pemrograman Anda semudah itu, semalas dan karenanya seefektif mungkin bagi para programmer-tetangga Anda yang bekerja dengan Anda dan mengambil isi perut pemrograman Anda.

Konstanta antarmuka-pola adalah kebiasaan buruk ???

Di bawah hukum pemrograman yang efektif dan bertanggung jawab secara fundamental, apa aturan agama ini?

Cukup baca artikel wikipedia tentang konstanta pola antarmuka ( https://en.wikipedia.org/wiki/Constant_interface ), dan alasan konyol menyatakannya terhadap konstanta pola antarmuka.

  • Whatif-No IDE? Siapa di bumi sebagai programmer perangkat lunak tidak akan menggunakan IDE? Sebagian besar dari kita adalah programmer yang lebih suka tidak harus membuktikan memiliki survivalisticism aescetic macho melalui menghindari penggunaan IDE.

    • Juga - tunggu pendukung kedua pemrograman mikro-fungsional sebagai cara tidak membutuhkan IDE. Tunggu sampai Anda membaca penjelasan saya tentang normalisasi data-model.
  • Mencemari namespace dengan variabel yang tidak digunakan dalam lingkup saat ini? Bisa jadi penganjur pendapat ini

    • tidak menyadari, dan perlunya, normalisasi data-model
  • Menggunakan antarmuka untuk menegakkan konstanta adalah penyalahgunaan antarmuka. Pendukung seperti memiliki kebiasaan buruk

    • tidak melihat bahwa "konstanta" harus diperlakukan sebagai kontrak. Dan antarmuka digunakan untuk menegakkan atau memproyeksikan kepatuhan terhadap kontrak.
  • Sulit jika bukan tidak mungkin untuk mengubah antarmuka menjadi kelas yang diimplementasikan di masa depan. Hah .... hmmm ... ???

    • Mengapa Anda ingin terlibat dalam pola pemrograman seperti itu sebagai mata pencaharian Anda yang gigih? TKI, mengapa mengabdikan diri pada kebiasaan pemrograman AMBIVALEN dan buruk?

Apa pun alasannya, TIDAK ADA VALID EXCUSE dalam hal rekayasa perangkat lunak EFEKTIF SECARA EFEKTIF untuk mendelegitimasi atau umumnya mencegah penggunaan konstanta antarmuka.

Tidak masalah apa maksud asli dan kondisi mental para pendiri bangsa yang menyusun Konstitusi Amerika Serikat. Kita bisa memperdebatkan maksud asli dari para pendiri bangsa tetapi yang saya pedulikan hanyalah pernyataan tertulis dari Konstitusi AS. Dan itu adalah tanggung jawab setiap warga negara AS untuk mengeksploitasi fundamentalisme sastra tertulis, bukan tujuan pendiri tidak tertulis, Konstitusi AS.

Demikian pula, saya tidak peduli apa maksud "asli" dari pendiri platform Java dan bahasa pemrograman untuk antarmuka. Apa yang saya pedulikan adalah fitur-fitur efektif yang disediakan oleh spesifikasi Java, dan saya bermaksud untuk mengeksploitasi fitur-fitur itu sepenuhnya untuk membantu saya memenuhi hukum dasar pemrograman perangkat lunak yang bertanggung jawab. Saya tidak peduli jika saya dianggap "melanggar niat untuk antarmuka". Saya tidak peduli apa yang dikatakan Gosling atau seseorang Bloch tentang "cara yang tepat untuk menggunakan Java", kecuali apa yang mereka katakan tidak melanggar kebutuhan saya untuk EFEKTIF dalam memenuhi fundamental.

Fundamental adalah Normalisasi Data-Model

Tidak masalah bagaimana model data Anda dihosting atau dikirimkan. Apakah Anda menggunakan antarmuka atau enum atau apa pun, relasional atau tidak-SQL, jika Anda tidak memahami kebutuhan dan proses normalisasi model-data.

Pertama-tama kita harus mendefinisikan dan menormalkan data-model dari serangkaian proses. Dan ketika kita memiliki model-data yang koheren, HANYA kita dapat menggunakan aliran proses dari komponen-komponennya untuk mendefinisikan perilaku fungsional dan memproses blok suatu bidang atau bidang aplikasi. Dan hanya dengan begitu kita dapat mendefinisikan API dari setiap proses fungsional.

Bahkan aspek normalisasi data seperti yang diusulkan oleh EF Codd sekarang sangat ditantang dan sangat ditantang. misalnya pernyataannya tentang 1NF telah dikritik sebagai ambigu, tidak selaras, dan terlalu disederhanakan, seperti halnya sisa pernyataannya terutama dalam munculnya layanan data modern, repo-teknologi dan transmisi. IMO, pernyataan EF Codd harus sepenuhnya dibuang dan set baru pernyataan yang lebih masuk akal secara matematis dirancang.

Kelemahan mencolok Codd's EF dan penyebab ketidakselarasannya pada pemahaman manusia yang efektif adalah keyakinannya bahwa data multi-dimensi, dimensi-bisa-berubah yang dapat dipahami secara manusia dapat secara efisien dipersepsikan melalui serangkaian pemetaan 2-dimensi.

Dasar-dasar Normalisasi Data

Apa yang tidak diungkapkan oleh Codd EF.

Dalam setiap data-model yang koheren, ini adalah urutan bertahap dari keterpaduan data-model yang harus dicapai.

  1. Persatuan dan Identitas contoh data.
    • mendesain granularity masing-masing komponen data, di mana granularitasnya berada pada level di mana setiap instance komponen dapat diidentifikasi dan diambil secara unik.
    • tidak adanya contoh alias. yaitu, tidak ada sarana di mana identifikasi menghasilkan lebih dari satu instance komponen.
  2. Tidak adanya crosstalk misalnya. Tidak ada keharusan untuk menggunakan satu atau lebih contoh komponen lainnya untuk berkontribusi dalam mengidentifikasi contoh komponen.
  3. Kesatuan dan identitas komponen/dimensi data.
    • Kehadiran komponen de-aliasing. Harus ada satu definisi di mana komponen/dimensi dapat diidentifikasi secara unik. Yang merupakan definisi utama dari suatu komponen;
    • di mana definisi utama tidak akan menghasilkan pengungkapan sub-dimensi atau komponen-anggota yang bukan bagian dari komponen yang dimaksudkan;
  4. Cara unik dealiasing komponen. Harus ada satu, dan hanya satu, komponen yang mendefinisikan de-aliasing definisi untuk suatu komponen.
  5. Ada satu, dan hanya satu, antarmuka definisi atau kontrak untuk mengidentifikasi komponen induk dalam hubungan hierarki komponen.
  6. Tidak adanya crosstalk komponen. Tidak ada keharusan untuk menggunakan anggota komponen lain untuk berkontribusi pada identifikasi definitif komponen.
    • Dalam hubungan orangtua-anak seperti itu, definisi identifikasi orang tua tidak boleh bergantung pada bagian dari set komponen anggota anak. Komponen anggota dari identitas orang tua harus merupakan identitas anak yang lengkap tanpa menggunakan referensi salah satu atau semua anak dari seorang anak.
  7. Penampilan dwi-modal atau multi-modal dari model-data.
    • Ketika ada dua definisi kandidat komponen, itu adalah tanda yang jelas bahwa ada dua model data yang berbeda digabungkan menjadi satu. Itu berarti ada ketidaksesuaian di tingkat data-model, atau di tingkat lapangan.
    • Bidang aplikasi harus menggunakan satu dan hanya satu model data, secara koheren.
  8. Mendeteksi dan mengidentifikasi mutasi komponen. Kecuali Anda telah melakukan analisis komponen statistik dari data besar, Anda mungkin tidak melihat, atau melihat perlunya memperlakukan, mutasi komponen.
    • Model-data mungkin memiliki beberapa komponennya bermutasi secara siklis atau bertahap.
    • Mode dapat berupa rotasi anggota atau transposisi-rotasi.
    • Mutasi rotasi anggota dapat menjadi pertukaran komponen anak yang berbeda antar komponen. Atau di mana komponen yang benar-benar baru harus didefinisikan.
    • Mutasi transposisi akan bermanifestasi sebagai anggota dimensi bermutasi menjadi atribut, sebaliknya.
    • Setiap siklus mutasi harus diidentifikasi sebagai modal data yang berbeda.
  9. Beri versi setiap mutasi. Sedemikian rupa sehingga Anda dapat mengeluarkan versi model data sebelumnya, saat mungkin diperlukan untuk mengobati mutasi model data yang berusia 8 tahun.

Dalam suatu bidang atau kisi aplikasi-komponen antar-layanan, harus ada satu dan hanya satu model-data yang koheren atau ada sarana untuk model-data/versi untuk mengidentifikasi dirinya sendiri.

Apakah kita masih bertanya apakah kita bisa menggunakan Konstanta Antarmuka? Benarkah?

Ada masalah normalisasi data yang dipertaruhkan lebih penting daripada pertanyaan biasa ini. JIKA Anda tidak menyelesaikan masalah tersebut, kebingungan yang menurut Anda disebabkan oleh konstanta antarmuka relatif tidak ada. Zilch.

Dari normalisasi data-model maka Anda menentukan komponen sebagai variabel, sebagai properti, sebagai konstanta antarmuka kontrak.

Kemudian Anda menentukan yang masuk ke injeksi nilai, placeholding konfigurasi properti, antarmuka, string akhir, dll.

Jika Anda harus menggunakan alasan untuk mencari komponen yang lebih mudah didiktekan terhadap konstanta antarmuka, itu artinya Anda berada dalam kebiasaan buruk untuk tidak melakukan normalisasi data-model.

Mungkin Anda ingin mengkompilasi model data menjadi rilis vcs. Bahwa Anda bisa mengeluarkan versi data-model yang dapat diidentifikasi dengan jelas.

Nilai yang didefinisikan dalam antarmuka sepenuhnya dijamin tidak dapat diubah. Dan dapat dibagikan. Mengapa memuat serangkaian string terakhir ke kelas Anda dari kelas lain ketika semua yang Anda butuhkan adalah seperangkat konstanta ??

Jadi mengapa tidak mempublikasikan kontrak model data ini? Maksud saya jika Anda dapat mengelola dan menormalkannya secara koheren, mengapa tidak? ...

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"
      }
    }
  }
}

Sekarang saya dapat mereferensikan label kontrak aplikasi saya dengan cara seperti

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

Ini membingungkan isi file jar? Sebagai seorang programmer Java saya tidak peduli dengan struktur toples.

Ini menyajikan kompleksitas untuk swap runtime osgi-termotivasi? Osgi adalah cara yang sangat efisien untuk memungkinkan programmer melanjutkan kebiasaan buruknya. Ada alternatif yang lebih baik daripada osgi.

Atau mengapa tidak? Tidak ada kebocoran Konstanta pribadi ke dalam kontrak yang dipublikasikan. Semua konstanta pribadi harus dikelompokkan ke dalam antarmuka pribadi bernama "Konstanta", karena saya tidak ingin harus mencari konstanta dan saya terlalu malas untuk berulang kali mengetik "private final String".

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

Bahkan mungkin ini:

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

Satu-satunya masalah dengan konstanta antarmuka yang patut dipertimbangkan adalah ketika antarmuka diimplementasikan.

Ini bukan "niat asli" dari antarmuka? Seperti saya akan peduli tentang "niat asli" dari para pendiri pendiri dalam menyusun Konstitusi AS, daripada bagaimana Mahkamah Agung akan menafsirkan surat-surat tertulis dari Konstitusi AS ???

Lagi pula, saya tinggal di tanah yang bebas, liar dan rumah yang berani. Jadilah berani, bebas, liar - gunakan antarmuka. Jika sesama programmer saya menolak menggunakan cara pemrograman yang efisien dan malas, apakah saya diwajibkan oleh aturan emas untuk mengurangi efisiensi pemrograman saya agar selaras dengan mereka? Mungkin saya harus, tetapi itu bukan situasi yang ideal.

0
Blessed Geek

Untuk mengambil langkah lebih jauh, Anda dapat menempatkan konstanta yang digunakan secara global dalam sebuah antarmuka sehingga mereka dapat digunakan di seluruh sistem. Misalnya.

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

Tapi jangan lakukan itu. Cukup rujuk langsung dalam kode melalui nama kelas yang memenuhi syarat.

0

Saya menggunakan static final untuk mendeklarasikan konstanta dan pergi dengan notasi penamaan ALL_CAPS. Saya telah melihat beberapa contoh kehidupan nyata di mana semua konstanta disatukan menjadi sebuah antarmuka. Beberapa posting dengan tepat menyebut itu praktik yang buruk, terutama karena bukan itu tujuan dari antarmuka. Antarmuka harus menegakkan kontrak dan tidak boleh menjadi tempat untuk meletakkan konstanta yang tidak terkait. Menyatukannya ke dalam kelas yang tidak dapat dipakai (melalui konstruktor pribadi) juga baik-baik saja jika semantik konstan tidak termasuk dalam kelas tertentu ( es). Saya selalu menempatkan konstanta di kelas yang paling berhubungan dengannya, karena itu masuk akal dan juga mudah dipelihara.

Enum adalah pilihan yang baik untuk mewakili rentang nilai, tetapi jika Anda menyimpan konstanta mandiri dengan penekanan pada nilai absolut (mis. TIMEOUT = 100 ms), Anda bisa menggunakan pendekatan static final.

0
bincob

Untuk Konstanta, Enum adalah pilihan IMHO yang lebih baik. Berikut ini sebuah contoh

myClass kelas publik {

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
mmansoor

Saya setuju dengan apa yang dikatakan kebanyakan orang, yang terbaik adalah menggunakan enum ketika berhadapan dengan kumpulan konstanta. Namun, jika Anda memprogram di Android ada solusi yang lebih baik: IntDef Annotation .

@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();

Anotasi IntDef lebih unggul daripada enum dalam satu cara sederhana, ini membutuhkan ruang lebih sedikit karena hanya merupakan penanda waktu kompilasi. Ini bukan kelas, juga tidak memiliki properti konversi string otomatis.

0
Quinn Turner

Salah satu cara saya melakukannya adalah dengan membuat kelas 'Global' dengan nilai konstan dan melakukan impor statis di kelas yang membutuhkan akses ke konstanta.

0
Javamann