Masalah yang terlupakan,
Berlari berhenti
Disuntikkan oleh robot
Selamat pria!
Dari film "Terminator Anak" "Petualangan Elektronik"
Hai, hari ini kita akan berbicara tentang kinerja lagi. Tentang produktivitas pengembang.
Saya akan berbicara tentang cara memompa keterampilan ini melalui Situs. Saya harap tips saya berguna, komentar dan perbaikan dipersilahkan. Ayo pergi!
Pengembang biasa menghabiskan sebagian besar hari kerjanya untuk kegiatan rutin. Sampai baru-baru ini, saya juga berakting. Dan kemudian beberapa pemikiran sederhana dan jelas muncul di kepala saya:
- Jarang kita menulis sesuatu yang benar-benar baru dan tidak biasa
- bagian penting dari waktu kerja, pengembang menulis kode templat
- banyak konstruksi sederhana yang kami gunakan mudah diformalkan, dan di kepala kami kami ungkapkan dengan beberapa kata
Bagian terbesar dari waktu saya bekerja dengan Spring Booth / Hibernate, sehingga sebagian besar pembuatan kode dan templat menyangkut mereka, meskipun pendekatannya bersifat universal dan Anda dapat dengan mudah melakukan perbaikan serupa untuk proyek Anda.
Teater dimulai dengan gantungan, dan aplikasi Spring Booth dimulai dengan pengaturan. Biasanya mereka masuk dalam file application.yml
/ application.properties
, tetapi juga terjadi beberapa kacang / konfigurasi harus dijelaskan dengan kode:
@Configuration @EnableSwagger2 class SwaggerConfig { @Bean Docket documentationApi() { return new Docket(DocumentationType.SWAGGER_2) .select() .apis(RequestHandlerSelectors.any()) .paths(PathSelectors.any()) .build(); } }
Pengaturan ini termasuk kesombongan (item yang berguna di pertanian). Pikirkan apa yang bisa diotomatisasi? Pengembang tahu bahwa @Configuration
ditempatkan di atas kelas pengaturan. Yaitu Anda dapat membuat semacam blank - templat dari kelas konfigurasi dan membuatnya dengan gerakan pergelangan tangan. Di luar kotak "Ide" memberi pengguna kesempatan untuk menyesuaikan template yang ada untuk diri mereka sendiri:

Apa yang akan kita gunakan:
#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end import org.springframework.context.annotation.Configuration; @Configuration class ${NAME} { }
Untuk pengembang berpengalaman, semuanya jelas di sini, untuk pemula saya akan menjelaskan:
Baris 1: baris seperti ini akan ditambahkan ke kode kelas yang baru dibuat
package com.example.-;
Baris 2: sambungkan anotasi yang diinginkan
Baris 3: kelas tubuh.
Perhatikan bahwa variabel ${NAME}
akan berubah menjadi jendela sembulan di mana kita perlu memasukkan nama kelas.
Total:

Template ini menyelamatkan kita dari keharusan menulis @Configuration
di kelas dengan tangan kita @Configuration
dan menyelesaikan impor. Tidak banyak, tetapi penting bagi kami untuk memulai dan mendapatkan pengalaman.
Kelas pengaturan kosong saja bernilai sedikit. Mari kita belajar cara membuat kacang tanpa usaha ekstra. Untuk melakukan ini, dari Editor> File dan Templat Kode , buka Editor> Templat Langsung . Di sini Anda dapat menggambarkan pola yang dikenali dengan mengetik. Di lingkungan pengembangan saya, saya mendefinisikan subspesies terpisah untuk digunakan dengan Spring. Di dalamnya kita membuat templat:
@Bean public $CLASS_NAME$ $mthdName$() { return new $CLASS_NAME$($END$); }
Variabel CLASS_NAME
disetel oleh pengguna di jendela sembulan dan, selain penugasan langsung, digunakan untuk membuat nama metode:

