1. Pengenalan
Dalam tutorial ringkas ini, kami akan menyiasat bagaimana kami dapat memberikan nilai lalai untuk atribut ketika menggunakan pola pembangun dengan Lombok .
Pastikan juga untuk melihat intro kami ke Lombok.
2. Kebergantungan
Kami akan menggunakan Lombok dalam tutorial ini, dan untuk itu, kami hanya memerlukan satu pergantungan:
org.projectlombok lombok 1.18.10 provided
3. POJO Bersama Pembangun Lombok
Pertama, mari kita lihat bagaimana Lombok dapat membantu kita menyingkirkan kod pelat boiler yang diperlukan untuk melaksanakan corak pembangun.
Kami akan mulakan dengan POJO ringkas:
public class Pojo { private String name; private boolean original; }
Agar kelas ini berguna, kami memerlukan pemula. Sebagai contoh, jika kita mahu menggunakan kelas ini dengan ORM, kita mungkin memerlukan pembina lalai.
Selain itu, kami mahukan pembina kelas ini. Dengan Lombok, kita dapat memperoleh semua ini dengan beberapa penjelasan ringkas:
@Getter @Builder @NoArgsConstructor @AllArgsConstructor public class Pojo { private String name; private boolean original; }
4. Menentukan Harapan
Mari tentukan beberapa jangkaan untuk apa yang ingin kita capai dalam bentuk ujian unit.
Keperluan pertama dan asas adalah adanya nilai lalai setelah kami membina objek dengan pembangun:
@Test public void givenBuilderWithDefaultValue_ThanDefaultValueIsPresent() { Pojo build = Pojo.builder() .build(); Assert.assertEquals("foo", build.getName()); Assert.assertTrue(build.isOriginal()); }
Sudah tentu, ujian ini gagal kerana anotasi @Builder tidak mengisi nilai. Kami akan menyelesaikannya tidak lama lagi.
Sekiranya kita menggunakan ORM, biasanya bergantung pada konstruktor lalai. Jadi, kita harus mengharapkan tingkah laku yang sama dari konstruktor lalai seperti yang kita lakukan dari pembangun:
@Test public void givenBuilderWithDefaultValue_NoArgsWorksAlso() { Pojo build = Pojo.builder() .build(); Pojo pojo = new Pojo(); Assert.assertEquals(build.getName(), pojo.getName()); Assert.assertTrue(build.isOriginal() == pojo.isOriginal()); }
Pada peringkat ini, ujian ini lulus.
Sekarang mari kita lihat bagaimana kita dapat membuat kedua-dua ujian itu lulus!
5. Pembina Lombok. Anotasi Lalai
Sejak Lombok v1.16.16, kita dapat menggunakan penjelasan dalaman @Builder :
// class annotations as before public class Pojo { @Builder.Default private String name = "foo"; @Builder.Default private boolean original = true; }
Ia mudah dan mudah dibaca, tetapi mempunyai beberapa kekurangan.
Dengan ini, nilai lalai akan hadir dengan pembangun, menjadikan kes ujian pertama lulus. Malangnya, konstruktor no-args tidak akan mendapat nilai lalai, menjadikan kes ujian kedua gagal . Walaupun konstruktor no-args tidak dihasilkan tetapi ditulis secara eksplisit.
Kesan sampingan Builder ini. Anotasi lalai ada sejak awal dan mungkin akan lama kita bersama.
6. Permulaan Pembina
Kami boleh membuat kedua-dua ujian tersebut lulus dengan menentukan nilai lalai dalam pelaksanaan pembangun minimalis:
// class annotations as before public class Pojo { private String name = "foo"; private boolean original = true; public static class PojoBuilder { private String name = "foo"; private boolean original = true; } }
Dengan cara ini, kedua-dua ujian akan lulus.
Malangnya, harganya adalah pendua kod. Untuk POJO dengan puluhan medan, mungkin ralat untuk mengekalkan inisialisasi berganda.
Tetapi, jika kita sanggup membayar harga ini, kita harus mengurus satu perkara lagi. Sekiranya kita menamakan semula kelas kita menggunakan pemfaktoran semula dalam IDE kita, kelas dalaman yang statik tidak akan dinamakan semula secara automatik. Kemudian, Lombok tidak akan menjumpainya dan kod kami akan rosak.
Untuk menghilangkan risiko ini, kita dapat menghiasi anotasi pembangun:
// class annotations as before @Builder(builderClassName = "PojoBuilder") public class Pojo { private String name = "foo"; private boolean original = true; public static class PojoBuilder { private String name = "foo"; private boolean original = true; } }
7. Menggunakan toBuilder
@Builder juga menyokong menghasilkan contoh pembangun dari contoh kelas asal. Ciri ini tidak diaktifkan secara lalai. Kita boleh mengaktifkannya dengan menetapkan parameter toBuilder dalam penjelasan pembangun:
// class annotations as before @Builder(toBuilder = true) public class Pojo { private String name = "foo"; private boolean original = true; }
Dengan ini, kita dapat menyingkirkan inisialisasi berganda .
Sudah tentu, ada harga untuk itu. Kita mesti membuat kelas untuk membuat pembina. Oleh itu, kita juga harus mengubah suai ujian kita:
@Test public void givenBuilderWithDefaultValue_ThenDefaultValueIsPresent() { Pojo build = new Pojo().toBuilder() .build(); Assert.assertEquals("foo", build.getName()); Assert.assertTrue(build.isOriginal()); } @Test public void givenBuilderWithDefaultValue_thenNoArgsWorksAlso() { Pojo build = new Pojo().toBuilder() .build(); Pojo pojo = new Pojo(); Assert.assertEquals(build.getName(), pojo.getName()); Assert.assertTrue(build.isOriginal() == pojo.isOriginal()); }
Sekali lagi, kedua-dua ujian lulus, jadi kami mempunyai nilai lalai yang sama menggunakan konstruktor no-args seperti ketika menggunakan pembangun.
8. Kesimpulannya
Oleh itu, kami telah melihat beberapa pilihan untuk memberikan nilai lalai untuk pembangun Lombok.
Kesan sampingan Pembina . Anotasi lalai patut diperhatikan. Tetapi, pilihan lain mempunyai kekurangannya juga. Oleh itu, kita harus memilih dengan teliti berdasarkan keadaan semasa.
Seperti biasa, kodnya tersedia di GitHub.