Membuat Java Builder untuk Kelas di IntelliJ

1. Pengenalan

Corak reka bentuk Builder adalah salah satu corak penciptaan yang paling banyak digunakan. Ia membantu kita membina objek yang kompleks.

Menulis pembina dengan tangan adalah rumit dan ralat. Oleh itu, kita harus menggunakan alat khusus untuk menghasilkannya secara automatik bila mungkin.

Dalam tutorial ini, kita akan meneroka pelbagai cara untuk membuat kelas pembangun secara automatik di IntelliJ IDE. Kami akan melihat ciri-ciri bawaan yang disediakan IntelliJ di luar kotak, dan juga pemalam pihak ketiga.

2. Persediaan Awal

Sepanjang artikel ini, kami akan menggunakan versi 2019.1.3 edisi Komuniti IntelliJ IDEA, yang merupakan rilis terbaru pada masa penulisan. Walau bagaimanapun, semua teknik yang ditunjukkan dalam contoh harus berfungsi dengan baik dengan versi IDEA yang lain juga.

Mari kita mulakan dengan menentukan kelas Buku yang mana kita akan menghasilkan pembina:

public class Book { private String title; private Author author; private LocalDate publishDate; private int pageCount; // standard constructor(s), getters and setters }

3. Menggunakan Fungsi Built-In IntelliJ

Untuk menghasilkan pembina untuk kelas Buku menggunakan alat bawaan IntelliJ, kami memerlukan pembina yang sesuai.

Mari buat satu:

public Book(String title, Author author, LocalDate publishDate, int pageCount) { this.title = title; this.author = author; this.publishDate = publishDate; this.pageCount = pageCount; }

Sekarang, kami sudah bersedia untuk membuat pembina. Oleh itu, mari letakkan kursor pada konstruktor yang dibuat dan buka tetingkap Refactor ini dengan menekan Ctrl + Alt + Shift + T (di PC) dan pilih Ganti Konstruktor dengan refactoring Builder :

Kami dapat menyesuaikan beberapa pilihan untuk kelas pembangun, seperti nama dan pakej sasarannya:

Hasilnya, kami telah menghasilkan kelas BookBuilder :

public class BookBuilder { private String title; private Author author; private LocalDate publishDate; private int pageCount; public BookBuilder setTitle(String title) { this.title = title; return this; } public BookBuilder setAuthor(Author author) { this.author = author; return this; } public BookBuilder setPublishDate(LocalDate publishDate) { this.publishDate = publishDate; return this; } public BookBuilder setPageCount(int pageCount) { this.pageCount = pageCount; return this; } public Book createBook() { return new Book(title, author, publishDate, pageCount); } }

3.1. Awalan Pengatur Tersuai

Amalan biasa untuk menggunakan awalan dengan kaedah setter dalam kelas pembina.

Untuk menukar awalan lalai, kita perlu memilih ikon Ubah Nama Tetapan Awalan di sudut kanan atas tetingkap pilihan :

3.2. Pembina Dalaman Statik

Sebilangan daripada kita mungkin lebih suka menerapkan pembangun sebagai kelas dalaman yang statik seperti yang dijelaskan oleh Joshua Bloch di Java Effective .

Sekiranya ini berlaku, kita perlu mengambil beberapa langkah tambahan untuk mencapainya dengan menggunakan fitur Replace Constructor with Builder IntelliJ .

Pertama sekali, kita perlu membuat kelas dalaman kosong secara manual dan menjadikan pembangunnya peribadi:

public class Book { private String title; private Author author; private LocalDate publishDate; private int pageCount; public static class Builder { } private Book(String title, Author author, LocalDate publishDate, int pageCount) { this.title = title; this.author = author; this.publishDate = publishDate; this.pageCount = pageCount; } // standard getters and setters }

Selanjutnya, kita harus memilih Gunakan yang ada di tetingkap pilihan dan menunjuk ke kelas yang baru kita buat:

4. Menggunakan InnerBuilder Plugin

Sekarang mari kita lihat bagaimana kita dapat menjana pembangun untuk kelas Buku menggunakan pemalam InnerBuilder.

Setelah memasang plugin, kita dapat membuka pop timbul Hasilkan dengan menekan Alt + Insert (pada PC) dan memilih pilihan Builder… :

Sebagai alternatif, kita boleh memanggil pemalam InnerBuilder secara langsung dengan menekan Alt + Shift + B (di PC):

Seperti yang kita lihat, ada beberapa pilihan yang dapat kita pilih untuk menyesuaikan pembangun yang dihasilkan.

Mari lihat pembangun dihasilkan apabila semua pilihan tidak dicentang:

public static final class Builder { private String title; private Author author; private LocalDate publishDate; private int pageCount; public Builder() { } public Builder title(String val) { title = val; return this; } public Builder author(Author val) { author = val; return this; } public Builder publishDate(LocalDate val) { publishDate = val; return this; } public Builder pageCount(int val) { pageCount = val; return this; } public Book build() { return new Book(this); } }

Plugin InnerBuilder menerapkan pembina sebagai kelas dalaman statik secara lalai.

5. Menggunakan Builder Generator Plugin

Akhirnya, mari kita lihat bagaimana Builder Generator berfungsi.

Begitu juga dengan InnerBuilder, kita boleh menekan Alt + Insert (di PC) dan memilih pilihan Builder atau menggunakan pintasan Alt + Shift + B.

Seperti yang dapat kita lihat, kita mempunyai tiga pilihan untuk menyesuaikan BookBuilder :

Mari biarkan semua pilihan tidak dicentang dan lihat kelas pembina yang dihasilkan:

public final class BookBuilder { private String title; private Author author; private LocalDate publishDate; private int pageCount; private BookBuilder() { } public static BookBuilder aBook() { return new BookBuilder(); } public BookBuilder withTitle(String title) { this.title = title; return this; } public BookBuilder withAuthor(Author author) { this.author = author; return this; } public BookBuilder withPublishDate(LocalDate publishDate) { this.publishDate = publishDate; return this; } public BookBuilder withPageCount(int pageCount) { this.pageCount = pageCount; return this; } public Book build() { Book book = new Book(); book.setTitle(title); book.setAuthor(author); book.setPublishDate(publishDate); book.setPageCount(pageCount); return book; } }

Pilihan pertama yang disediakan oleh plugin Builder Generator untuk menyesuaikan kelas pembina yang dibuat - Pembina dalaman - agak jelas.

Namun, dua yang lain lebih menarik, dan kami akan menerokainya di bahagian berikut.

5.1. 'tetapi' Pilihan Kaedah

Sekiranya kita memilih pilihan ini, plugin akan menambahkan kaedah but () ke kelas BookBuilder :

public BookBuilder but() { return aBook().withTitle(title).withAuthor(author) .withPublishDate(publishDate).withPageCount(pageCount); }

Now, let's imagine we want to create three books with the same author and the same number of pages but with different titles and publish dates. We may create a base builder with common properties already set and then use the but() method to create new BookBuilders (and Books later on) out of it.

Let's take a look at an example:

BookBuilder commonBuilder = BookBuilder.aBook().withAuthor(johnDoe).withPageCount(123); Book my_first_book = commonBuilder.but() .withPublishDate(LocalDate.of(2017, 12, 1)) .withTitle("My First Book").build(); Book my_second_book = commonBuilder.but() .withPublishDate(LocalDate.of(2018, 12, 1)) .withTitle("My Second Book").build(); Book my_last_book = commonBuilder.but() .withPublishDate(LocalDate.of(2019, 12, 1)) .withTitle("My Last Book").build();

5.2. Use a Single Field Option

If we choose this option, the generated builder will hold a reference to the created Book object instead of all the book's properties:

public final class BookBuilder { private Book book; private BookBuilder() { book = new Book(); } public static BookBuilder aBook() { return new BookBuilder(); } public BookBuilder withTitle(String title) { book.setTitle(title); return this; } public BookBuilder withAuthor(Author author) { book.setAuthor(author); return this; } public BookBuilder withPublishDate(LocalDate publishDate) { book.setPublishDate(publishDate); return this; } public BookBuilder withPageCount(int pageCount) { book.setPageCount(pageCount); return this; } public Book build() { return book; } }

This is a bit different approach to create a builder class that might come in handy in certain situations.

6. Conclusion

In this tutorial, we've explored different ways to generate builder classes in IntelliJ.

Biasanya lebih baik menggunakan alat seperti ini untuk menghasilkan pembangun kami secara automatik . Setiap pilihan yang kami kemukakan mempunyai kebaikan dan keburukan. Pendekatan mana yang sebenarnya kita pilih adalah soal selera dan pilihan individu.