Helo, artikel hari ini membincangkan pandangan yang kelihatan tidak popular, dan saya pasti ia akan mendapat tentangan. Hanya kerana sesuatu boleh dilaksanakan secara teknikal tidak mengesahkan utiliti atau kesesuaiannya secara automatik. Oleh itu, saya akan cuba untuk membuktikan sebab saya percaya menggunakan Lombok boleh menjejaskan kod anda.
Sebelum mendalami butiran yang kurang popular, izinkan saya memberikan penjelasan ringkas tentang cara perpustakaan Lombok berfungsi.
Projek Lombok bertindak sebagai perpustakaan yang menyuntik kod ke dalam kelas pada masa penyusunan, yang mungkin kelihatan hampir ajaib. Untuk memahami operasinya, memahami proses penyusunan Java adalah penting. Penyusunan Java melibatkan tiga peringkat utama (Rajah 1): Parse dan Enter, Pemprosesan Anotasi, dan Analyse and Generate, seperti yang digambarkan dalam rajah berikut:
Rajah 1 – Pokok Sintaks Abstrak (AST)
Hilang dan Masukkan:
Di sini, pengkompil menukar fail sumber kepada Pokok Sintaks Abstrak (AST). Ralat hanya dilemparkan untuk sintaks yang tidak sah, bukan untuk penggunaan kelas atau kaedah yang salah.
Pemprosesan Anotasi:
Semasa fasa ini, pemproses anotasi tersuai mengesahkan kelas atau menjana sumber baharu seperti fail sumber. Ini boleh mencetuskan kitaran kompilasi baharu jika sumber baharu dijana.
Analisis dan Jana:
Pada peringkat akhir ini, pengkompil menghasilkan kod bait daripada AST, menyemak rujukan yang rosak, mengesahkan aliran logik, melakukan pemadaman jenis dan gula sintaktik desugaring.
Projek Lombok beroperasi sebagai pemproses anotasi, mengubah suai AST dengan menyuntik kaedah, medan atau ungkapan baharu. Tidak seperti pemproses biasa yang menjana sumber baharu, Lombok mengubah kelas sedia ada, satu perbezaan yang membolehkannya memberi kesan langsung kepada kod bait yang dijana.
AnnotationProcessor yang diperkenalkan dalam J2SE 1.5 tidak boleh membuat perubahan pada fail sedia ada. Ia hanya boleh mencipta fail baharu atau kod bait. Ini menjadikan pelaksanaan lombok menarik, kerana mereka menggunakan AnnotationProcessor untuk mengubah suai fail kelas java sedia ada, semasa fasa penyusunan. Berikut ialah gambaran keseluruhan
proses penyusunan dengan Lombok (Rajah 2).
Rajah 2 – Proses penyusunan dan Lombok
Setelah memahami keajaiban di sebalik Lombok, mari kita selidiki sebab saya percaya ia boleh memudaratkan pangkalan kod anda.
Operasi Lombok pada masa penyusunan pasti memanjangkan proses penyusunan, terutamanya dinyatakan dalam pangkalan kod yang lebih besar disebabkan oleh peningkatan pengurusan AST yang diperlukan.
Lombok menawarkan pelbagai anotasi yang mungkin memberikan ilusi menyelesaikan cabaran pengaturcaraan asas. Saya akan membincangkan beberapa anotasi ini yang kerap saya temui dalam pangkalan kod.
Anotasi @Builder di Lombok memudahkan penciptaan objek melalui corak pembina, menambahkan lapisan kemudahan yang pada mulanya menarik. Pertimbangkan contoh ini:
@Data @Builder public class Course { public enum Type { ONLINE, ONSITE; @JsonValue @Override public String toString() { return super.toString().toLowerCase(); } } private long id; private Type type; }
Dan penggunaannya:
public class CourseCreator { public static Course createCourse(Enrollment enrollment, Registration registration) { Course.Type courseType = enrollment.getVenue().equals(registration.getVenue()) ? Course.Type.ONSITE : Course.Type.ONLINE; return Course.builder() .id(enrollment.getId()) .type(courseType) .build(); } public static void main(String[] args) { Registration registration = new Registration(); Enrollment enrollment = new Enrollment(); Course course = createCourse(enrollment, registration); System.out.println(course); } }
Sementara corak pembina dilaksanakan dengan cekap, persoalan penting tentang integriti dan kesahihan objek yang dicipta ditimbulkan.
Apakah jenis kursus yang kita nyatakan jika kita meninggalkan .type() dalam pembina?
Barisan kod ini akan disusun, tetapi ia membuatkan kita tertanya-tanya: Apakah jenis kursus yang sebenarnya telah kita buat? Adakah ini contoh kursus yang sah?
Course.builder().id(1L).build();
Kebimbangan ini mencadangkan bahawa pembangun, mungkin terpengaruh dengan kemudahan anotasi, mungkin terlepas pandang pemodelan domain menyeluruh yang diperlukan untuk mengekalkan integriti logik perniagaan. Daripada membiarkan Lombok menentukan reka bentuk kami, pendekatan yang lebih dipertimbangkan untuk memastikan penjajaran dengan keperluan perniagaan adalah penting.
Pertimbangkan untuk melaraskan pelaksanaan untuk memastikan bahawa sebarang penciptaan kursus adalah jelas dan terhad dalam konteks perniagaan:
@Data public class Course { private enum Type { ONLINE, ONSITE; @JsonValue @Override public String toString() { return super.toString().toLowerCase(); } } public static Course online(long id) { return new Course(id, Type.ONLINE); } public static Course onsite(long id) { return new Course(id, Type.ONSITE); } private long id; private Type type; public boolean isOnline() { return Type.ONLINE.equals(this.type); } public boolean isOnsite() { return Type.ONSITE.equals(this.type); } }
Dengan mereka bentuk semula kelas:
public class CourseManagement { public static Course createAppropriateCourse(Enrollment enrollment, Registration registration) { return enrollment.getVenue().equals(registration.getVenue()) ? Course.onsite(enrollment.getId()) : Course.online(enrollment.getId()); } public static void main(String[] args) { Registration registration = new Registration(); Enrollment enrollment = new Enrollment(); Course createdCourse = createAppropriateCourse(enrollment, registration); System.out.println(createdCourse); } }
Reka bentuk yang disemak memastikan bahawa penciptaan objek Kursus adalah eksplisit dan kalis mudah, mencerminkan pilihan terhad yang wujud dalam domain dan menghapuskan kesamaran.
Selain itu, dengan menjadikan Type enum peribadi dan menyediakan kaedah yang jelas dan eksplisit seperti isOnline() dan isOnsite(), kami memastikan bahawa hanya keadaan sah didedahkan dan dimanipulasi, menjaga integriti domain.
Through this thoughtful restructuring, we demonstrate that while tools like Lombok can significantly reduce boilerplate, they are not substitutes for careful design and a deep understanding of the domain. It underscores that Lombok should be employed judiciously, complementing rather than overshadowing robust architectural practices. This ensures that the elegance of our code does not come at the expense of its correctness and clarity.
The argument that getters and setters reduce boilerplate falls short when Java offers alternatives like the Record classes from Java 14.
@Data public class Movie { private String title; private int releaseYear; } // Can be replaced with: public record Movie(String title, int releaseYear) {}
Having null in your code - aside from inputs is generally considered problematic and is often indicative of deeper design issues. The prevalent advice is to avoid returning null whenever possible. Instead, opt for alternatives such as returning non-null collections, utilizing null objects, or throwing exceptions to signify unusual or exceptional conditions. This strategic avoidance means null checks become redundant in most parts of your code.
To distance from Lombok's @NonNull annotation and ensure robustness in Java natively, the Objects.requireNonNull() method from the java.util.Objects class is incredibly useful.
This method streamlines null checking by ensuring that an object is not null, and it throws a NullPointerException with a clear message if it is. This explicit exception-throwing mechanism prevents latent null-related bugs from surfacing in runtime, promoting earlier detection during the development cycle. Here’s an example showing how this method can replace Lombok's functionality
Using Lombok's@NonNull:
public class NonNullExample { private Student student; public NonNullExample(@NonNull Student student) { this.student = student; } }
Equivalent pure Java approach:
import java.util.Objects; public class NonNullExample { private Student student; public NonNullExample(Student student) { this.student = Objects.requireNonNull(student, "Student cannot be null"); } }
This transition to native Java handling enhances code transparency by making the null-check explicit, which is advantageous for code maintenance and understanding.
Constructors play a critical role in how classes interact within your software architecture. A well-designed class should have a variety of constructors that accommodate different use cases, promoting reusability and flexibility. If your constructors merely replicate field assignments, the underlying issue isn't the need to write boilerplate code; rather, it's the risk of fostering a non-reusable and inflexible design that Lombok cannot rectify. Proper constructor design allows a class to be integrated and utilized in a multitude of scenarios, enhancing the overall robustness and adaptability of your codebase.
Lombok's popularity predominantly stems from its ability to reduce boilerplate code, particularly in domain-specific classes like transfer and data objects. While Lombok effectively diminishes the visible clutter by auto-generating necessary code like getters, setters, equals, hashCode, and toString methods, this convenience might obscure potential pitfalls. However, with the advent of Java Records introduced in Java 14, there is a preferable alternative that natively supports the concise declaration of immutable data carriers. Most integrated
development environments (IDEs) are also equipped to automatically generate these boilerplate codes with minimal user input, offering a balance between Lombok’s automation and the control of traditional Java coding.
Project Lombok's dependency on the underlying Java version poses a significant compatibility risk. As Java evolves, the Abstract Syntax Tree (AST) structure and its interpretation could change, necessitating continuous updates to Lombok to ensure compatibility. This creates a fragile dependency where upgrading to a newer Java version could potentially break your build if Lombok is not simultaneously updated to support these changes. The reliance on unofficial or private APIs to modify class definitions further exacerbates this issue because these APIs could be restricted or altered in future Java releases, threatening Lombok’s long-term viability.
Menggunakan Lombok boleh membawa kepada komplikasi apabila membina projek dengan alatan yang hanya menggunakan pilihan pengkompil Java standard. Contohnya, jika kod anda menggunakan getter dan setter yang dijana oleh Lombok, menyusun terus dengan javac tanpa pra-pemprosesan Lombok boleh mengakibatkan ralat yang menunjukkan kaedah hilang. Walaupun sesetengah orang mungkin menganggap keupayaan Lombok untuk menyuntik kod sebagai "helah" yang bijak, adalah penting untuk menilai secara kritis risiko dan alternatif yang berkaitan. Teras isu ini terletak pada fakta bahawa spesifikasi pemprosesan anotasi Java tidak secara rasmi menyokong pengubahsuaian kelas sedia ada semasa penyusunan. Bergantung pada teknik tidak rasmi ini menjadikan Lombok terdedah kepada kemas kini Java masa hadapan yang berpotensi mengganggu atau melumpuhkan fungsinya.
Akhirnya, pertimbangan ini menekankan kepentingan menilai bukan sahaja manfaat segera alatan seperti Lombok tetapi juga implikasi jangka panjangnya terhadap kebolehselenggaraan, keserasian dan penjajaran dengan piawaian Java. Apabila Java terus berkembang, pergantungan pada ciri yang stabil dan standard menjadi semakin kritikal untuk memastikan kemampanan dan kebolehpercayaan projek perisian anda.
Lombok mungkin kelihatan seperti pintasan yang berguna untuk pembangunan Java, tetapi ia mengalihkan kod Java kepada versi khusus domain yang saya suka panggil "Lombok Java". Adalah penting untuk menyedari bahawa bergantung secara berlebihan pada Lombok boleh mengaburkan intipati Jawa, yang berpotensi membawa kepada kod yang kurang mantap dan sukar untuk diurus tanpa tongkat Lombok.
Jika terlalu bergantung pada Lombok adalah penyelesaian untuk mengurus pangkalan kod anda, mungkin sudah tiba masanya untuk menilai semula seni bina dan amalan asas. Kekuatan sebenar Java terletak pada kejelasan dan strukturnya, bukan pada pintasan yang disediakan oleh perpustakaan luaran.
Jika diberi peluang, saya akan memilih untuk membuang Lombok daripada projek saya.
Atas ialah kandungan terperinci Mengapa Saya Percaya Lombok Perlu Dibuang daripada Projek Java. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!