Buku “Belajar Java EE. Pemrograman modern untuk perusahaan besar "

gambar Hai Habr!

Buku ini menjelaskan tentang generasi baru Java EE. Anda akan memulai perjalanan melalui Java EE dalam konteks dunia modern layanan dan wadah mikro. Ini bukan panduan referensi untuk sintaksis API - konsep dan teknik yang disajikan di sini mencerminkan pengalaman nyata seseorang yang baru-baru ini berjalan di jalur ini, memperhatikan dengan seksama kendala yang muncul, dan siap untuk berbagi pengetahuannya. Dalam berbagai situasi, mulai dari membuat paket untuk pengujian dan penggunaan cloud, buku ini akan menjadi pendamping yang ideal untuk pemula dan pengembang berpengalaman yang berusaha memahami lebih dari sekadar API, dan membantu mereka membangun kembali pemikiran mereka untuk membuat arsitektur aplikasi modern di Java EE .

Urutan eksekusi


Proses bisnis yang diterapkan dalam aplikasi perusahaan menggambarkan aliran proses tertentu. Untuk skenario bisnis yang terlibat, ini adalah proses permintaan dan tanggapan yang sinkron, atau pemrosesan tidak sinkron dari proses yang dimulai.

Skenario bisnis disebut dalam utas terpisah, satu utas per permintaan atau panggilan. Streaming dibuat oleh wadah dan dimasukkan ke dalam drive untuk digunakan kembali setelah panggilan berhasil diproses. Secara default, proses bisnis yang didefinisikan dalam kelas aplikasi, serta tugas lintas sektor seperti transaksi, dijalankan secara berurutan.

Eksekusi sinkron


Skenario khas ketika permintaan HTTP membutuhkan respons dari database diimplementasikan sebagai berikut. Satu utas memproses permintaan yang tiba di loop, misalnya, Sumber Daya Pengguna JAX-RS, dengan membalikkan prinsip kontrol; Metode sumber daya JAX-RS disebut oleh wadah. Sumber daya mengimplementasikan dan menggunakan EJB UserManagement, yang juga secara implisit disebut oleh wadah. Semua operasi dilakukan oleh perantara secara serempak. Pengguna EJB akan menggunakan manajer entitas untuk menyimpan entitas baru, dan segera setelah metode bisnis yang memulai transaksi yang aktif selesai, wadah akan mencoba untuk melakukan transaksi ke database. Bergantung pada hasil transaksi, metode sumber daya sirkuit melanjutkan operasi dan menghasilkan respons kepada klien. Semuanya terjadi secara serempak, pada saat ini klien diblokir dan menunggu tanggapan.

Eksekusi sinkron mencakup pemrosesan peristiwa CDI sinkron. Mereka memisahkan pemicu peristiwa domain dari prosesnya, namun, peristiwa diproses secara serempak. Ada beberapa metode untuk memantau transaksi. Jika tahap transaksi ditunjukkan, maka peristiwa tersebut dapat diproses pada tahap ini - selama memperbaiki transaksi, sebelum penyelesaiannya, setelah selesai, dalam kasus transaksi yang gagal atau berhasil. Secara default, atau jika transaksi tidak aktif, acara CDI segera diproses saat terjadi. Ini memungkinkan para insinyur untuk mengimplementasikan solusi yang kompleks - misalnya, menggunakan peristiwa yang terjadi hanya setelah berhasil menambahkan entitas ke database. Bagaimanapun, dalam semua kasus, pemrosesan dilakukan secara serempak.

Eksekusi tidak sinkron


Pelaksanaan tugas yang disinkronkan memenuhi persyaratan banyak skenario bisnis, tetapi ada kalanya Anda memerlukan perilaku tidak sinkron. Ada sejumlah batasan pada penggunaan utas oleh lingkungan Java EE. Kontainer mengelola sumber daya dan mengalir serta menempatkannya dalam drive. Utilitas kontrol konkurensi eksternal terletak di luar wadah, dan mereka tidak mengetahui aliran ini. Oleh karena itu, kode aplikasi tidak boleh berjalan dan mengendalikan utasnya. Untuk melakukan ini, ia menggunakan fitur Java EE. Ada beberapa API dengan dukungan asinkron bawaan.

