Ketika saya membagi metode besar (atau prosedur, atau fungsi - pertanyaan ini tidak spesifik untuk OOP, tetapi karena saya bekerja dalam bahasa OOP 99% dari waktu, itu adalah terminologi yang paling nyaman bagi saya) menjadi banyak yang kecil , Saya sering merasa tidak senang dengan hasilnya. Menjadi lebih sulit untuk menalar tentang metode-metode kecil ini daripada ketika mereka hanya berupa blok kode dalam metode besar, karena ketika saya mengekstraknya, saya kehilangan banyak asumsi mendasar yang berasal dari konteks pemanggil.
Kemudian, ketika saya melihat kode ini dan melihat metode individual, saya tidak langsung tahu dari mana mereka dipanggil, dan menganggapnya sebagai metode pribadi biasa yang dapat dipanggil dari mana saja dalam file. Misalnya, bayangkan metode inisialisasi (konstruktor atau lainnya) dibagi menjadi serangkaian yang kecil: dalam konteks metode itu sendiri, Anda dengan jelas tahu bahwa keadaan objek masih tidak valid, tetapi dalam metode pribadi biasa Anda mungkin beralih dari asumsi objek itu sudah diinisialisasi dan dalam keadaan valid.
Satu-satunya solusi yang saya lihat untuk ini adalah where
klausa di Haskell, yang memungkinkan Anda untuk mendefinisikan fungsi-fungsi kecil yang hanya digunakan dalam fungsi "induk". Pada dasarnya, ini terlihat seperti ini:
len x y = sqrt $ (sq x) + (sq y)
where sq a = a * a
Tetapi bahasa lain yang saya gunakan tidak memiliki hal seperti ini - hal terdekat adalah mendefinisikan lambda dalam lingkup lokal, yang mungkin bahkan lebih membingungkan.
Jadi, pertanyaan saya adalah - apakah Anda menemukan ini, dan apakah Anda bahkan melihat ini adalah masalah? Jika Anda melakukannya, bagaimana Anda biasanya menyelesaikannya, khususnya dalam bahasa OOP "arus utama", seperti Java / C # / C ++?
Edit tentang duplikat: Seperti yang diketahui orang lain, sudah ada pertanyaan yang membahas metode pemisahan dan pertanyaan kecil yang bersifat satu baris. Saya membacanya, dan mereka tidak membahas masalah asumsi mendasar yang dapat diturunkan dari konteks penelepon (misalnya di atas, objek diinisialisasi). Itulah inti dari pertanyaan saya, dan itulah mengapa pertanyaan saya berbeda.
Pembaruan: Jika Anda mengikuti pertanyaan dan diskusi di bawah ini, Anda dapat menikmati artikel ini oleh John Carmack tentang masalah ini , khususnya:
Selain kesadaran akan kode aktual yang dieksekusi, fungsi inlining juga bermanfaat karena tidak memungkinkan untuk memanggil fungsi dari tempat lain. Itu kedengarannya konyol, tapi ada benarnya. Sebagai basis kode tumbuh dari tahun ke tahun penggunaan, akan ada banyak peluang untuk mengambil jalan pintas dan hanya memanggil fungsi yang hanya melakukan pekerjaan yang menurut Anda perlu dilakukan. Mungkin ada fungsi FullUpdate () yang memanggil PartialUpdateA (), dan PartialUpdateB (), tetapi dalam beberapa kasus tertentu Anda mungkin menyadari (atau berpikir) bahwa Anda hanya perlu melakukan PartialUpdateB (), dan Anda menjadi efisien dengan menghindari yang lain kerja. Banyak dan banyak bug berasal dari ini. Sebagian besar bug adalah hasil dari kondisi eksekusi yang tidak sesuai dengan apa yang Anda pikirkan.