Dokumentasi dalam OOP harus menghindari menentukan apakah "pengambil" melakukan perhitungan atau tidak?

39

Program CS sekolah saya menghindari penyebutan pemrograman berorientasi objek, jadi saya telah melakukan beberapa bacaan sendiri untuk menambahnya - khususnya, Konstruksi Perangkat Lunak Berorientasi Objek oleh Bertrand Meyer.

Meyer berulang kali menekankan bahwa kelas harus menyembunyikan sebanyak mungkin informasi tentang implementasi mereka, yang masuk akal. Secara khusus, ia berargumen berulang kali bahwa atribut (yaitu, statis, sifat-sifat non-komputer kelas) dan rutinitas (sifat kelas yang sesuai dengan panggilan fungsi / prosedur) harus dapat dibedakan satu sama lain.

Sebagai contoh, jika sebuah kelas Personmemiliki atribut age, ia menegaskan bahwa seharusnya tidak mungkin untuk mengatakan, dari notasi, apakah Person.ageberkorespondensi secara internal dengan sesuatu seperti return current_year - self.birth_dateatau hanya return self.age, di mana self.agetelah didefinisikan sebagai atribut konstan. Ini masuk akal bagi saya. Namun, ia kemudian mengklaim sebagai berikut:

Dokumentasi klien standar untuk suatu kelas, yang dikenal sebagai bentuk pendek dari kelas, akan dirancang agar tidak mengungkapkan apakah fitur yang diberikan adalah atribut atau fungsi (dalam kasus yang bisa jadi salah satu).

yaitu, ia mengklaim bahwa bahkan dokumentasi untuk kelas harus menghindari menentukan apakah seorang "pengambil" melakukan perhitungan atau tidak.

Ini, saya tidak mengikuti. Bukankah dokumentasi satu-satunya tempat di mana penting untuk memberi tahu pengguna tentang perbedaan ini? Jika saya mendesain database yang penuh dengan Personobjek, bukankah penting untuk mengetahui apakah Person.agepanggilan itu mahal atau tidak , jadi saya dapat memutuskan apakah akan menerapkan semacam cache atau tidak untuknya? Apakah saya salah paham apa yang dia katakan, atau dia hanya contoh ekstrem dari filosofi desain OOP?

Patrick Collins
sumber
1
Pertanyaan menarik. Saya bertanya tentang sesuatu yang sangat mirip baru-baru ini: Bagaimana saya mendesain antarmuka sedemikian rupa sehingga jelas sifat mana yang dapat mengubah nilainya, dan mana yang akan tetap konstan? . Dan saya mendapat jawaban yang baik dengan menunjuk pada dokumentasi, yaitu apa yang justru dipertanyakan oleh Bertrand Meyer.
stakx
Saya belum membaca buku itu. Apakah Meyer memberikan contoh gaya dokumentasi yang ia rekomendasikan? Saya merasa sulit membayangkan apa yang Anda gambarkan bekerja untuk bahasa apa pun .
user16764
1
@ Patrickrickoll Saya sarankan Anda membaca 'eksekusi di kerajaan kata benda' dan dapatkan di belakang konsep kata kerja dan kata benda di sini. Kedua OOP BUKAN tentang getter dan setter, saya sarankan Alan Kay (penemu OOP): pemrograman dan skala
AndreasScheinert
@AndreasScheinert - Anda maksudkan ini ? Saya terkekeh pada "semua karena kekurangan paku tapal kuda," tetapi tampaknya menjadi kata-kata kasar tentang kejahatan pemrograman berorientasi objek.
Patrick Collins
1
@ Patrickolls ya ini: steve-yegge.blogspot.com/2006/03/… ! Ini memberikan beberapa poin untuk direnungkan, yang lain adalah: Anda harus mengubah objek Anda menjadi struktur data dengan (ab) menggunakan setter.
AndreasScheinert

Jawaban:

58

Saya tidak berpikir poin Meyer adalah bahwa Anda tidak harus memberi tahu pengguna ketika Anda memiliki operasi yang mahal. Jika fungsi Anda akan mencapai basis data, atau membuat permintaan ke server web, dan menghabiskan beberapa jam menghitung, kode lain akan perlu tahu itu.