Variabel mthdName
menggunakan mthdName
camelCase()
, yang meneruskan nilai CLASS_NAME
. Pengaturan berlangsung di Edit variabel :

Variabel $END$
berarti posisi pointer setelah rendering. Kacang kami mungkin memiliki dependensi (diimplementasikan melalui konstruktor), jadi Anda perlu membuatnya argumen dengan metode yang mengembalikan kacang kami:

Sekarang mari kita pergi melalui aplikasi dari atas ke bawah dan melihat apa tugas sehari-hari lainnya dapat dipercepat dengan cara yang sederhana.
Layanan
Akal sehat menunjukkan bahwa metode ini akan sangat berguna dalam kasus-kasus di mana kita memiliki sejumlah besar kode yang berkeliaran dari satu tempat ke tempat lain. Sebagai contoh, layanan pegas reguler mungkin tergantung pada repositori (yang berarti bahwa transaksi diperlukan), apakah beberapa jenis logging, dan dependensi diimplementasikan melalui konstruktor. Agar tidak mencantumkan semua anotasi pada kelas yang baru dibuat setiap kali, kami menjelaskan templat:
#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end #parse("File Header.java") import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import lombok.RequiredArgsConstructor; import lombok.extern.log4j.Log4j2; @Log4j2 @Service @Transactional @RequiredArgsConstructor public class ${NAME} { }
Beraksi:

Berikutnya adalah daftar ketergantungan yang penuh kebencian. Di atas, kami menggunakan metode camelCase()
untuk menjelaskan nama metode yang mengembalikan kacang. Mereka juga dapat membuat nama bidang:

private final $CLASS_NAME$ $fieldName$; $END$
Agar tidak menekan Ctrl + Alt + L (alignment) setiap kali, aktifkan kotak centang Reformat sesuai dengan gaya dan lingkungan akan melakukan segalanya untuk Anda:

Repositori dan Entitas
Bahkan dalam entitas yang paling sederhana, kami memiliki banyak anotasi impor. Anda dapat membuat templat yang sangat efektif untuk mereka:
#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end #parse("File Header.java") import lombok.Getter; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Table; @Getter @Table @Entity public class ${NAME} { @Id private Long id; }

Pada 2019, jika Anda menggunakan Hibernate, maka tentunya Anda juga menggunakan Spring Date, dan jika demikian, maka Anda perlu membuat repositori. Mari percepat kreasi mereka:
#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end #parse("File Header.java") import org.springframework.data.jpa.repository.JpaRepository; public interface ${Entity_name}Repository extends JpaRepository<${Entity_name}, ${Key}>{ }

Akan lebih bagus jika, ketika mengatur kursor pada entitas (kelas ditandai @Table
dan @Table
) dan menekan Alt + Enter, "Ide" akan menyarankan segera membuat repositori, tetapi tidak begitu pintar :). Saat ini, pengguna tidak memiliki kemampuan untuk mengubah / menambah niat ( Editor> Niat ), tetapi Anda dapat menulis plugin sendiri:

Pengujian
Secara umum, semakin banyak templat yang dibuat dalam kode Anda, semakin besar keuntungan otomasi. Salah satu karya yang paling berulang adalah tes. Mereka yang menonton laporan Cyril Tolkachev "The Curse of the Spring Test" tahu bahwa ada cara mudah untuk membuat konteks naik hanya sekali untuk semua tes: membuat kelas abstrak dan mewarisi semua tes dari itu.
Menggambarkan sesuatu seperti
package com.example; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.transaction.annotation.Transactional; import org.springframework.test.context.junit.jupiter.SpringExtension; @Transactional @SpringBootTest @ExtendWith(SpringExtension.class) public abstract class BaseTest { }
kita dapat dengan mudah membuat semua tes yang baru dibuat mewarisi BaseTest
. Untuk melakukan ini, Anda perlu mengubah templat yang menciptakan pengujian default:

