Saat mengubah kode Java menjadi kode Ceylon, kadang -kadang saya menemukan beberapa konstruktor kelas Java yang membingungkan verifikasi dan inisialisasi. Mari kita gunakan contoh kode sederhana namun buatan untuk menggambarkan apa yang ingin saya jelaskan.
Beberapa kode buruk
Pertimbangkan kelas Java berikut. (Man, jangan menulis kode seperti itu di rumah)
periode kelas publik {startDate tanggal akhir pribadi; enddate tanggal akhir pribadi; // returns null jika string yang diberikan // tidak mewakili tanggal yang valid tanggal private parsedate (date string) {...} periode publik (string start, string end) {startDate = parsedate (start); endDate = parsedate (akhir); } public boolean isValid () {return startDate! = null && endDate! = null; } tanggal publik getStartDate () {if (startDate == null) Lempar baru ilegalstateException (); kembalikan startDate; } Tanggal publik getEndDate () {if (endDate == null) Lempar baru ilegalstateException (); Return enddate; }}Hei, saya sudah memperingatkannya sebelumnya, itu buatan. Namun, sebenarnya tidak jarang menemukan sesuatu seperti ini dalam kode Java yang sebenarnya.
Masalahnya di sini adalah bahwa bahkan jika verifikasi parameter input (dalam metode Parsedate () tersembunyi) gagal, kami masih akan mendapatkan instance periode. Tetapi periode yang kita dapatkan bukanlah keadaan "valid". Sebenarnya, apa maksud saya?
Nah, jika suatu objek tidak dapat merespons secara bermakna terhadap operasi publik, saya akan mengatakan itu dalam keadaan non-valid. Dalam contoh ini, getStartDate () dan getEndDate () melempar pengecualian exception ilegalstate, yang merupakan kasus yang menurut saya tidak "bermakna".
Melihat contoh ini di sisi lain, saat merancang periode, kami gagal mengetik keamanan di sini. Pengecualian yang tidak dicentang mewakili "kekosongan" dalam sistem tipe. Oleh karena itu, desain jenis-aman periode yang lebih baik akan menjadi tidak digunakannya pengecualian yang tidak dicentang-dalam contoh ini, IlegalStateException tidak dilemparkan.
;
Kita dapat dengan mudah mengubah kelas periode di atas menjadi kelas bentuk ceylon:
Periode kelas yang dibagikan (string start, string end) {// returns null jika string yang diberikan // tidak mewakili tanggal tanggal yang valid? parsedate (date string) => ...; nilai maybestartdate = parsedate (mulai); Nilai mungkin endDate = parsedate (akhir); boolean valid => maybestArtDate ada && mungkin akan ada; startDate tanggal dibagikan {assert (ada maybestartDate); mengembalikan maybestartdate; } Tanggal dibagikan endDate {assert (ada maybestArtDate); mengembalikan maybestartdate; } Tanggal dibagikan endDate {assert (ada mungkin padaDDate); kembalikan mungkin endDate; }}Tentu saja, kode ini juga akan mengalami masalah yang sama dengan kode Java asli. Dua simbol menegaskan berteriak kepada kami, ada masalah dalam jenis keamanan kode.
Membuat kode java lebih baik
Bagaimana cara meningkatkan kode ini di Java? Nah, inilah contoh pengecualian yang dikritik Java yang sangat masuk akal untuk dipecahkan! Kami dapat sedikit memodifikasi periode untuk melempar pengecualian yang diperiksa dari konstruktornya:
periode kelas publik {startDate tanggal akhir pribadi; enddate tanggal akhir pribadi; // melempar jika string yang diberikan // tidak mewakili tanggal yang valid tanggal privat parsedate (date string) melempar dateFormateException {...} periode publik (string start, string end) melempar DateFormateException {startDate = parsedate (start); endDate = parsedate (akhir); } tanggal publik getStartDate () {return startDate; } tanggal publik getEndDate () {return endDate; }}Sekarang, dengan solusi ini, kami tidak akan mendapatkan periode dalam keadaan non-valid. Kode yang membuat instansi periode akan ditangani oleh kompiler untuk menangani input yang tidak valid, yang akan menangkap pengecualian DateFormatException.
coba {periode p = periode baru (start, end); ...} catch (DateFormateException dfe) {...}Ini adalah penggunaan pengecualian yang bagus, sempurna, dan benar, dan sayangnya saya jarang melihat kode Java menggunakan pengecualian yang diperiksa seperti yang di atas.
Membuat kode ceylon lebih baik
Jadi bagaimana dengan Ceylon? Ceylon tidak memiliki pengecualian yang diperiksa, jadi kita perlu menemukan solusi yang berbeda. Biasanya, dalam situasi di mana Java memanggil fungsi dan melempar pengecualian yang diperiksa, Ceylon memanggil fungsi dan mengembalikan jenis serikat. Karena, inisialisasi kelas tidak mengembalikan jenis apa pun kecuali kelas itu sendiri, kita perlu mengekstrak beberapa logika inisialisasi/verifikasi campuran untuk menjadikannya fungsi pabrik.
// returns dateFormaterror jika string yang diberikan // tidak mewakili tanggal yang valid | dateFormaterRor parsedate (date string) => ...; periode bersama | dateFormaterror parseperiod (string start, string end) {value startDate = parsedate (start); if (adalah dateFormaterror startDate) {return startDate; } value endDate = parsedate (end); if (adalah dateFormaterror endDate) {return endDate; } periode pengembalian (startDate, endDate);} periode kelas bersama (startDate, endDate) {startDate tanggal bersama; Tanggal Bersama EndDate;}Menurut sistem tipe, penelepon berkewajiban untuk menangani DateFormaterror:
nilai p = parseperiod (start, end); if (adalah dateFormaterror p) {...} else {...}Atau, jika kita tidak peduli dengan masalah aktual dengan format tanggal yang diberikan (yang dimungkinkan, dengan asumsi bahwa kode inisialisasi yang kita kerjakan tidak ada informasi itu), kita dapat menggunakan null alih -alih DateFormaterror:
// mengembalikan nol jika string yang diberikan // tidak mewakili tanggal yang valid? parsedate (date string) => ...; periode bersama? parseperiod (string start, string end) => if (ada startDate = parsedate (start), ada endDate = parsedate (end)) kemudian periode (startDate, endDate) lain null; periode kelas bersama (startDate, akhir) {startDate tanggal bersama; Tanggal Bersama EndDate;}Pendekatan untuk menggunakan fungsi pabrik sangat baik untuk dikatakan, karena umumnya memiliki isolasi yang lebih baik antara logika validasi dan inisialisasi objek. Ini sangat berguna di Ceylon, di mana kompiler menambahkan beberapa pembatasan yang sangat ketat pada logika inisialisasi objek untuk memastikan bahwa semua area objek hanya ditugaskan sekali.
Di atas adalah semua konten artikel ini. Saya berharap ini akan membantu untuk pembelajaran semua orang dan saya harap semua orang akan lebih mendukung wulin.com.