Tetapi pembuat kode yang menggunakan kelas Anda tidak perlu tahu apakah Anda telah menerapkan:

return currentAge;

atau:

return getCurrentYear() - yearBorn;

Karakteristik kinerja antara kedua pendekatan itu sangat minimal sehingga tidak masalah. Coder yang menggunakan kelas Anda benar-benar tidak peduli yang Anda miliki. Itu maksud meyer.

Tapi itu tidak selalu terjadi, misalnya, misalkan Anda memiliki metode ukuran pada wadah. Itu bisa diterapkan:

return size;

atau

return end_pointer - start_pointer;

atau bisa juga:

count = 0
for(Node * node = firstNode; node; node = node->next)
{
    count++
}
return count

Perbedaan antara dua yang pertama seharusnya tidak menjadi masalah. Tetapi yang terakhir bisa memiliki konsekuensi kinerja yang serius. Itu sebabnya STL, misalnya, mengatakan bahwa .size()adalah O(1). Itu tidak mendokumentasikan dengan tepat bagaimana ukuran dihitung, tetapi itu memberi saya karakteristik kinerja.

Jadi : mendokumentasikan masalah kinerja. Jangan mendokumentasikan detail implementasi. Saya tidak peduli bagaimana std :: mengurutkan barang-barang saya, selama itu melakukannya dengan benar dan efisien. Kelas Anda juga tidak boleh mendokumentasikan bagaimana penghitungannya, tetapi jika sesuatu memiliki profil kinerja yang tidak terduga, dokumentasikan hal itu.

