Saat ini saya sedang memikirkan antarmuka ke kelas yang saya tulis. Kelas ini berisi gaya untuk karakter, misalnya apakah karakter itu tebal, miring, bergaris bawah, dll. Saya telah berdebat dengan diri saya sendiri selama dua hari apakah saya harus menggunakan getter / setter atau nama logis untuk metode yang mengubah nilai menjadi gaya-gaya ini. Walaupun saya cenderung lebih suka nama logis, itu berarti menulis kode yang tidak seefisien dan tidak logis. Biarkan saya memberi Anda sebuah contoh.
Aku punya kelas CharacterStyles
yang memiliki variabel anggota bold
, italic
, underline
(dan beberapa orang lain, tapi aku akan meninggalkan mereka untuk tetap sederhana). Cara termudah untuk mengizinkan bagian lain dari program untuk mengakses variabel-variabel ini, adalah dengan menulis metode pengambil / penyetel, sehingga Anda dapat melakukannya styles.setBold(true)
dan styles.setItalic(false)
.
Tapi saya tidak suka ini. Bukan hanya karena banyak orang mengatakan bahwa getter / seter menghancurkan enkapsulasi (apakah ini benar-benar seburuk itu?), Tetapi kebanyakan karena itu tidak masuk akal bagi saya. Saya berharap untuk mendesain karakter melalui satu metode, styles.format("bold", true)
atau sesuatu seperti itu, tetapi tidak melalui semua metode ini.
Namun ada satu masalah. Karena Anda tidak dapat mengakses variabel anggota objek dengan konten string dalam C ++, saya harus menulis wadah if-statement / switch besar untuk semua gaya, atau saya harus menyimpan gaya dalam array asosiatif ( peta).
Saya tidak tahu apa cara terbaik. Satu saat saya pikir saya harus menulis getter / setter, dan saat berikutnya saya condong ke arah lain. Pertanyaan saya adalah: apa yang akan Anda lakukan? Dan mengapa Anda melakukan itu?
sumber
bold
set ketrue
dan variabel lain tidak terdefinisi, metode pengambil untuk variabel lain harus mengembalikan nilai gaya induk (yang disimpan di properti lain), sedangkan pengambil untukbold
properti harus kembalitrue
. Ada beberapa hal lain seperti nama dan cara itu ditampilkan di antarmuka juga.Jawaban:
Ya, getter / setters memecah enkapsulasi - mereka pada dasarnya hanya lapisan tambahan antara secara langsung mengakses bidang yang mendasarinya. Anda mungkin juga langsung mengaksesnya.
Sekarang, jika Anda ingin metode yang lebih kompleks untuk mengakses bidang, itu sah, tetapi alih-alih mengekspos bidang, Anda perlu memikirkan metode apa yang harus ditawarkan oleh kelas. yaitu. alih-alih kelas Bank dengan nilai Uang yang terpapar menggunakan properti, Anda perlu memikirkan jenis akses yang harus ditawarkan oleh objek Bank (menambah uang, menarik, mendapatkan saldo) dan mengimplementasikannya. Properti pada variabel Uang hanya secara sintaksis berbeda dari mengekspos variabel Uang secara langsung.
DrDobbs memiliki artikel yang mengatakan lebih banyak.
Untuk masalah Anda, saya punya 2 metode setStyle dan clearStyle (atau apa pun) yang memerlukan enum dari gaya yang mungkin. Pernyataan peralihan di dalam metode ini kemudian akan menerapkan nilai yang relevan ke variabel kelas yang sesuai. Dengan cara ini, Anda dapat mengubah representasi internal dari gaya ke sesuatu yang lain jika nanti Anda memutuskan untuk menyimpannya sebagai string (untuk digunakan dalam HTML misalnya) - sesuatu yang akan mengharuskan semua pengguna kelas Anda untuk diubah juga jika Anda menggunakan dapatkan / atur properti.
Anda masih dapat mengaktifkan string jika Anda ingin mengambil nilai arbitrer, baik memiliki pernyataan if-then besar (jika ada beberapa), atau peta nilai string ke pointer metode menggunakan std :: mem_fun (atau std :: function ) jadi "bold" akan disimpan dalam kunci peta dengan nilainya menjadi sts :: mem_fun ke metode yang menetapkan variabel bold menjadi true (jika string sama dengan nama variabel anggota, maka Anda juga dapat menggunakan yang makro stringifying untuk mengurangi jumlah kode yang Anda butuhkan untuk menulis)
sumber
styles.setStyle(BOLD, true)
? Apakah itu benar?styles.getStyle(BOLD)
ketika Anda tidak hanya memiliki variabel anggota tipe boolean, tetapi juga tipe integer dan string (misalnyastyles.getStyle(FONTSIZE)
:). Karena Anda tidak dapat membebani jenis pengembalian, bagaimana Anda memprogram ini? Saya tahu Anda bisa menggunakan pointer kosong, tapi itu terdengar seperti cara yang sangat buruk bagi saya. Apakah Anda punya petunjuk tentang cara melakukan ini?Satu ide yang mungkin belum Anda pertimbangkan adalah Pola Dekorator . Daripada mengatur bendera di suatu objek dan kemudian menerapkan bendera itu untuk apa pun yang Anda tulis, Anda membungkus kelas yang menulis di Dekorator, yang pada gilirannya menerapkan gaya.
Kode panggilan tidak perlu tahu berapa banyak pembungkus yang Anda letakkan di sekitar teks Anda, Anda hanya memanggil metode pada objek luar dan memanggil tumpukan.
Untuk contoh pseudocode:
Dan seterusnya, untuk setiap gaya dekorasi. Dalam penggunaannya yang paling sederhana, Anda bisa mengatakannya
Dan kode yang memanggil metode ini tidak perlu mengetahui detail dari apa yang diterimanya. Selama itu SESUATU yang dapat menggambar teks melalui metode WriteString.
sumber
TextWriter
perlu berbicara dengan keduanyaBoldDecorator
danItalicDecorator
(dua arah) untuk menyelesaikan pekerjaan.Saya akan condong ke solusi kedua. Terlihat lebih elegan dan fleksibel. Meskipun sulit untuk membayangkan tipe lain selain tebal, miring, dan bergaris bawah (overline?), Akan sulit untuk menambahkan tipe baru menggunakan variabel anggota.
Saya menggunakan pendekatan ini di salah satu proyek terbaru saya. Saya memiliki kelas yang dapat memiliki beberapa atribut boolean. Jumlah dan nama atribut dapat berubah dalam waktu. Saya menyimpannya di kamus. Jika atribut tidak ada, saya menganggap nilainya "salah". Saya juga harus menyimpan daftar nama atribut yang tersedia, tapi itu cerita lain.
sumber
Saya pikir Anda terlalu memikirkan masalah ini.
styles.setBold(true)
dan baikstyles.setItalic(false)
-baik sajasumber