Saya memiliki sedikit perdebatan dengan rekan kerja. Sederhananya, apakah ada alasan bagus untuk menyembunyikan / merangkum fungsi yang murni?
Yang saya maksud dengan "murni" adalah definisi wikipedia :
- Selalu mengembalikan hasil yang sama dari input yang sama. (Demi diskusi
Foo Create(){ return new Foo(); }
ini dianggap tidak murni jikaFoo
tidak memiliki nilai semantik.) - Tidak menggunakan keadaan bisa berubah-ubah (kecuali variabel lokal) atau I / O.
- Tidak menghasilkan efek samping.
design
pure-function
Telastyn
sumber
sumber
Jawaban:
Fungsi murni masih bisa menjadi detail implementasi. Meskipun fungsi tersebut tidak menyebabkan kerusakan (dari sudut pandang tidak melanggar invarian / kontrak penting), dengan mengeksposnya baik penulis dan pengguna kelas / modul / paket tersebut hilang. Penulis kehilangan karena sekarang dia tidak dapat menghapusnya bahkan jika implementasi berubah dan fungsinya tidak lagi berguna baginya. Pengguna kehilangan karena mereka harus menyaring dan mengabaikan fungsi tambahan yang tidak relevan untuk menggunakan API untuk memahaminya.
sumber
Pertanyaannya terbalik.
Anda tidak mencari alasan untuk membuat suatu fungsi non-publik. Ini adalah pola pikir yang salah untuk memulai (menurut saya). Alasannya harus sebaliknya.
Dengan kata lain - jangan tanya "mengapa saya membuatnya pribadi?". Tanyakan: "mengapa saya harus mempublikasikannya?"
Jika ragu, jangan ungkapkan. Ini seperti pisau cukur Ockham - jangan gandakan hak yang melebihi kebutuhan.
EDIT: Mengatasi kontra-argumen yang diajukan oleh @Telastyn dalam komentar (untuk menghindari diskusi panjang di sana):
Ya, kadang-kadang menyakitkan jika kelas terbuka untuk warisan, tetapi Anda tidak dapat mengganti beberapa metode pribadi (yang perilakunya ingin Anda ubah).
Tetapi
protected
akan cukup - dan itu masih non-publik.Jika menjadi bermasalah, maka cukup buat publik! Ada kebutuhan yang saya bicarakan :)
Maksud saya adalah bahwa Anda tidak harus melakukannya untuk berjaga-jaga (YAGNI dan semuanya).
Perhatikan bahwa selalu membuat fungsi pribadi menjadi publik lebih mudah daripada menariknya kembali ke privasi. Yang terakhir kemungkinan akan memecahkan kode yang ada.
sumber
Saya tidak berpikir keputusan untuk menyembunyikan / merangkum fungsi harus bergantung pada kemurniannya. Hanya karena suatu fungsi murni tidak berarti bahwa pihak eksternal perlu tahu tentang hal itu. Cukup menarik meskipun jika fungsinya murni dan dimaksudkan untuk umum mungkin bahkan tidak perlu menjadi contoh anggota antarmuka sama sekali mungkin lebih cocok sebagai statis. Tetapi sekali lagi semua ini tergantung pada maksud kontrak dan dalam hal ini pengelompokan fungsionalitas logis, bukan kemurnian fungsi.
sumber
Kelas harus mematuhi Prinsip Tanggung Jawab Tunggal . Sementara sebuah kelas mungkin perlu memanggil fungsionalitas lain untuk mencapai tujuannya, ia seharusnya hanya mengekspos fungsi yang merupakan bagian dari tanggung jawab tunggal.
Berikut ini hanya satu contoh kasus di mana visibilitas dapat menyebabkan masalah.
Pertimbangkan kelas yang mengatur widget. Mungkin sebagai bagian dari kode frobasinya, diperlukan fungsi utilitas yang mem-parsing sebuah string: mungkin ia perlu mengubah nama widget dengan cara yang tidak didukung fungsi string standar.
Karena ini adalah fungsi murni (string masuk, mengubahnya entah bagaimana, mengembalikan string baru), itu bisa publik atau pribadi tanpa konsekuensi. Atau mungkinkah itu?
Jika Anda membuatnya publik, sekarang kelas Anda memiliki dua tanggung jawab: widget frobnicating, dan mentransformasikan string. Ini melanggar SRP, dan dapat menyebabkan masalah jika kelas lain mengandalkan fungsi tersebut. Karena ini adalah sesuatu yang Anda pikir hanya digunakan di dalam kelas, mungkin Anda mengubah antarmuka atau visibilitasnya. Sekarang kelas di bagian lain dari sistem rusak.
Dengan menjaga fungsi pribadi, tidak ada yang pernah memiliki kesempatan untuk mengandalkan kode yang bukan bagian dari tanggung jawab tunggal kelas.
sumber
StringTransformer
kelas terpisah untuk merangkum dua atau tiga baris kode yang hanya digunakan di satu tempat? Saya setuju bahwa begitu kode digunakan di banyak tempat, yang terbaik adalah memisahkannya menjadi kelas baru dengan satu tanggung jawab, tetapi ada tradeoff.