Terkadang Anda perlu menulis konstruktor yang bisa gagal. Sebagai contoh, katakan saya ingin instantiate objek dengan path file, sesuatu seperti
obj = new Object("/home/user/foo_file")
Selama jalur menunjuk ke file yang sesuai, semuanya baik-baik saja. Tetapi jika string bukan jalur yang valid, hal-hal yang harus dipatahkan. Tapi bagaimana caranya?
Anda bisa:
- lempar pengecualian
- return null object (jika bahasa pemrograman Anda memungkinkan konstruktor untuk mengembalikan nilai)
- mengembalikan objek yang valid tetapi dengan bendera yang menunjukkan bahwa jalurnya tidak diset dengan benar (ugh)
- orang lain?
Saya berasumsi bahwa "praktik terbaik" dari berbagai bahasa pemrograman akan menerapkan ini secara berbeda. Misalnya saya pikir ObjC lebih suka (2). Tetapi (2) tidak mungkin diimplementasikan dalam C ++ di mana konstruktor harus membatalkan sebagai tipe kembali. Dalam hal ini saya menganggap bahwa (1) digunakan.
Dalam bahasa pemrograman pilihan Anda, dapatkah Anda menunjukkan bagaimana Anda akan menangani masalah ini dan menjelaskan mengapa?
sumber
void
- mereka mengembalikan objek.new
panggilanoperator new
untuk mengalokasikan memori, maka konstruktor untuk mengisinya. Konstruktor tidak mengembalikan apa pun, dannew
mengembalikan pointer yang didapatnyaoperator new
. Apakah "tidak mengembalikan apa-apa" menyiratkan "pengembalianvoid
" adalah untuk diperebutkan.Jawaban:
Tidak pernah baik untuk mengandalkan konstruktor untuk melakukan pekerjaan kotor. Selain itu, juga tidak jelas bagi programmer lain apakah pekerjaan akan dilakukan dalam konstruktor kecuali ada dokumentasi eksplisit yang menyatakan demikian (dan bahwa pengguna kelas telah membacanya atau diberi tahu demikian).
Misalnya (dalam C #):
Apa yang terjadi jika pengguna tidak ingin langsung memuat file? Bagaimana jika mereka ingin melakukan caching file berdasarkan permintaan? Mereka tidak bisa. Anda mungkin berpikir untuk meletakkan
bool loadFile
argumen di konstruktor, tetapi ini membuat ini berantakan karena Anda sekarang masih memerlukanLoad()
metode untuk memuat file.Dengan skenario saat ini, akan lebih fleksibel dan lebih jelas bagi pengguna kelas untuk melakukan ini:
Atau sebagai alternatif (untuk sesuatu seperti sumber daya):
sumber
Di Jawa, Anda bisa menggunakan pengecualian atau menggunakan pola pabrik, yang memungkinkan Anda mengembalikan nol.
Di Scala, Anda bisa mengembalikan Opsi [Foo] dari metode pabrik. Itu akan bekerja di Jawa juga, tetapi akan lebih rumit.
sumber
Lempar pengecualian.
Null perlu diperiksa jika Anda dapat mengembalikannya (dan tidak akan diperiksa)
Inilah yang mengecualikan pengecualian. Anda tahu itu bisa gagal. Penelepon harus menangani ini.
sumber
Dalam C ++ , konstruktor digunakan untuk membuat / menginisialisasi anggota kelas.
Tidak ada jawaban yang tepat untuk pertanyaan ini. Tapi yang saya amati sejauh ini, adalah bahwa sebagian besar waktu adalah klien (atau siapa pun yang akan menggunakan API Anda) yang memilih bagaimana Anda harus menangani hal ini.
Kadang-kadang mereka mungkin meminta Anda untuk mengalokasikan semua sumber daya yang mungkin dibutuhkan objek pada konstruktor dan melemparkan pengecualian jika ada yang gagal (membatalkan pembuatan objek), atau tidak melakukan itu pada konstruktor, dan memastikan bahwa kreasi akan selalu berhasil , meninggalkan tugas-tugas ini untuk beberapa fungsi anggota untuk dilakukan.
Jika terserah Anda untuk memilih perilaku, pengecualian adalah cara C ++ default untuk menangani kesalahan dan Anda harus menggunakannya saat Anda bisa.
sumber
Anda juga bisa instantiate objek tanpa parameter, atau hanya dengan parameter yang pasti tidak pernah gagal, dan kemudian Anda menggunakan fungsi inisialisasi atau metode dari mana Anda dapat dengan aman melemparkan pengecualian atau melakukan apa pun yang Anda inginkan.
sumber
Saya lebih suka untuk tidak menginisialisasi kelas atau daftar apa pun di konstruktor. Inisialisasi kelas atau daftar kapan pun Anda butuhkan. Misalnya.
Jangan lakukan ini
Alih-alih menginisialisasi ketika diminta misalnya.
sumber