Sistem
Berikut adalah ciri-ciri sistem yang diingini secara amnya:- Kerumitan minimum. Projek yang terlalu rumit mesti dielakkan. Perkara yang paling penting ialah kesederhanaan dan kejelasan (lebih mudah = lebih baik).
- Kemudahan penyelenggaraan. Apabila membuat aplikasi, anda mesti ingat bahawa ia perlu dikekalkan (walaupun anda secara peribadi tidak akan bertanggungjawab untuk mengekalkannya). Ini bermakna kod mestilah jelas dan jelas.
- Gandingan longgar. Ini bermakna kami meminimumkan bilangan pergantungan antara bahagian program yang berlainan (memaksimumkan pematuhan kami terhadap prinsip OOP).
- Kebolehgunaan semula. Kami mereka bentuk sistem kami dengan keupayaan untuk menggunakan semula komponen dalam aplikasi lain.
- Mudah alih. Ia sepatutnya mudah untuk menyesuaikan sistem kepada persekitaran lain.
- Gaya seragam. Kami mereka bentuk sistem kami menggunakan gaya seragam dalam pelbagai komponennya.
- Kebolehlanjutan (skala). Kita boleh meningkatkan sistem tanpa melanggar struktur asasnya (menambah atau menukar komponen tidak boleh menjejaskan semua yang lain).
Peringkat mereka bentuk sistem
- Sistem perisian. Reka bentuk aplikasi secara keseluruhan.
- Pembahagian kepada subsistem/pakej. Tentukan bahagian yang berbeza secara logik dan tentukan peraturan untuk interaksi antara mereka.
- Pembahagian subsistem ke dalam kelas. Bahagikan bahagian sistem kepada kelas dan antara muka tertentu, dan tentukan interaksi antara mereka.
- Pembahagian kelas kepada kaedah. Cipta takrifan lengkap kaedah yang diperlukan untuk kelas, berdasarkan tanggungjawab yang diberikan.
- Reka bentuk kaedah. Buat takrifan terperinci tentang kefungsian kaedah individu.
Prinsip dan konsep umum reka bentuk sistem
Inisialisasi malas. Dalam simpulan bahasa pengaturcaraan ini, aplikasi tidak membuang masa mencipta objek sehingga ia benar-benar digunakan. Ini mempercepatkan proses permulaan dan mengurangkan beban pada pemungut sampah. Yang berkata, anda tidak sepatutnya mengambil ini terlalu jauh, kerana itu boleh melanggar prinsip modulariti. Mungkin ia patut mengalihkan semua contoh pembinaan ke bahagian tertentu, contohnya, kaedah utama atau ke kelas kilang . Satu ciri kod yang baik ialah ketiadaan kod boilerplate yang berulang. Sebagai peraturan, kod tersebut diletakkan dalam kelas berasingan supaya ia boleh dipanggil apabila diperlukan.AOP
Saya juga ingin ambil perhatian pengaturcaraan berorientasikan aspek. Paradigma pengaturcaraan ini adalah mengenai memperkenalkan logik telus. Iaitu, kod berulang dimasukkan ke dalam kelas (aspek) dan dipanggil apabila syarat tertentu dipenuhi. Contohnya, apabila memanggil kaedah dengan nama tertentu atau mengakses pembolehubah jenis tertentu. Kadangkala aspek boleh mengelirukan, kerana tidak jelas dari mana kod itu dipanggil, tetapi ini masih merupakan fungsi yang sangat berguna. Terutama apabila caching atau log. Kami menambah fungsi ini tanpa menambah logik tambahan kepada kelas biasa. Empat peraturan Kent Beck untuk seni bina mudah:- Ekspresi — Niat kelas harus dinyatakan dengan jelas. Ini dicapai melalui penamaan yang betul, saiz kecil dan pematuhan kepada prinsip tanggungjawab tunggal (yang akan kami pertimbangkan dengan lebih terperinci di bawah).
- Bilangan kelas dan kaedah minimum — Dalam keinginan anda untuk menjadikan kelas sekecil mungkin dan tertumpu sempit, anda boleh pergi terlalu jauh (mengakibatkan pembedahan senapang patah anti-pola). Prinsip ini memerlukan untuk memastikan sistem padat dan tidak pergi terlalu jauh, mewujudkan kelas yang berasingan untuk setiap tindakan yang mungkin.
- Tiada pertindihan — Kod pendua, yang menimbulkan kekeliruan dan merupakan petunjuk reka bentuk sistem suboptimum, diekstrak dan dipindahkan ke lokasi yang berasingan.
- Menjalankan semua ujian — Sistem yang lulus semua ujian boleh diurus. Sebarang perubahan boleh menyebabkan ujian gagal, mendedahkan kepada kami bahawa perubahan kami dalam logik dalaman kaedah juga mengubah tingkah laku sistem dengan cara yang tidak dijangka.
PADAT
Apabila mereka bentuk sistem, prinsip SOLID yang terkenal patut dipertimbangkan:S (tanggungjawab tunggal), O (terbuka-tertutup), L (penggantian Liskov), I (pengasingan antara muka), D (penyongsangan kebergantungan).
Kami tidak akan memikirkan setiap prinsip individu. Itu akan menjadi sedikit di luar skop artikel ini, tetapi anda boleh membaca lebih lanjut di sini .Antara muka
Mungkin salah satu langkah paling penting dalam mencipta kelas yang direka dengan baik ialah mencipta antara muka yang direka bentuk dengan baik yang mewakili abstraksi yang baik, menyembunyikan butiran pelaksanaan kelas dan pada masa yang sama mempersembahkan sekumpulan kaedah yang jelas konsisten antara satu sama lain. Mari kita lihat dengan lebih dekat salah satu prinsip SOLID — pengasingan antara muka: pelanggan (kelas) tidak seharusnya melaksanakan kaedah yang tidak perlu yang mereka tidak akan gunakan. Dalam erti kata lain, jika kita bercakap tentang mencipta antara muka dengan bilangan paling sedikit kaedah yang bertujuan untuk melaksanakan satu-satunya tugas antara muka (yang saya fikir sangat serupa dengan prinsip tanggungjawab tunggal), lebih baik untuk mencipta beberapa yang lebih kecil sebaliknya daripada satu antara muka kembung. Nasib baik, kelas boleh melaksanakan lebih daripada satu antara muka. Ingat untuk menamakan antara muka anda dengan betul: nama itu harus mencerminkan tugas yang diberikan setepat mungkin. Dan, sudah tentu, semakin pendek, semakin kurang kekeliruan yang akan ditimbulkan. Komen dokumentasi biasanya ditulis pada peringkat antara muka. Komen ini memberikan butiran tentang perkara yang perlu dilakukan oleh setiap kaedah, hujah yang diperlukan dan perkara yang akan dikembalikan.Kelas
- pemalar statik awam;
- pemalar statik persendirian;
- pembolehubah contoh peribadi.
Saiz kelas
Sekarang saya ingin bercakap tentang saiz kelas. Mari kita ingat salah satu prinsip SOLID — prinsip tanggungjawab tunggal. Ia menyatakan bahawa setiap objek hanya mempunyai satu tujuan (tanggungjawab), dan logik semua kaedahnya bertujuan untuk mencapainya. Ini memberitahu kita untuk mengelakkan kelas yang besar dan kembung (yang sebenarnya adalah anti-corak objek Tuhan), dan jika kita mempunyai banyak kaedah dengan pelbagai jenis logik yang dijejalkan ke dalam kelas, kita perlu memikirkan untuk memecahkannya menjadi satu beberapa bahagian logik (kelas). Ini, seterusnya, akan meningkatkan kebolehbacaan kod, kerana ia tidak akan mengambil masa yang lama untuk memahami tujuan setiap kaedah jika kita mengetahui tujuan anggaran mana-mana kelas tertentu. Juga, perhatikan nama kelas, yang sepatutnya mencerminkan logik yang terkandung di dalamnya. Sebagai contoh, jika kita mempunyai kelas dengan 20+ perkataan dalam namanya, kita perlu memikirkan tentang pemfaktoran semula. Mana-mana kelas yang menghargai diri sendiri tidak sepatutnya mempunyai pembolehubah dalaman sebanyak itu. Malah, setiap kaedah berfungsi dengan satu atau beberapa daripadanya, menyebabkan banyak kesepaduan dalam kelas (yang betul-betul seperti yang sepatutnya, kerana kelas itu harus menjadi keseluruhan yang bersatu). Akibatnya, meningkatkan perpaduan kelas membawa kepada pengurangan saiz kelas, dan, sudah tentu, bilangan kelas meningkat. Ini menjengkelkan bagi sesetengah orang, kerana anda perlu meneliti fail kelas dengan lebih lanjut untuk melihat cara tugas besar tertentu berfungsi. Di samping itu, setiap kelas adalah modul kecil yang harus mempunyai kaitan minimum dengan yang lain. Pengasingan ini mengurangkan bilangan perubahan yang perlu kita buat apabila menambah logik tambahan pada kelas. setiap kaedah berfungsi dengan satu atau beberapa daripadanya, menyebabkan banyak kesepaduan dalam kelas (yang betul-betul seperti yang sepatutnya, kerana kelas itu harus menjadi satu keseluruhan yang bersatu). Akibatnya, meningkatkan perpaduan kelas membawa kepada pengurangan saiz kelas, dan, sudah tentu, bilangan kelas meningkat. Ini menjengkelkan bagi sesetengah orang, kerana anda perlu meneliti fail kelas dengan lebih lanjut untuk melihat cara tugas besar tertentu berfungsi. Di samping itu, setiap kelas adalah modul kecil yang harus mempunyai kaitan minimum dengan yang lain. Pengasingan ini mengurangkan bilangan perubahan yang perlu kita buat apabila menambah logik tambahan pada kelas. setiap kaedah berfungsi dengan satu atau beberapa daripadanya, menyebabkan banyak kesepaduan dalam kelas (yang betul-betul seperti yang sepatutnya, kerana kelas itu harus menjadi satu keseluruhan yang bersatu). Akibatnya, meningkatkan perpaduan kelas membawa kepada pengurangan saiz kelas, dan, sudah tentu, bilangan kelas meningkat. Ini menjengkelkan bagi sesetengah orang, kerana anda perlu meneliti fail kelas dengan lebih lanjut untuk melihat cara tugas besar tertentu berfungsi. Di samping itu, setiap kelas adalah modul kecil yang harus mempunyai kaitan minimum dengan yang lain. Pengasingan ini mengurangkan bilangan perubahan yang perlu kita buat apabila menambah logik tambahan pada kelas. perpaduan membawa kepada pengurangan dalam saiz kelas, dan, sudah tentu, bilangan kelas meningkat. Ini menjengkelkan bagi sesetengah orang, kerana anda perlu meneliti fail kelas dengan lebih lanjut untuk melihat cara tugas besar tertentu berfungsi. Di samping itu, setiap kelas adalah modul kecil yang harus mempunyai kaitan minimum dengan yang lain. Pengasingan ini mengurangkan bilangan perubahan yang perlu kita buat apabila menambah logik tambahan pada kelas. perpaduan membawa kepada pengurangan dalam saiz kelas, dan, sudah tentu, bilangan kelas meningkat. Ini menjengkelkan bagi sesetengah orang, kerana anda perlu meneliti fail kelas dengan lebih lanjut untuk melihat cara tugas besar tertentu berfungsi. Di samping itu, setiap kelas adalah modul kecil yang harus mempunyai kaitan minimum dengan yang lain. Pengasingan ini mengurangkan bilangan perubahan yang perlu kita buat apabila menambah logik tambahan pada kelas.Objek
Enkapsulasi
Di sini kita akan bercakap tentang prinsip OOP: enkapsulasi. Menyembunyikan pelaksanaan tidak sama dengan mencipta kaedah untuk melindungi pembolehubah (mengehadkan akses melalui kaedah individu, pengambil dan penetap, yang tidak baik, kerana keseluruhan titik enkapsulasi hilang). Menyembunyikan akses bertujuan untuk membentuk abstraksi, iaitu, kelas menyediakan kaedah konkrit kongsi yang kami gunakan untuk bekerja dengan data kami. Dan pengguna tidak perlu mengetahui dengan tepat cara kami bekerja dengan data ini — ia berfungsi dan itu sudah memadai.Hukum Demeter
Kita juga boleh mempertimbangkan Hukum Demeter: ia adalah satu set kecil peraturan yang membantu dalam menguruskan kerumitan pada peringkat kelas dan kaedah. Katakan kita mempunyai objek Kereta , dan ia mempunyai kaedah bergerak(Objek arg1, Objek arg2) . Menurut Undang-undang Demeter, kaedah ini terhad kepada panggilan:- kaedah objek Kereta itu sendiri (dengan kata lain, objek "ini");
- kaedah objek yang dicipta dalam kaedah bergerak ;
- kaedah objek diluluskan sebagai hujah ( arg1 , arg2 );
- kaedah objek dalaman Kereta (sekali lagi, "ini").
Struktur data
Struktur data ialah himpunan elemen yang berkaitan. Apabila mempertimbangkan objek sebagai struktur data, terdapat satu set elemen data yang kaedah beroperasi. Kewujudan kaedah ini diandaikan secara tersirat. Iaitu, struktur data ialah objek yang tujuannya adalah untuk menyimpan dan bekerja dengan (memproses) data yang disimpan. Perbezaan utamanya daripada objek biasa ialah objek biasa ialah koleksi kaedah yang beroperasi pada elemen data yang diandaikan wujud secara tersirat. Adakah anda faham? Aspek utama objek biasa ialah kaedah. Pembolehubah dalaman memudahkan operasi yang betul. Tetapi dalam struktur data, kaedah ada untuk menyokong kerja anda dengan elemen data yang disimpan, yang paling penting di sini. Satu jenis struktur data ialah objek pemindahan data (DTO). Ini ialah kelas dengan pembolehubah awam dan tiada kaedah (atau hanya kaedah untuk membaca/menulis) yang digunakan untuk memindahkan data apabila bekerja dengan pangkalan data, menghuraikan mesej daripada soket, dsb. Data biasanya tidak disimpan dalam objek sedemikian untuk tempoh yang panjang. Ia hampir serta-merta ditukar kepada jenis entiti yang aplikasi kami berfungsi. Entiti, sebaliknya, juga merupakan struktur data, tetapi tujuannya adalah untuk mengambil bahagian dalam logik perniagaan di pelbagai peringkat aplikasi. Tujuan DTO adalah untuk mengangkut data ke/dari aplikasi. Contoh DTO: juga merupakan struktur data, tetapi tujuannya adalah untuk mengambil bahagian dalam logik perniagaan di pelbagai peringkat aplikasi. Tujuan DTO adalah untuk mengangkut data ke/dari aplikasi. Contoh DTO: juga merupakan struktur data, tetapi tujuannya adalah untuk mengambil bahagian dalam logik perniagaan di pelbagai peringkat aplikasi. Tujuan DTO adalah untuk mengangkut data ke/dari aplikasi. Contoh DTO:
@Setter
@Getter
@NoArgsConstructor
public class UserDto {
private long id;
private String firstName;
private String lastName;
private String email;
private String password;
}
Segala-galanya kelihatan cukup jelas, tetapi di sini kita belajar tentang kewujudan hibrid. Hibrid ialah objek yang mempunyai kaedah untuk mengendalikan logik penting, menyimpan elemen dalaman, dan juga termasuk kaedah pengakses (get/set). Objek sedemikian tidak kemas dan menyukarkan untuk menambah kaedah baharu. Anda harus mengelakkannya, kerana tidak jelas untuk apa ia - menyimpan elemen atau melaksanakan logik?
Prinsip mencipta pembolehubah
Mari kita renungkan sedikit tentang pembolehubah. Lebih khusus lagi, mari kita fikirkan tentang prinsip yang digunakan semasa menciptanya:- Sebaik-baiknya, anda harus mengisytiharkan dan memulakan pembolehubah sejurus sebelum menggunakannya (jangan buat satu dan lupakannya).
- Apabila boleh, isytiharkan pembolehubah sebagai muktamad untuk mengelakkan nilainya berubah selepas permulaan.
- Jangan lupa tentang pembolehubah balas, yang biasanya kita gunakan dalam beberapa jenis gelung . Iaitu, jangan lupa untuk memusnahkannya. Jika tidak, semua logik kita mungkin pecah.
- Anda harus cuba memulakan pembolehubah dalam pembina.
- Jika terdapat pilihan antara menggunakan objek dengan rujukan atau tanpa ( new SomeObject() ), pilih tanpa, kerana selepas objek digunakan ia akan dipadamkan semasa kitaran pengumpulan sampah seterusnya dan sumbernya tidak akan dibazirkan.
- Pastikan jangka hayat pembolehubah (jarak antara penciptaan pembolehubah dan kali terakhir ia dirujuk) sesingkat mungkin.
- Mulakan pembolehubah yang digunakan dalam gelung sejurus sebelum gelung, bukan pada permulaan kaedah yang mengandungi gelung.
- Sentiasa mulakan dengan skop yang paling terhad dan kembangkan hanya apabila perlu (anda harus cuba membuat pembolehubah sebagai setempat yang mungkin).
- Gunakan setiap pembolehubah untuk satu tujuan sahaja.
- Elakkan pembolehubah dengan tujuan tersembunyi, cth pembahagian pembolehubah antara dua tugasan — ini bermakna jenisnya tidak sesuai untuk menyelesaikan salah satu daripadanya.
Kaedah
daripada filem "Star Wars: Episode III - Revenge of the Sith" (2005)
-
Peraturan #1 — Kekompakan. Sebaik-baiknya, kaedah tidak boleh melebihi 20 baris. Ini bermakna jika kaedah awam "membengkak" dengan ketara, anda perlu memikirkan tentang memecahkan logik dan mengalihkannya ke kaedah peribadi yang berasingan.
-
Peraturan #2 — if , else , while dan pernyataan lain tidak sepatutnya mempunyai blok bersarang banyak: banyak bersarang mengurangkan kebolehbacaan kod dengan ketara. Sebaik-baiknya, anda seharusnya tidak mempunyai lebih daripada dua blok {} bersarang .
Dan ia juga wajar untuk mengekalkan kod dalam blok ini padat dan ringkas.
-
Peraturan #3 — Kaedah hendaklah melakukan satu operasi sahaja. Iaitu, jika kaedah melakukan semua jenis logik yang kompleks, kita memecahkannya kepada subkaedah. Akibatnya, kaedah itu sendiri akan menjadi fasad yang tujuannya adalah untuk memanggil semua operasi lain dalam susunan yang betul.
Tetapi bagaimana jika operasi kelihatan terlalu mudah untuk dimasukkan ke dalam kaedah yang berasingan? Benar, kadang-kadang ia mungkin terasa seperti menembak meriam ke arah burung pipit, tetapi kaedah kecil memberikan beberapa kelebihan:
- Pemahaman kod yang lebih baik;
- Kaedah cenderung menjadi lebih kompleks apabila pembangunan berkembang. Jika kaedah adalah mudah untuk dimulakan, maka ia akan menjadi lebih mudah untuk merumitkan fungsinya;
- Butiran pelaksanaan disembunyikan;
- Penggunaan semula kod yang lebih mudah;
- Kod yang lebih dipercayai.
-
Peraturan langkah turun — Kod harus dibaca dari atas ke bawah: semakin rendah anda membaca, semakin mendalam anda menyelidiki logiknya. Dan sebaliknya, semakin tinggi anda pergi, semakin abstrak kaedahnya. Sebagai contoh, pernyataan suis agak tidak padat dan tidak diingini, tetapi jika anda tidak dapat mengelak daripada menggunakan suis, anda harus cuba mengalihkannya serendah mungkin, ke kaedah peringkat terendah.
-
Argumen kaedah — Apakah nombor ideal? Sebaik-baiknya, tiada langsung :) Tetapi adakah itu benar-benar berlaku? Yang berkata, anda harus cuba mempunyai sedikit hujah yang mungkin, kerana semakin sedikit, semakin mudah untuk menggunakan kaedah dan semakin mudah untuk mengujinya. Apabila ragu-ragu, cuba jangkakan semua senario untuk menggunakan kaedah dengan sejumlah besar parameter input.
-
Di samping itu, adalah baik untuk memisahkan kaedah yang mempunyai bendera boolean sebagai parameter input, kerana ini dengan sendirinya membayangkan bahawa kaedah melaksanakan lebih daripada satu operasi (jika benar, maka lakukan satu perkara; jika palsu, lakukan yang lain). Seperti yang saya tulis di atas, ini tidak baik dan harus dielakkan jika boleh.
-
Jika kaedah mempunyai bilangan parameter input yang banyak (yang melampau ialah 7, tetapi anda harus benar-benar mula berfikir selepas 2-3), beberapa hujah harus dikumpulkan ke dalam objek yang berasingan.
-
Jika terdapat beberapa kaedah yang serupa (lebih beban), maka parameter yang serupa mesti diluluskan dalam susunan yang sama: ini meningkatkan kebolehbacaan dan kebolehgunaan.
-
Apabila anda menghantar parameter kepada kaedah, anda mesti memastikan bahawa semuanya digunakan, jika tidak, mengapa anda memerlukannya? Potong mana-mana parameter yang tidak digunakan daripada antara muka dan selesaikan dengannya.
- cuba/tangkap tidak kelihatan sangat bagus sifatnya, jadi adalah idea yang baik untuk memindahkannya ke kaedah perantaraan yang berasingan (kaedah untuk mengendalikan pengecualian):
public void exceptionHandling(SomeObject obj) { try { someMethod(obj); } catch (IOException e) { e.printStackTrace(); } }
GO TO FULL VERSION