Winston Ewert
sumber
4
Selain itu: kompleksitas waktu / ruang dokumen terlebih dahulu, lalu berikan penjelasan mengapa fungsi memiliki properti tersebut. Misalnya:// O(n) Traverses the entire user list.
Jon Purdy
2
= (Sesuatu yang sepele seperti Python lengagal melakukan ini ... (Dalam setidaknya beberapa situasi, itu adalah O(n), seperti yang kita pelajari dalam sebuah proyek di perguruan tinggi ketika saya menyarankan menyimpan panjang alih-alih menghitung ulang setiap iterasi loop)
Izkata
@Izkata, ingin tahu. Apakah Anda ingat struktur apa itu O(n)?
Winston Ewert
@ WinstonEwert Sayangnya tidak. Itu 4+ tahun yang lalu dalam proyek Data Mining, dan saya hanya menyarankan kepada teman saya pada firasat karena saya telah bekerja dengan C di kelas lain ..
Izkata
1
@ JonPurdy Saya akan menambahkan bahwa dalam kode bisnis normal, mungkin tidak masuk akal untuk menentukan kompleksitas big-O. Misalnya, akses database O (1) kemungkinan besar akan jauh lebih lambat daripada O (n) traversal daftar dalam memori, jadi dokumentasikan apa yang penting. Tetapi tentu saja ada kasus di mana mendokumentasikan kompleksitas sangat penting (koleksi atau kode algoritma-berat lainnya).
svick
16

Dari pandangan akademis atau puritan CS, tentu saja kegagalan untuk menjelaskan dalam dokumentasi apa pun tentang internal penerapan fitur. Itu karena pengguna kelas idealnya tidak membuat asumsi tentang implementasi internal kelas. Jika implementasinya berubah, idealnya tidak ada pengguna yang tidak akan menyadari hal itu - fitur ini membuat abstraksi dan internal harus tetap tersembunyi sepenuhnya.

Namun, sebagian besar program dunia nyata menderita "Hukum abstraksi bocor" karya Joel Spolsky , yang mengatakan

"Semua abstraksi non-sepele, sampai taraf tertentu, bocor."

Itu berarti, hampir tidak mungkin untuk membuat abstraksi kotak hitam lengkap dari fitur kompleks. Dan gejala khas dari ini adalah masalah kinerja. Jadi untuk program dunia nyata, mungkin menjadi sangat penting panggilan mana yang mahal dan mana yang tidak, dan dokumentasi yang baik harus mencakup informasi itu (atau harus mengatakan di mana pengguna kelas diizinkan untuk membuat asumsi tentang kinerja, dan di mana tidak ).

Jadi saran saya adalah: sertakan informasi tentang panggilan mahal yang potensial jika Anda menulis dokumen untuk program dunia nyata, dan mengecualikannya untuk program yang Anda tulis hanya untuk tujuan pendidikan kursus CS Anda, mengingat setiap pertimbangan kinerja harus disimpan sengaja di luar ruang lingkup.

Doc Brown
sumber
+1, ditambah sebagian besar dokumentasi yang dibuat adalah untuk programmer berikutnya untuk mempertahankan proyek Anda, bukan programmer berikutnya untuk menggunakannya .
jmoreno
12

Anda dapat menulis apakah panggilan yang diberikan mahal atau tidak. Lebih baik, gunakan konvensi penamaan seperti getAgeuntuk akses cepat dan loadAgeatau fetchAgeuntuk pencarian mahal. Anda pasti ingin memberi tahu pengguna jika metode ini melakukan IO.

Setiap detail yang Anda berikan dalam dokumentasi itu seperti kontrak yang harus dihormati oleh kelas. Ini harus menginformasikan tentang perilaku penting. Seringkali, Anda akan melihat indikasi kompleksitas dengan notasi O besar. Tetapi Anda biasanya ingin singkat dan to the point.

Simon Bergot
sumber
1
+1 untuk menyebutkan bahwa dokumentasi merupakan bagian dari kontrak suatu kelas dengan antarmuka-nya.
Bart van Ingen Schenau
Saya mendukung ini. Lebih lanjut secara umum berusaha meminimalkan kebutuhan getter dengan menyediakan metode dengan perilaku.
sevenforce
9

Jika saya mendesain database yang diisi dengan objek Person, bukankah penting untuk mengetahui apakah Person.age adalah panggilan yang mahal atau tidak?

Iya nih.

Inilah sebabnya saya terkadang menggunakan Find()fungsi untuk menunjukkan bahwa menelepon mungkin perlu waktu. Ini lebih dari sebuah konvensi daripada yang lain. Waktu yang dibutuhkan untuk fungsi atau atribut untuk kembali ada bedanya program (meskipun mungkin kepada pengguna), meskipun di antara programer ada adalah harapan bahwa, jika dideklarasikan sebagai atribut, biaya untuk menyebutnya harus rendah.

Bagaimanapun, harus ada informasi yang cukup dalam kode itu sendiri untuk menyimpulkan apakah sesuatu adalah fungsi atau atribut, jadi saya tidak benar-benar melihat kebutuhan untuk mengatakan itu dalam dokumentasi.

Robert Harvey
sumber
4
+1: konvensi itu idiomatis di beberapa tempat. Selanjutnya, dokumentasi harus dilakukan di tingkat antarmuka - pada saat itu Anda tidak tahu bagaimana Person.Age diimplementasikan.
Telastyn
@ Telastyn: Saya tidak pernah memikirkan dokumentasi dengan cara seperti ini; yaitu, bahwa itu harus dilakukan pada level antarmuka. Tampaknya sudah jelas sekarang. +1 untuk komentar berharga itu.
stakx
Saya suka jawaban ini banyak. Contoh sempurna dari apa yang Anda gambarkan bahwa kinerja bukan masalah bagi program itu sendiri adalah jika Orang adalah entitas yang diambil dari layanan RESTful. GET bersifat inheren tetapi tidak jelas apakah ini akan murah atau mahal. Ini tentu saja tidak harus OOP tetapi intinya sama.
maple_shaft
+1 untuk menggunakan Getmetode di atas atribut untuk menunjukkan operasi yang lebih berat. Saya telah melihat cukup kode di mana pengembang menganggap sebuah properti hanyalah sebuah accessor dan menggunakannya beberapa kali alih-alih menyimpan nilai ke variabel lokal, dan dengan demikian mengeksekusi algoritma yang sangat kompleks lebih dari sekali. Jika tidak ada konvensi untuk tidak mengimplementasikan properti seperti itu dan dokumentasi tidak mengisyaratkan kompleksitas, maka saya berharap siapa pun yang memiliki aplikasi seperti itu selamat mencoba.
enzi
Dari mana konvensi ini berasal? Berpikir tentang Java saya akan mengharapkannya sebaliknya: getmetode yang setara dengan akses atribut dan jadi tidak mahal.
sevenforce
3

Penting untuk dicatat bahwa edisi pertama buku ini ditulis pada tahun 1988, pada hari-hari awal OOP. Orang-orang ini bekerja dengan bahasa berorientasi objek yang lebih murni yang banyak digunakan saat ini. Bahasa OO kami yang paling populer saat ini - C ++, C # & Java - memiliki beberapa perbedaan yang cukup signifikan dari cara bahasa-bahasa awal, yang lebih murni OO, bekerja.

Dalam bahasa seperti C ++ & Java, Anda harus membedakan antara mengakses atribut dan pemanggilan metode. Ada dunia perbedaan antara instance.getter_methoddan instance.getter_method(). Yang satu benar-benar mendapatkan nilai Anda dan yang lain tidak.

Ketika bekerja dengan bahasa OO yang lebih murni, dari persuasi Smalltalk atau Ruby (yang nampak bahwa bahasa Eiffel yang digunakan dalam buku ini), itu menjadi saran yang sangat valid. Bahasa-bahasa ini secara implisit akan memanggil metode untuk Anda. Tidak ada perbedaan antara instance.attributedan instance.getter_method.

Saya tidak akan berkeringat saat ini atau menganggapnya terlalu dogmatis. Maksudnya bagus - Anda tidak ingin pengguna kelas Anda khawatir tentang detail implementasi yang tidak relevan - tetapi itu tidak diterjemahkan dengan baik ke sintaksis banyak bahasa modern.

Sean McSomething
sumber
1
Poin yang sangat penting tentang mempertimbangkan tahun di mana saran itu dibuat. Nit: Smalltalk dan Simula tanggal kembali ke 60-an dan 70-an, jadi 88 hampir tidak "hari awal".
luser droog
2

Sebagai pengguna, Anda tidak perlu tahu bagaimana sesuatu diterapkan.

Jika kinerja adalah masalah, sesuatu harus dilakukan di dalam implementasi kelas, bukan di sekitarnya. Oleh karena itu, tindakan yang benar adalah memperbaiki implementasi kelas atau untuk mengajukan bug ke pengelola.

mouviciel
sumber
3
Apakah selalu demikian bahwa metode yang mahal secara komputasi adalah bug? Sebagai contoh sepele, katakanlah saya prihatin dengan menjumlahkan panjang array string. Secara internal, saya tidak tahu apakah string dalam bahasa saya adalah gaya Pascal atau C-style. Dalam kasus sebelumnya, karena string "tahu" panjangnya, saya bisa berharap loop penjumlahan panjang saya akan mengambil waktu linier tergantung pada jumlah string. Saya juga harus tahu bahwa operasi yang mengubah panjang string akan memiliki overhead yang terkait dengan mereka, karena string.lengthakan dihitung ulang setiap kali itu berubah.
Patrick Collins
3
Dalam kasus terakhir, karena string tidak "tahu" panjangnya, saya bisa berharap loop penjumlahan panjang saya akan mengambil waktu kuadratik (yang tergantung pada jumlah string dan panjangnya), tetapi operasi yang mengubah panjang string akan lebih murah. Tidak satu pun dari implementasi ini yang salah, dan tidak ada yang pantas mendapat laporan bug, tetapi mereka menyerukan gaya pengkodean yang sedikit berbeda untuk menghindari cegukan yang tidak terduga. Bukankah lebih mudah jika pengguna setidaknya memiliki ide yang tidak jelas apa yang sedang terjadi?
Patrick Collins
Jadi jika Anda tahu bahwa kelas string mengimplementasikan gaya-C, Anda akan memilih cara pengkodean dengan mempertimbangkan fakta itu. Tetapi bagaimana jika versi berikutnya dari kelas string mengimplementasikan representasi gaya Foo baru? Apakah Anda akan mengubah kode Anda atau Anda akan menerima kehilangan kinerja yang disebabkan oleh asumsi yang salah dalam kode Anda?
mouviciel
Saya melihat. Jadi jawaban OO untuk "Bagaimana saya bisa memeras beberapa kinerja ekstra dari kode saya, bergantung pada implementasi tertentu?" adalah "Kamu tidak bisa." Dan jawaban untuk "Kode saya lebih lambat dari yang saya harapkan, mengapa?" adalah "Itu perlu ditulis ulang." Apakah itu kurang lebih idenya?
Patrick Collins
2
@PatrickCollins Respons OO bergantung pada antarmuka bukan implementasi. Jangan gunakan antarmuka yang tidak menyertakan jaminan kinerja sebagai bagian dari definisi antarmuka (seperti contoh C ++ 11 List.size dijamin O (1)). Tidak perlu menyertakan detail implementasi dalam definisi antarmuka. Jika kode Anda lebih lambat dari yang Anda inginkan, adakah jawaban lain selain Anda harus mengubahnya lebih cepat (setelah membuat profil untuk menentukan kemacetan)?
stonemetal
2

Setiap dokumentasi yang berorientasi pada programmer yang gagal memberi tahu programmer tentang biaya kerumitan rutinitas / metode adalah salah.

  • Kami mencari untuk menghasilkan metode bebas efek samping.

  • Jika eksekusi suatu metode telah menjalankan kompleksitas waktu dan / atau kompleksitas memori selain dari itu O(1), dalam lingkungan yang dibatasi memori atau waktu, itu dapat dianggap memiliki efek samping .

  • The prinsip paling mengejutkan dilanggar jika metode melakukan sesuatu yang sama sekali tak terduga - dalam hal ini, memonopoli memori atau membuang-buang waktu CPU.

Pemburu rusa
sumber
1

Saya pikir Anda memahaminya dengan benar, tetapi saya juga berpikir Anda memiliki poin yang bagus. jika Person.agediimplementasikan dengan perhitungan yang mahal, maka saya pikir saya juga ingin melihatnya dalam dokumentasi. Itu bisa membuat perbedaan antara menyebutnya berulang kali (jika itu operasi yang murah) atau memanggilnya sekali dan menyimpan nilai (jika mahal). Saya tidak tahu pasti, tetapi saya pikir dalam hal ini Meyer mungkin setuju bahwa peringatan dalam dokumentasi harus dimasukkan.

Cara lain untuk menangani ini mungkin dengan memperkenalkan atribut baru yang namanya menyiratkan bahwa perhitungan yang panjang mungkin terjadi (seperti Person.ageCalculatedFromDB) dan kemudian Person.agemengembalikan nilai yang di-cache di dalam kelas, tetapi ini mungkin tidak selalu sesuai, dan tampaknya terlalu rumit hal, menurut saya.

FrustratedWithFormsDesigner
sumber
3
Anda juga bisa membuat argumen bahwa jika Anda perlu mengetahui agea Person, Anda harus memanggil metode untuk mendapatkannya. Jika penelepon mulai melakukan hal-hal yang terlalu pintar untuk menghindari harus melakukan perhitungan, mereka berisiko memiliki implementasi mereka tidak bekerja dengan benar karena mereka melewati batas ulang tahun. Implementasi yang mahal di kelas akan bermanifestasi sebagai masalah kinerja yang dapat di-root oleh profil dan perbaikan seperti caching dapat dilakukan di dalam kelas, di mana semua penelepon akan melihat manfaat (dan hasil yang benar).
Blrfl
1
@ Bllfl: baik ya, caching harus dilakukan di Personkelas, tapi saya pikir pertanyaannya dimaksudkan sebagai lebih umum dan Person.ageitu hanya sebuah contoh. Mungkin ada beberapa kasus di mana akan lebih masuk akal bagi penelepon untuk memilih - mungkin callee memiliki dua algoritma yang berbeda untuk menghitung nilai yang sama: satu cepat tetapi tidak akurat, satu jauh lebih lambat tetapi lebih akurat (rendering 3D datang ke pikiran sebagai satu tempat di mana itu mungkin terjadi), dan dokumentasi harus menyebutkan ini.
FrustratedWithFormsDesigner
Dua metode yang memberikan hasil yang berbeda adalah use case yang berbeda dari ketika Anda mengharapkan jawaban yang sama setiap kali.
Blrfl
0

Dokumentasi untuk kelas berorientasi objek sering melibatkan pertukaran antara memberikan pengelola kelas fleksibilitas untuk mengubah desainnya, versus memungkinkan konsumen kelas untuk memanfaatkan sepenuhnya potensinya. Jika kelas berubah akan memiliki sejumlah properti yang akan memiliki tertentu yang sebenarnya hubungan satu sama lain (misalnya Left, Right, danWidthproperti dari integer-coordinate grid-aligned rectangle), orang mungkin mendesain kelas untuk menyimpan kombinasi dua properti dan menghitung yang ketiga, atau orang mungkin mendesainnya untuk menyimpan ketiganya. Jika tidak ada antarmuka yang memperjelas properti mana yang disimpan, programmer kelas mungkin dapat mengubah desain jika hal itu terbukti bermanfaat karena beberapa alasan. Sebaliknya, jika misalnya dua properti diekspos sebagai finalbidang dan yang ketiga tidak, maka versi kelas yang akan datang harus selalu menggunakan dua properti yang sama sebagai "basis".

Jika properti tidak memiliki hubungan yang tepat (misalnya karena mereka floatatau doublebukan daripada int), maka mungkin perlu untuk mendokumentasikan properti mana yang "mendefinisikan" nilai suatu kelas. Sebagai contoh, meskipun Leftplus Widthseharusnya sama Right, matematika floating-point sering tidak tepat. Sebagai contoh, anggap suatu Rectangleyang menggunakan tipe Floataccept Leftdan Widthsebagai parameter konstruktor dikonstruksi dengan Leftdiberikan sebagai 1234567fdan Widthsebagai 1.1f. floatRepresentasi terbaik dari jumlah tersebut adalah 1234568,125 [yang dapat ditampilkan sebagai 1234568,13]; yang lebih kecil berikutnya floatadalah 1234568.0. Jika kelas benar-benar menyimpan LeftdanWidth, itu dapat melaporkan nilai lebar seperti yang ditentukan. Namun, jika konstruktor dihitung Rightberdasarkan pass-in Leftdan Width, dan kemudian dihitung Widthberdasarkan Leftdan Right, itu akan melaporkan lebar 1.25fdaripada sebagai pass-in 1.1f.

Dengan kelas yang bisa berubah, hal-hal bisa menjadi lebih menarik, karena perubahan ke salah satu nilai yang saling terkait akan menyiratkan perubahan ke setidaknya satu yang lain, tetapi mungkin tidak selalu jelas yang mana. Dalam beberapa kasus, mungkin yang terbaik untuk menghindari metode yang "set" satu properti seperti itu, melainkan juga harus metode untuk misalnya SetLeftAndWidthatau SetLeftAndRight, atau make jelas apa sifat yang sedang ditetapkan dan yang berubah (misalnya MoveRightEdgeToSetWidth, ChangeWidthToSetLeftEdgeatau MoveShapeToSetRightEdge) .

Kadang-kadang mungkin berguna untuk memiliki kelas yang melacak nilai properti mana yang telah ditentukan dan yang telah dihitung dari yang lain. Misalnya, kelas "momen dalam waktu" mungkin menyertakan waktu absolut, waktu lokal, dan zona waktu offset. Seperti banyak jenis seperti itu, diberikan dua potong informasi, satu dapat menghitung yang ketiga. Tahu yang manasepotong informasi dihitung, namun, kadang-kadang mungkin penting. Sebagai contoh, misalkan suatu peristiwa dicatat terjadi pada "17:00 UTC, zona waktu -5, waktu setempat 12:00 siang", dan satu kemudian menemukan bahwa zona waktu seharusnya -6. Jika ada yang tahu bahwa UTC direkam dari server, catatan tersebut harus dikoreksi menjadi "18:00 UTC, zona waktu -6, waktu setempat 12:00 siang"; Jika seseorang memasukkan waktu lokal di luar jam maka harus "17:00 UTC, zona waktu -6, waktu setempat 11:00". Tanpa mengetahui apakah waktu global atau lokal harus dianggap "lebih dapat dipercaya", bagaimanapun, tidak mungkin untuk mengetahui koreksi mana yang harus diterapkan. Namun, jika catatan melacak waktu yang ditentukan, perubahan zona waktu dapat meninggalkan yang satu itu sementara mengubah yang lain.

supercat
sumber
0

Semua aturan ini tentang cara menyembunyikan informasi di kelas sangat masuk akal dengan asumsi perlu melindungi seseorang dari pengguna kelas yang akan membuat kesalahan dengan membuat ketergantungan pada implementasi internal.

Tidak apa-apa untuk membangun perlindungan seperti itu, jika kelas memiliki penonton seperti itu. Tetapi ketika pengguna menulis panggilan ke fungsi di kelas Anda, mereka mempercayai Anda dengan rekening bank waktu eksekusi mereka.

Inilah hal yang sering saya lihat:

  1. Objek memiliki bit "dimodifikasi" yang mengatakan jika mereka, dalam beberapa hal, ketinggalan zaman. Cukup sederhana, tetapi kemudian mereka memiliki objek bawahan, jadi mudah untuk membiarkan "dimodifikasi" menjadi fungsi yang menjumlahkan semua objek bawahan. Kemudian jika ada beberapa lapisan objek bawahan (kadang-kadang berbagi objek yang sama lebih dari sekali) sederhana "Dapatkan" dari properti "dimodifikasi" akhirnya dapat mengambil sebagian kecil dari waktu eksekusi yang sehat.

  2. Ketika suatu objek diubah dengan cara tertentu, diasumsikan bahwa objek lain yang tersebar di sekitar perangkat lunak perlu "diberitahu". Ini dapat terjadi pada beberapa lapisan struktur data, jendela, dll. Yang ditulis oleh programmer yang berbeda, dan kadang-kadang berulang dalam rekursi tak terbatas yang perlu dijaga. Bahkan jika semua penulis dari penangan notifikasi tersebut cukup berhati-hati untuk tidak membuang waktu, seluruh interaksi gabungan dapat berakhir dengan menggunakan sebagian kecil waktu eksekusi yang tidak terduga dan menyakitkan, dan asumsi bahwa itu hanya "perlu" dibuat dengan riang.

SO, saya suka melihat kelas-kelas yang menyajikan antarmuka abstrak bersih yang bagus untuk dunia luar, tetapi saya ingin memiliki beberapa gagasan tentang bagaimana mereka bekerja, jika hanya untuk memahami pekerjaan apa yang menyelamatkan saya. Tetapi di luar itu, saya cenderung merasa bahwa "lebih sedikit lebih banyak". Orang-orang begitu terpikat pada struktur data sehingga mereka berpikir lebih banyak lebih baik, dan ketika saya melakukan tuning kinerja alasan besar universal untuk masalah kinerja adalah kepatuhan terhadap struktur data yang membengkak membangun cara orang diajarkan.

Jadi pergilah.

Mike Dunlavey
sumber
0

Menambahkan detail implementasi seperti "hitung atau tidak" atau "info kinerja" membuatnya lebih sulit untuk menjaga kode dan dokumen tetap sinkron .

Contoh:

Jika Anda memiliki metode "mahal-kinerja" apakah Anda ingin mendokumentasikan "mahal" juga untuk semua kelas yang menggunakan metode ini? bagaimana jika Anda mengubah implementasinya menjadi tidak mahal lagi. Apakah Anda ingin memperbarui info ini ke semua konsumen juga?

Tentu saja baik bagi pengelola kode untuk mendapatkan semua info penting dari dokumentasi kode, tetapi saya tidak suka dokumentasi yang mengklaim sesuatu yang tidak valid lagi (tidak sinkron dengan kode)

k3b
sumber
0

Ketika jawaban yang diterima sampai pada kesimpulan:

Jadi: mendokumentasikan masalah kinerja.

dan kode yang didokumentasikan sendiri dianggap lebih baik daripada dokumentasi yang mengikuti bahwa nama metode harus menyatakan hasil kinerja yang tidak biasa.

Jadi tetap Person.ageuntuk return current_year - self.birth_datetetapi jika metode ini menggunakan loop untuk menghitung usia (ya):Person.calculateAge()

sevenforce
sumber