Dalam kode:
import com.example.BaseTest; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.*; #parse("File Header.java") class ${NAME} extends BaseTest { ${BODY} }
Selanjutnya kita jelaskan dependensinya. Saya tidak ingin melakukan panggilan setiap waktu
@Autowired private MyService service;
oleh karena itu, di bagian Editor> Templat langsung, tulis
@Autowired private $CLASS_NAME$ $fieldName$; $END$
Variabel $fieldName$
dijelaskan dengan cara yang persis sama seperti pada contoh membuat kacang, dengan satu pengecualian: untuk segera mengganti kursor setelah dibuat, centang Lewati jika didefinisikan :

Pada dasarnya, @Autowired
hanya diperlukan untuk bidang kelas, jadi pastikan untuk mengatur Deklarasi dalam menu tarik-turun yang berlaku:

Kami melihat:

Ngomong-ngomong, karena kita membuat tes untuk kelas tertentu, tidak ada yang mencegah kita memperkenalkan ketergantungan yang diperlukan segera ketika itu dibuat ( toCamelCase()
tidak berfungsi di sini, jadi Velocity digunakan):
import com.example.demo.BaseTest; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.*; #parse("File Header.java") class ${NAME} extends BaseTest { #set($bodyLength = $NAME.length() - 4) #set($field = $NAME.substring(0, 1).toLowerCase() + $NAME.substring(1, $bodyLength)) @Autowired private ${CLASS_NAME} ${field}; ${BODY} }

Pengalaman saya menunjukkan bahwa jika memungkinkan semua tes harus lintas sektoral. Sekalipun suatu layanan dicentang yang mengeluarkan entitas dan memotong bagian dari salah satu bidangnya, masih lebih baik untuk mendapatkan entitas secara jujur, yaitu. dari basis data. Oleh karena itu, untuk sebagian besar tes, saya mengambil data jujur ββdari salah satu lingkungan dan memuatnya sebelum menjalankan tes menggunakan @Sql
.
Pengambilan sampel data perlu dilakukan dengan tangan untuk setiap tugas, tetapi menghubungkannya dengan tes yang diinginkan dapat dengan mudah diotomatisasi. Sekali lagi, buka Editor> Live templates , bagian JUnit dan tulis:
@Sql("/sql/$CLASS_NAME$.sql") $END$

Sekarang, mengetik sql
, kita mendapatkan dropdown dengan 1 catatan, memilih yang kita dapatkan:
@Sql("/sql/MyEntityRepositoryTest.sql") class MyEntityRepositoryTest extends BaseTest { }
Harap perhatikan bahwa file yang kami maksudkan belum ada, jadi ketika Anda menjalankan tes dalam bentuk mentah, pasti akan macet. Namun, dimulai dengan versi 193.1617 , Ide tersebut menyoroti file yang tidak ada, dan yang paling penting, ia menyarankan untuk membuatnya!

Postfixes
Salah satu alat yang paling kuat adalah pembuatan / penambahan kode menggunakan ekspresi postfix (penghentian). Contoh paling sederhana:

Ada banyak penyelesaian, Anda dapat melihat semuanya di bagian Editor> General> Postfix Completion :

Ada juga ruang untuk berbagai jenis percobaan. Untuk saya sendiri, saya membuat penyelesaian untuk mengganti variabel menjadi ekspresi tes berbasis AssertJ :

Dalam hidup, ini terlihat seperti ini:

Tautan yang bermanfaat
Jika Anda ingin meningkatkan keterampilan Anda dengan Ide, pastikan untuk memeriksa dua laporan hebat:
Anton Arkhipov - kerja efektif dengan IntelliJ IDEA
Tagir Valeev - Refactoring atom di IntelliJ IDEA: kami membengkokkan IDE untuk diri kita sendiri
Itu saja, jarang terganggu dan ingat bahwa waktu adalah satu-satunya sumber daya kami yang benar-benar tidak dapat diperbarui.