Metode Asinkron EJB

Cara termudah untuk menerapkan perilaku asinkron adalah dengan menggunakan anotasi @ Asinkron untuk metode bisnis kelas EJB atau EJB. Panggilan ke metode ini segera kembali, kadang-kadang dengan respons tipe Future. Mereka berjalan di utas terpisah yang dikendalikan oleh wadah. Metode ini berfungsi dengan baik untuk skenario sederhana, tetapi terbatas pada EJB:

@Asynchronous @Stateless public class Calculator { public void calculatePi(long decimalPlaces) { //      } } 

Layanan manajemen kinerja

Untuk pelaksanaan tugas yang tidak sinkron dalam objek CDI yang dikelola atau menggunakan utilitas kontrol konkurensi Java SE, Java EE mencakup versi yang dikelola kontainer dari fungsi ExecutorService dan ScheduledExecutorService. Mereka digunakan untuk mengimplementasikan tugas-tugas tidak sinkron dalam utas yang digerakkan oleh wadah. Contoh ManagedExecutorService dan ManagedScheduledExecutorService tertanam dalam kode aplikasi. Mereka dapat digunakan untuk mengeksekusi logika mereka sendiri, tetapi paling efektif ketika dikombinasikan dengan utilitas kontrol konkurensi Java SE, seperti nilai-nilai masa depan yang dilengkapi. Contoh berikut menunjukkan cara membuat nilai masa depan empuk menggunakan utas yang digerakkan oleh wadah:

 import javax.annotation.Resource; import javax.enterprise.concurrent.ManagedExecutorService; import java.util.Random; import java.util.concurrent.CompletableFuture; @Stateless public class Calculator { @Resource ManagedExecutorService mes; public CompletableFuture<Double> calculateRandomPi(int maxDecimalPlaces) { return CompletableFuture.supplyAsync(() -> new Random().nextInt(maxDecimalPlaces) + 1, mes) .thenApply(this::calculatePi); } private double calculatePi(long decimalPlaces) { … } } 

Objek Kalkulator mengembalikan nilai masa depan yang dilengkapi dari tipe ganda, yang masih dapat dihitung saat konteks panggilan dilanjutkan. Itu dapat diminta ketika perhitungan selesai, serta dikombinasikan dengan perhitungan selanjutnya. Tidak masalah di mana utas baru diperlukan dalam aplikasi perusahaan, Anda harus menggunakan fungsionalitas Java EE untuk mengelolanya.

Acara CDI Asinkron

Acara CDI juga dapat diproses secara tidak sinkron. Dalam hal ini, wadah juga menyediakan aliran untuk menangani acara. Untuk menjelaskan peristiwa pengendali asinkron, metode ini dijelaskan dengan @ObservesAsync, dan acara tersebut diaktifkan menggunakan metode fireAsync (). Cuplikan kode berikut menunjukkan peristiwa CDI asinkron:

 @Stateless public class CarManufacturer { @Inject CarFactory carFactory; @Inject Event<CarCreated> carCreated; public Car manufactureCar(Specification spec) { Car car = carFactory.createCar(spec); carCreated.fireAsync(new CarCreated(spec)); return car; } } 

Pengatur kejadian dipanggil dengan utas yang dikelola wadah sendiri:

 import javax.enterprise.event.ObservesAsync; public class CreatedCarListener { public void onCarCreated(@ObservesAsync CarCreated event) { //    } } 

Untuk alasan kompatibilitas ke belakang, peristiwa CDI sinkron juga dapat diproses dalam metode EJB asinkron. Dengan demikian, peristiwa dan penangan didefinisikan sebagai sinkron, dan metode penangan adalah metode bisnis EJB dengan penjelasan @Asynchronous. Sebelum peristiwa asinkron diperkenalkan ke standar CDI untuk Java EE 8, ini adalah satu-satunya cara untuk mengimplementasikan fitur ini. Untuk menghindari kebingungan di Java EE 8 dan yang lebih baru, implementasi ini sebaiknya dihindari.

Lingkup Pemrosesan Asinkron

Karena wadah tidak memiliki informasi tentang berapa lama tugas asinkron dapat dilakukan, penggunaan cakupan dalam kasus ini terbatas. Objek dengan cakupan dalam permintaan atau sesi yang tersedia saat tugas asinkron diluncurkan tidak serta merta akan aktif selama implementasinya - permintaan dan sesi dapat berakhir jauh sebelum selesai. Dengan demikian, utas yang melakukan tugas asinkron, seperti yang disediakan oleh layanan pelaksana yang dijadwalkan atau peristiwa asinkron, mungkin tidak memiliki akses ke instance objek yang dikelola dengan ruang lingkup dalam permintaan atau sesi yang aktif selama panggilan. Hal yang sama berlaku untuk mengakses tautan ke instance tertanam, misalnya dalam metode lambda yang merupakan bagian dari eksekusi sinkron.

Ini harus diperhitungkan saat memodelkan tugas asinkron. Semua informasi tentang panggilan tertentu harus diberikan pada saat tugas dimulai. Namun, tugas asinkron dapat memiliki instance objek yang dikelola sendiri dengan cakupan terbatas.

Tetapkan waktu eksekusi

Skenario bisnis dapat dipanggil tidak hanya dari luar, misalnya, melalui permintaan HTTP, tetapi juga dari dalam aplikasi - tugas yang berjalan pada waktu tertentu.

Di dunia Unix, fungsionalitas untuk menjalankan pekerjaan berkala sangat populer - ini adalah tugas-tugas penjadwal. EJB menyediakan kemampuan yang sama menggunakan pengukur waktu EJB. Pengatur waktu memanggil metode bisnis pada interval yang ditentukan atau setelah waktu yang ditentukan. Contoh berikut menjelaskan pengatur waktu siklus yang dimulai setiap sepuluh menit:

 import javax.ejb.Schedule; import javax.ejb.Startup; @Singleton @Startup public class PeriodicJob { @Schedule(minute = "*/10", hour = "*", persistent = false) public void executeJob() { //   10  } } 

Setiap EJB - singleton, objek terkelola dengan atau tanpa persistensi negara - dapat membuat pengatur waktu. Namun, dalam sebagian besar skenario masuk akal untuk membuat penghitung waktu hanya untuk tunggal. Penundaan diatur untuk semua objek yang aktif. Biasanya diperlukan untuk meluncurkan tugas yang dijadwalkan dalam waktu, itulah sebabnya itu digunakan dalam singleton. Untuk alasan yang sama, dalam contoh ini, objek EJB harus aktif ketika aplikasi dimulai. Ini memastikan bahwa penghitung waktu mulai bekerja segera.

Jika Anda menggambarkan timer sebagai konstanta, maka masa pakainya meluas ke seluruh siklus hidup JVM. Kontainer bertanggung jawab untuk menyimpan timer yang persisten, biasanya dalam database. Penghitung waktu permanen, yang seharusnya berfungsi saat aplikasi tidak tersedia, hidup saat startup. Ini juga memungkinkan Anda untuk menggunakan penghitung waktu yang sama dengan banyak instance objek. Penghitung waktu konstan dengan konfigurasi server yang sesuai adalah solusi yang tepat jika Anda perlu menjalankan proses bisnis tepat sekali di beberapa server.

Pengatur waktu yang dibuat secara otomatis menggunakan anotasi Jadwal diuraikan menggunakan ekspresi cron seperti Unix. Untuk menambah fleksibilitas, pengukur waktu EJB dijelaskan secara terprogram menggunakan layanan pengatur waktu yang disediakan wadah, yang menciptakan metode Pengingat Waktu Balik dan waktu habis .

Tugas periodik dan tangguhan juga dapat dijelaskan di luar EJB menggunakan layanan penjadwal yang dikelola kontainer. Sebuah instance dari ManagedScheduledExecutorService yang melakukan tugas setelah penundaan yang ditentukan atau pada interval yang ditentukan diimplementasikan dalam komponen yang dikelola. Tugas-tugas ini akan diimplementasikan dalam utas yang digerakkan oleh wadah:

 @ApplicationScoped public class Periodic { @Resource ManagedScheduledExecutorService mses; public void startAsyncJobs() { mses.schedule(this::execute, 10, TimeUnit.SECONDS); mses.scheduleAtFixedRate(this::execute, 60, 10, TimeUnit.SECONDS); } private void execute() { … } } 

Memanggil metode startAsyncJobs () akan menjalankan fungsi execute () pada utas yang dikelola sepuluh detik setelah panggilan dan kemudian setiap sepuluh detik setelah menit pertama.

Sinkronisasi dan reaktivitas dalam JAX-RS

JAX-RS mendukung perilaku asinkron sehingga tidak perlu memblokir aliran permintaan sisi server. Bahkan jika koneksi HTTP sedang menunggu tanggapan, aliran permintaan dapat terus memproses permintaan lain sementara proses yang panjang berjalan di server. Alur permintaan dikumpulkan dalam wadah, dan repositori permintaan ini berukuran tertentu. Agar tidak membuang aliran permintaan, metode sumber daya asinkron JAX-RS membuat tugas yang dieksekusi ketika aliran permintaan kembali dan dapat digunakan kembali. Koneksi HTTP dilanjutkan dan memberikan respons setelah selesainya tugas asinkron atau setelah batas waktu. Contoh berikut menunjukkan metode sumber daya sinkron JAX-RS:

 @Path("users") @Consumes(MediaType.APPLICATION_JSON) public class UsersResource { @Resource ManagedExecutorService mes; … @POST public CompletionStage<Response> createUserAsync(User user) { return CompletableFuture.supplyAsync(() -> createUser(user), mes); } private Response createUser(User user) { userStore.create(user); return Response.accepted().build(); } } 

Agar alur permintaan sibuk terlalu lama, metode JAX-RS harus diselesaikan dengan cepat. Ini disebabkan oleh fakta bahwa metode sumber daya dipanggil dari wadah dengan cara inversi kontrol. Hasil yang diperoleh pada tahap penyelesaian akan digunakan untuk melanjutkan koneksi klien pada akhir pemrosesan.

Tahap pengembalian penyelesaian adalah teknologi yang relatif baru di JAX-RS API. Jika Anda perlu menjelaskan keterlambatan dan pada saat yang sama memberikan fleksibilitas yang lebih besar dengan respons asinkron, Anda dapat memasukkan tipe AsyncResponse dalam metode ini. Pendekatan ini ditunjukkan dalam contoh berikut:

 import javax.ws.rs.container.AsyncResponse; import javax.ws.rs.container.Suspended; @Path("users") @Consumes(MediaType.APPLICATION_JSON) public class UsersResource { @Resource ManagedExecutorService mes; … @POST public void createUserAsync(User user, @Suspended AsyncResponse response) { response.setTimeout(5, TimeUnit.SECONDS); response.setTimeoutHandler(r -> r.resume(Response.status(Response.Status.SERVICE_UNAVAILABLE).build())); mes.execute(() -> response.resume(createUser(user))); } } 

Berkat batas waktu yang dibuat, permintaan klien tidak akan menunggu tanpa batas, tetapi hanya sampai hasilnya diterima atau batas waktu panggilan berakhir. Namun, penghitungan akan berlanjut karena dilakukan secara tidak sinkron. Untuk sumber daya JAX-RS diimplementasikan sebagai EJBs, Anda dapat menerapkan anotasi @Asynchronous sehingga Anda tidak secara eksplisit memanggil metode bisnis asinkron melalui pelaksana layanan.

Klien JAX-RS juga mendukung perilaku asinkron. Bergantung pada persyaratan, masuk akal untuk tidak memblokirnya selama panggilan HTTP. Contoh sebelumnya menunjukkan cara mengatur penundaan untuk permintaan klien. Untuk panggilan sistem eksternal yang berjalan lama dan terutama paralel, lebih baik menggunakan perilaku asinkron dan reaktif.

Pertimbangkan beberapa aplikasi server yang menyediakan informasi cuaca. Komponen klien mengakses semua aplikasi ini dan menghitung perkiraan cuaca rata-rata. Idealnya, Anda dapat membuat akses ke sistem paralel:

 import java.util.stream.Collectors; @ApplicationScoped public class WeatherForecast { private Client client; private List<WebTarget> targets; @Resource ManagedExecutorService mes; @PostConstruct private void initClient() { client = ClientBuilder.newClient(); targets = … } public Forecast getAverageForecast() { return invokeTargetsAsync() .stream() .map(CompletableFuture::join) .reduce(this::calculateAverage) .orElseThrow(() -> new IllegalStateException("   ")); } private List<CompletableFuture<Forecast>> invokeTargetsAsync() { return targets.stream() .map(t -> CompletableFuture.supplyAsync(() -> t .request(MediaType.APPLICATION_JSON_TYPE) .get(Forecast.class), mes)) .collect(Collectors.toList()); } private Forecast calculateAverage(Forecast first, Forecast second) { … } @PreDestroy public void closeClient() { client.close(); } } 

Metode invokeTargetAsync () memanggil objek yang tersedia secara serempak, menggunakan layanan pelaksana terjadwal. Deskriptor CompletableFuture dikembalikan dan digunakan untuk menghitung hasil rata-rata. Awal metode join () akan diblokir sampai panggilan selesai dan hasilnya diterima.

Objek yang disebut mulai secara tidak sinkron dan menunggu respons dari beberapa sumber sekaligus, mungkin lebih lambat. Dalam hal ini, menunggu respons dari sumber daya layanan cuaca membutuhkan waktu sebanyak yang diharapkan dari respons yang paling lambat, dan tidak semua respons bersama.

Versi terbaru JAX-RS memiliki dukungan bawaan untuk tahap penyelesaian, yang mengurangi kode stereotip dalam aplikasi. Seperti halnya nilai padded, panggilan segera mengembalikan kode fase penyelesaian untuk referensi di masa mendatang. Contoh berikut menunjukkan fungsi klien reaktif JAX-RS menggunakan panggilan rx ():

 public Forecast getAverageForecast() { return invokeTargetsAsync() .stream() .reduce((l, r) -> l.thenCombine(r, this::calculateAverage)) .map(s -> s.toCompletableFuture().join()) .orElseThrow(() -> new IllegalStateException("   ")); } private List<CompletionStage<Forecast>> invokeTargetsAsync() { return targets.stream() .map(t -> t .request(MediaType.APPLICATION_JSON_TYPE) .rx() .get(Forecast.class)) .collect(Collectors.toList()); } 

Dalam contoh di atas, Anda tidak perlu mencari layanan dari pelaksana yang dijadwalkan - klien JAX-RS akan mengaturnya sendiri. Sebelum metode rx () muncul, klien menggunakan panggilan async () eksplisit. Metode ini berperilaku sama, tetapi hanya mengembalikan objek Masa Depan. Menggunakan pendekatan reaktif pada klien adalah optimal untuk sebagian besar proyek.
Seperti yang Anda lihat, Java EE menggunakan layanan artis yang dikelola kontainer.

Konsep dan prinsip desain dalam Java EE modern


API Java EE didasarkan pada konvensi dan prinsip desain yang dijabarkan sebagai standar. Insinyur perangkat lunak akan menemukan templat API yang familier dan pendekatan pengembangan aplikasi di dalamnya. Tujuan Java EE adalah untuk mempromosikan penggunaan API yang konsisten.

Prinsip utama aplikasi yang difokuskan terutama pada implementasi skenario bisnis adalah: teknologi tidak boleh mengganggu. Seperti yang telah disebutkan, insinyur harus dapat fokus pada penerapan logika bisnis tanpa menghabiskan sebagian besar waktu pada masalah teknologi dan infrastruktur. Idealnya, logika domain diterapkan di Jawa sederhana dan dilengkapi dengan anotasi dan properti lain yang didukung oleh lingkungan perusahaan, tanpa memengaruhi kode domain atau mempersulitnya. Ini berarti bahwa teknologi tidak memerlukan banyak perhatian dari para insinyur dan tidak memaksakan pembatasan terlalu besar. Lingkungan J2EE dulu membutuhkan banyak solusi yang sangat kompleks. Untuk mengimplementasikan antarmuka dan memperluas kelas dasar, kami harus menggunakan objek yang dikelola dan objek penyimpanan yang persisten. Ini mempersulit logika area subjek dan membuat pengujian menjadi sulit.

Dalam Java EE, logika domain diimplementasikan dalam bentuk kelas-kelas Java sederhana yang dilengkapi dengan anotasi, yang menurutnya wadah tersebut menyelesaikan tugas-tugas korporat tertentu selama eksekusi aplikasi. Praktek membuat kode bersih seringkali melibatkan penulisan kode yang lebih indah daripada nyaman untuk digunakan kembali. Java EE mendukung pendekatan ini. Jika karena alasan tertentu Anda perlu menghapus teknologi dan meninggalkan logika murni area subjek, ini dilakukan hanya dengan menghapus anotasi yang sesuai.

Seperti yang akan kita lihat di Bab 7, pendekatan pemrograman ini menyiratkan perlunya pengujian, karena untuk programmer, sebagian besar spesifikasi Java EE tidak lebih dari penjelasan.

Di seluruh API, prinsip desain yang disebut inversion of control (IoC) telah diadopsi - dengan kata lain, "jangan panggil kami, kami akan menyebut diri kami sendiri." Ini terutama terlihat di sirkuit aplikasi, seperti sumber daya JAX-RS. Metode sumber daya dijelaskan menggunakan anotasi metode Java, yang kemudian dipanggil oleh wadah dalam konteks yang sesuai. Hal yang sama berlaku untuk injeksi ketergantungan, di mana Anda harus memilih generator atau mempertimbangkan tugas lintas sektoral seperti pencegat. Pengembang aplikasi dapat fokus pada penerapan logika dan menggambarkan hubungan, meninggalkan penerapan detail teknis dalam sebuah wadah. Contoh lain, tidak begitu jelas, adalah deskripsi mengkonversi objek Java ke JSON dan sebaliknya melalui penjelasan JSON-B. Objek ditransformasikan tidak hanya dalam bentuk eksplisit, terprogram, tetapi juga secara implisit, dalam gaya deklaratif.

Prinsip lain yang memungkinkan para insinyur untuk menerapkan teknologi ini secara efektif adalah pemrograman berdasarkan kesepakatan. Secara default, Java EE mendefinisikan perilaku tertentu yang cocok dengan sebagian besar skenario penggunaan. Jika tidak cukup atau tidak memenuhi persyaratan, perilaku dapat didefinisikan ulang, seringkali pada beberapa tingkatan.
Ada banyak contoh pemrograman konvensi. Salah satunya adalah penggunaan metode sumber daya JAX-RS yang mengubah fungsi Java menjadi respons HTTP. Jika perilaku standar JAX-RS sehubungan dengan tanggapan tidak memenuhi persyaratan, Anda dapat menerapkan jenis respons tersebut. Contoh lain adalah spesifikasi objek yang dikelola, yang biasanya diimplementasikan menggunakan anotasi. Untuk mengubah perilaku ini, Anda dapat menggunakan deskriptor XML beans.xml. Sangat mudah bagi para programmer bahwa di dunia Java EE modern, aplikasi perusahaan dikembangkan dengan cara pragmatis dan berkinerja tinggi yang biasanya tidak memerlukan penggunaan intensif XML seperti sebelumnya.

Adapun produktivitas programmer, prinsip penting lain dari pengembangan pada Java EE adalah bahwa platform ini memerlukan integrasi dalam wadah berbagai standar. Karena kontainer mendukung serangkaian API tertentu - dan jika seluruh Java EE API didukung, itulah yang sebenarnya terjadi - kontainer juga memerlukan implementasi API untuk menyediakan integrasi API lainnya yang mulus. Keuntungan dari pendekatan ini adalah kemampuan untuk menggunakan sumber daya JAX-RS dari konversi JSON-B dan teknologi Validasi Bean tanpa konfigurasi eksplisit tambahan, dengan pengecualian anotasi. Dalam contoh sebelumnya, kami melihat bagaimana fungsi yang didefinisikan dalam standar individu dapat digunakan bersama tanpa upaya tambahan. Ini adalah salah satu keuntungan terbesar dari platform Java EE. Spesifikasi umum menjamin kombinasi standar individu. Pemrogram dapat mengandalkan fitur dan implementasi tertentu yang disediakan oleh server aplikasi.

Mudah digunakan kode berkualitas tinggi


Pemrogram umumnya setuju bahwa Anda harus berusaha untuk menulis kode berkualitas tinggi. Namun, tidak semua teknologi sama-sama cocok untuk ini.

Seperti yang disebutkan di awal buku, fokus pada pengembangan aplikasi harus logika bisnis. Dalam hal terjadi perubahan dalam logika bisnis atau munculnya pengetahuan baru, perlu memperbarui model domain, serta kode sumber. Diperlukan refactoring berulang untuk membuat dan memelihara model domain dan kode sumber berkualitas tinggi secara keseluruhan. Upaya untuk memperdalam pemahaman tentang area subjek dijelaskan dalam konsep desain berorientasi masalah.

Ada banyak literatur tentang refactoring tingkat kode.Setelah logika bisnis disajikan dalam bentuk kode dan diverifikasi oleh tes, programmer harus meluangkan waktu dan melakukan upaya untuk memikirkan kembali dan meningkatkan opsi pertama. Ini berlaku untuk pengidentifikasi nama, metode, dan kelas. Yang sangat penting adalah pemilihan nama, tingkat abstraksi, dan titik tanggung jawab bersama.

Menurut definisi desain berorientasi masalah, area subjek harus sesuai sebanyak mungkin dengan perwakilannya dalam bentuk kode. Ini termasuk, khususnya, bahasa bidang subjek - dengan kata lain, cara programmer dan pakar bisnis berbicara tentang fungsi-fungsi tertentu. Tujuan dari seluruh tim adalah untuk menemukan bahasa umum universal yang akan digunakan secara efektif tidak hanya dalam diskusi dan slide presentasi, tetapi juga dalam kode. Penyempurnaan pengetahuan di bidang bisnis akan terjadi secara siklis. Seperti refactoring pada level kode, pendekatan ini menyiratkan bahwa model asli tidak akan sepenuhnya memenuhi semua persyaratan.

Dengan demikian, teknologi yang diterapkan harus mendukung perubahan model dan kode. Jika ada terlalu banyak batasan, maka membuat perubahan nanti akan sulit.

Untuk pengembangan aplikasi secara umum, dan terutama untuk refactoring, sangat penting bahwa perangkat lunak cukup tercakup oleh tes otomatis. Karena kode terus berubah, uji regresi memastikan bahwa tidak ada fungsi bisnis yang secara tidak sengaja rusak. Dengan demikian, sejumlah uji kontrol mendukung refactoring, memungkinkan para insinyur untuk memahami dengan jelas bahwa setelah melakukan perubahan, semua fungsi masih berfungsi seperti yang diharapkan. Idealnya, teknologi harus mendukung kemampuan untuk menguji tanpa memaksakan pembatasan pada struktur kode. Kita akan membahas ini secara lebih rinci di Bab 7.

Untuk mengaktifkan refactoring, ikatan yang lemah lebih disukai daripada ikatan yang ketat. Mengubah satu komponen memengaruhi semua fungsi yang secara eksplisit menyebutnya, dan semua komponen yang dibutuhkan. Java EE mendukung beberapa opsi pengikatan yang lemah: injeksi ketergantungan, peristiwa, dan tugas ujung ke ujung seperti kait. Semua ini menyederhanakan perubahan kode.

Ada sejumlah alat dan metode untuk mengukur kualitas. Secara khusus, analisis kode statis memungkinkan Anda untuk mengumpulkan informasi tentang kompleksitas, konektivitas, dependensi antara kelas dan paket, dan implementasinya secara keseluruhan. Alat-alat ini membantu insinyur mengidentifikasi potensi masalah dan membuat gambaran luas tentang proyek perangkat lunak. Bab 6 akan menunjukkan kepada Anda cara memeriksa kualitas kode secara otomatis.

Secara umum, disarankan untuk terus menata ulang kode dan meningkatkan kualitasnya. Proyek perangkat lunak sering dibuat untuk memperkenalkan fungsi penghasil pendapatan baru, dan bukan untuk meningkatkan fungsionalitas yang ada. Masalahnya adalah bahwa refactoring dan peningkatan kualitas kode pada pandangan pertama tidak membawa manfaat bagi bisnis. Tentu saja tidak demikian. Untuk mencapai kecepatan yang stabil dan mengintegrasikan fungsi-fungsi baru dengan kualitas yang memuaskan, perlu untuk meninjau fungsi yang ada. Idealnya, loop refactoring harus tertanam dalam diagram proyek. Pengalaman menunjukkan bahwa manajer proyek sering tidak menyadari masalah ini. Namun, tim insinyur perangkat lunak bertanggung jawab untuk menjaga kualitas.

Tentang penulis


Sebastian Daschner adalah pekerja lepas Java yang bekerja sebagai konsultan dan guru, pemrogram dan penyuka Java (EE). Dia mengambil bagian dalam JCP, membantu menciptakan standar Java EE baru, melayani 37SR dan 374 kelompok ahli di JSR dan bekerja di berbagai proyek sumber terbuka. Untuk kontribusinya pada komunitas dan ekosistem Jawa, ia telah dianugerahi gelar Java and Oracle Development Champion.

Sebastian secara teratur berbicara di konferensi IT internasional seperti JavaLand, JavaOne, dan Jfokus. Dia menerima JavaOne Rockstar Award di JavaOne Conference 2016. Bersama dengan manajer komunitas Java Steve Chin, dia menghadiri puluhan konferensi dan kelompok pengguna Java saat bepergian dengan sepeda motor. Steve dan Sebastian menciptakan JOnsen, sebuah konferensi non-Jawa yang diadakan di sumber air panas di pedesaan Jepang.

Tentang Peninjau


Melissa McKay adalah pengembang perangkat lunak dengan 15 tahun pengalaman menciptakan berbagai jenis aplikasi untuk klien dan perusahaan swasta. Sekarang ia terutama bergerak dalam aplikasi Java sisi server yang digunakan di bidang komunikasi dan televisi. Minatnya meliputi sistem cluster, ia memiliki hasrat khusus untuk memecahkan masalah yang terkait dengan aplikasi paralel dan multi-berulir.

Melissa secara teratur menghadiri non-konferensi JCrete di Kreta, Yunani, dan senang menghadiri pembukaan non-konferensi JOnsen di Jepang. Dia menikmati berpartisipasi dalam konferensi IT sukarelawan untuk anak-anak, seperti JavaOne4Kids dan JCrete4Kids. Dia adalah anggota komite konten di JavaOne 2017 dan merupakan anggota aktif dari Kelompok Pengguna Java Denver.

»Informasi lebih lanjut tentang buku ini dapat ditemukan di situs web penerbit
» Isi
» Kutipan

Kupon diskon 20% untuk penjaja - Java EE

Source: https://habr.com/ru/post/id418025/


All Articles