Kelas yang tidak mewakili apa pun - apakah benar?

42

Saya hanya merancang aplikasi saya dan saya tidak yakin apakah saya mengerti SOLID dan OOP dengan benar. Kelas harus melakukan 1 hal dan melakukannya dengan baik tetapi dari sisi lain mereka harus mewakili objek nyata yang bekerja dengan kita.

Dalam kasus saya, saya melakukan ekstraksi fitur pada dataset dan kemudian saya melakukan analisis pembelajaran mesin. Saya berasumsi bahwa saya dapat membuat tiga kelas

  1. FeatureExtractor
  2. Set Data
  3. Penganalisa

Tetapi kelas FeatureExtractor tidak mewakili apa pun, ia melakukan sesuatu yang membuatnya lebih sebagai rutinitas daripada kelas. Ini hanya memiliki satu fungsi yang akan digunakan: extract_features ()

Apakah benar membuat kelas yang tidak mewakili satu hal tetapi melakukan satu hal?

EDIT: tidak yakin apakah itu penting tapi saya menggunakan Python

Dan jika extract_features () akan terlihat seperti itu: apakah layak membuat kelas khusus untuk menampung metode itu?

def extract_features(df):
    extr = PhrasesExtractor()
    extr.build_vocabulary(df["Text"].tolist())

    sent = SentimentAnalyser()
    sent.load()

    df = add_features(df, extr.features)
    df = mark_features(df, extr.extract_features)
    df = drop_infrequent_features(df)
    df = another_processing1(df)
    df = another_processing2(df)
    df = another_processing3(df)
    df = set_sentiment(df, sent.get_sentiment)
    return df
Alicja Głowacka
sumber
13
Ini terlihat sangat bagus sebagai fungsi. Mempertimbangkan tiga hal yang Anda daftarkan sebagai modul tidak apa-apa, dan Anda mungkin ingin menempatkannya dalam file yang berbeda, tetapi itu tidak berarti mereka perlu kelas.
Bergi
31
Perlu diketahui bahwa cukup umum dan dapat diterima untuk menggunakan pendekatan non-OO dengan Python.
jpmc26
13
Anda mungkin tertarik dengan Desain Berbasis Domain. "Kelas harus mewakili objek dari dunia nyata" sebenarnya salah ... mereka harus mewakili objek dalam domain . Domain sering sangat terkait dengan dunia nyata, tetapi tergantung pada aplikasi beberapa hal mungkin atau mungkin tidak dianggap objek, atau beberapa hal yang "pada kenyataannya" terpisah mungkin berakhir baik terkait atau identik di dalam domain aplikasi.
Bakuriu
1
Ketika Anda menjadi lebih akrab dengan OOP, saya pikir Anda akan menemukan bahwa kelas sangat jarang berhubungan satu-satu dengan entitas dunia nyata. Sebagai contoh, inilah esai yang berpendapat mencoba menjejalkan semua fungsionalitas yang terkait dengan entitas dunia nyata dalam satu kelas sangat sering merupakan anti-pola: programmer.97things.oreilly.com/wiki/index.php/…
Kevin - Pasang kembali Monica
1
"Mereka harus mewakili benda nyata yang bekerja dengan kita." belum tentu. Banyak bahasa memiliki kelas aliran yang mewakili aliran byte, yang merupakan konsep abstrak dan bukan 'objek nyata'. Secara teknis sistem file juga bukan 'objek nyata', itu hanya sebuah konsep, tetapi kadang-kadang ada kelas yang mewakili sistem file atau bagian dari itu.
Pharap

Jawaban:

96

Kelas harus melakukan 1 hal dan melakukannya dengan baik

Ya, itu umumnya pendekatan yang baik.

tetapi dari sisi lain mereka harus mewakili objek nyata yang bekerja dengan kita.

Tidak, itu adalah kesalahpahaman umum IMHO. Akses pemula yang baik ke OOP sering "mulai dengan objek yang mewakili hal-hal dari dunia nyata" , itu benar.

Namun, Anda tidak boleh berhenti dengan ini !

Kelas dapat (dan harus) digunakan untuk menyusun program Anda dengan berbagai cara. Membuat model objek dari dunia nyata adalah salah satu aspek dari ini, tetapi bukan satu-satunya. Membuat modul atau komponen untuk tugas tertentu adalah kasus penggunaan lain yang masuk akal untuk kelas. "Ekstraktor fitur" mungkin merupakan modul seperti itu, dan meskipun hanya berisi satu metode publikextract_features() , saya akan heran jika jika tidak juga mengandung banyak metode pribadi dan mungkin beberapa keadaan bersama. Jadi memiliki kelas FeatureExtractorakan memperkenalkan lokasi alami untuk metode pribadi ini.

Catatan: dalam bahasa seperti Python yang mendukung konsep modul terpisah, seseorang juga dapat menggunakan modul FeatureExtractoruntuk ini, tetapi dalam konteks pertanyaan ini, ini adalah IMHO perbedaan yang dapat diabaikan.

Selain itu, "ekstraktor fitur" dapat dibayangkan sebagai "orang atau bot yang mengekstraksi fitur". Itu adalah "benda" abstrak, mungkin bukan benda yang akan Anda temukan di dunia nyata, tetapi nama itu sendiri adalah abstraksi yang berguna, yang memberi setiap orang gagasan tentang apa tanggung jawab kelas itu. Jadi saya tidak setuju bahwa kelas ini tidak "mewakili apa pun".

Doc Brown
sumber
33
Saya terutama suka bahwa Anda menyebutkan masalah keadaan internal. Saya sering menemukan itu menjadi faktor penentu untuk apakah saya membuat sesuatu kelas atau fungsi dengan Python.
David Z
17
Anda sepertinya merekomendasikan "classitis". Jangan membuat kelas untuk ini, ini adalah antipattern gaya Java. Jika suatu fungsi, buatlah fungsi. Keadaan internal tidak relevan: fungsi dapat memiliki itu (melalui penutupan).
Konrad Rudolph
25
@KonradRudolph: Anda sepertinya melewatkan bahwa ini bukan tentang membuat satu fungsi. Ini tentang sepotong kode yang memerlukan beberapa fungsi, nama umum dan mungkin beberapa status bersama. Menggunakan modul untuk ini mungkin masuk akal dalam bahasa dengan konsep modul terpisah dari kelas.
Doc Brown
8
@DocBrown aku harus tidak setuju. Ini kelas dengan satu metode publik. Dari sisi API, itu tidak bisa dibedakan dari suatu fungsi. Lihat jawaban saya untuk detailnya. Menggunakan kelas metode tunggal dapat dibenarkan jika Anda perlu membuat tipe tertentu untuk mewakili negara. Tapi ini tidak terjadi di sini (dan bahkan kemudian, fungsi kadang-kadang dapat digunakan).
Konrad Rudolph
6
@DocBrown Saya mulai mengerti maksud Anda: Anda berbicara tentang fungsi yang dipanggil dari dalam extract_features? Saya agak berasumsi bahwa itu adalah acara publik dari tempat lain. Cukup adil, saya setuju bahwa jika ini pribadi maka mereka mungkin harus masuk ke modul (tapi tetap: bukan kelas, kecuali mereka berbagi negara), bersama dengan extract_features. (Konon, Anda tentu saja dapat mendeklarasikannya secara lokal di dalam fungsi itu.)
Konrad Rudolph
44

Doc Brown tepat: kelas tidak perlu mewakili objek dunia nyata. Mereka hanya perlu bermanfaat . Kelas adalah jenis dasarnya hanya tambahan, dan apa yang intatau stringsesuai dengan di dunia nyata? Mereka adalah deskripsi abstrak, bukan hal-hal konkret, nyata.

Yang mengatakan, kasing Anda istimewa. Menurut uraian Anda:

Dan jika extract_features () akan terlihat seperti itu: apakah layak membuat kelas khusus untuk menampung metode itu?

Anda benar sekali: jika kode Anda seperti yang ditunjukkan, tidak ada gunanya menjadikannya sebuah kelas. Ada pembicaraan terkenal yang berpendapat bahwa penggunaan kelas-kelas semacam itu di Python adalah bau kode, dan bahwa fungsi-fungsi sederhana seringkali cukup. Kasing Anda adalah contoh sempurna dari ini.

Terlalu sering menggunakan kelas disebabkan oleh kenyataan bahwa OOP menjadi arus utama dengan Jawa pada 1990-an. Sayangnya Java pada saat itu tidak memiliki beberapa fitur bahasa modern (seperti penutupan), yang berarti bahwa banyak konsep sulit atau tidak mungkin untuk diungkapkan tanpa menggunakan kelas. Misalnya, tidak mungkin di Jawa sampai saat ini untuk memiliki metode yang dilakukan negara (yaitu penutupan). Sebagai gantinya, Anda harus menulis kelas untuk membawa negara, dan yang memaparkan metode tunggal (disebut sesuatu seperti invoke).

Sayangnya gaya pemrograman ini menjadi populer jauh di luar Jawa (sebagian karena buku rekayasa perangkat lunak berpengaruh yang sebaliknya sangat berguna), bahkan dalam bahasa yang tidak memerlukan solusi seperti itu.

Dalam Python, kelas jelas merupakan alat yang sangat penting dan harus digunakan secara bebas. Tapi itu bukan satu - satunya alat, dan tidak ada alasan untuk menggunakannya di tempat yang tidak masuk akal. Ini adalah kesalahpahaman umum bahwa fungsi bebas tidak memiliki tempat di OOP.

Konrad Rudolph
sumber
Akan bermanfaat untuk menambahkan bahwa jika fungsi yang dipanggil dalam contoh sebenarnya adalah fungsi pribadi, mengenkapsulasi mereka dalam modul atau kelas akan sepenuhnya sesuai. Kalau tidak, saya setuju sepenuhnya.
Leliel
11
Juga berguna untuk mengingat bahwa "OOP" tidak berarti "menulis banyak kelas". Fungsi adalah objek dalam Python, jadi tidak perlu menganggap ini sebagai "bukan OOP". Sebaliknya, itu hanya menggunakan kembali tipe / kelas bawaan, dan "menggunakan kembali" adalah salah satu grails suci dalam pemrograman. Membungkus ini dalam sebuah kelas akan mencegah penggunaan kembali, karena tidak ada yang akan kompatibel dengan API baru ini (kecuali __call__ditentukan, dalam hal ini gunakan saja fungsi!)
Warbo
3
Juga tentang masalah "kelas vs fungsi yang berdiri sendiri": eev.ee/blog/2013/03/03/…
Joker_vD
1
Bukankah ini masalahnya, meskipun dalam Python "fungsi bebas" juga objek dengan tipe yang mengekspos suatu metode __call__()? Apakah itu benar-benar berbeda dari instance kelas batin anonim? Secara sintaksis, pasti tetapi dari desain bahasa, sepertinya perbedaan yang kurang signifikan dari yang Anda sajikan di sini.
JimmyJames
1
@ JimmyJames Benar. Intinya adalah bahwa mereka menawarkan fungsionalitas yang sama untuk tujuan tertentu tetapi lebih mudah digunakan.
Konrad Rudolph
36

Saya hanya merancang aplikasi saya dan saya tidak yakin apakah saya mengerti SOLID dan OOP dengan benar.

Sudah lebih dari 20 tahun dan saya tidak yakin juga.

Kelas harus melakukan 1 hal dan melakukannya dengan baik

Sulit salah di sini.

mereka harus mewakili objek nyata yang bekerja dengan kita.

Oh benarkah? Izinkan saya memperkenalkan Anda ke kelas yang paling sukses populer dan sepanjang masa: String. Kami menggunakannya untuk teks. Dan objek dunia nyata yang diwakilinya adalah ini:

Nelayan memegang 10 ikan yang digantungkan di tali

Kenapa tidak, tidak semua programmer terobsesi dengan memancing. Di sini kita menggunakan sesuatu yang disebut metafora. Boleh jadi membuat model hal-hal yang tidak benar-benar ada. Itu ide yang harus jelas. Anda sedang membuat gambar di benak pembaca Anda. Gambar-gambar itu tidak harus nyata. Mudah dipahami.

Desain OOP yang baik mengelompokkan pesan (metode) di sekitar data (keadaan) sehingga reaksi terhadap pesan tersebut dapat bervariasi tergantung pada data tersebut. Jika melakukan itu memodelkan beberapa hal dunia nyata, keren. Jika tidak, baiklah. Selama itu masuk akal bagi pembaca, tidak apa-apa.

Sekarang yakin, Anda bisa memikirkannya seperti ini:

surat meriah yang ditangguhkan dari string bertuliskan "LETS DO THINGS!"

tetapi jika Anda berpikir ini harus ada di dunia nyata sebelum Anda dapat menggunakan metafora, baik karir pemrograman Anda akan melibatkan banyak seni dan kerajinan.

candied_orange
sumber
1
Serangkaian gambar cantik ...
Zev Spitz
Pada titik ini saya tidak yakin "string" bahkan metaforis. Itu hanya memiliki arti khusus dalam domain pemrograman, seperti kata-kata seperti classdan tabledan column...
Kyralessa
@ Kirralessa Anda eter mengajarkan pemula metafora atau membiarkannya menjadi sihir bagi mereka. Tolong selamatkan saya dari coders yang percaya pada sihir.
candied_orange
6

Waspadalah! Tidak ada kata SOLID yang mengatakan kelas hanya "melakukan satu hal". Jika itu masalahnya, kelas hanya akan memiliki metode tunggal, dan tidak akan ada perbedaan nyata antara kelas dan fungsi.

SOLID mengatakan kelas harus mewakili satu tanggung jawab . Ini adalah semacam tanggung jawab orang dalam sebuah tim: Pengemudi, pengacara, pencopet, perancang grafis dll. Masing-masing orang ini dapat melakukan banyak tugas (terkait), tetapi semuanya berkaitan dengan satu tanggung jawab.

Intinya adalah - jika ada perubahan dalam persyaratan, idealnya Anda hanya perlu memodifikasi satu kelas. Ini hanya membuat kode lebih mudah dipahami, lebih mudah untuk memodifikasi dan mengurangi risiko.

Tidak ada aturan bahwa suatu benda harus mewakili "hal yang nyata". Ini hanya pengetahuan kargo karena OO awalnya diciptakan untuk digunakan dalam simulasi. Tetapi program Anda bukan simulasi (beberapa aplikasi OO modern), jadi aturan ini tidak berlaku. Selama setiap kelas memiliki tanggung jawab yang jelas, Anda harus baik-baik saja.

Jika suatu kelas benar-benar hanya memiliki metode tunggal dan kelas tidak memiliki keadaan apa pun, Anda dapat mempertimbangkan menjadikannya fungsi yang berdiri sendiri. Ini baik-baik saja dan mengikuti prinsip KISS dan YAGNI - tidak perlu membuat kelas jika Anda dapat menyelesaikannya dengan suatu fungsi. Di sisi lain, jika Anda memiliki alasan untuk percaya bahwa Anda mungkin memerlukan kondisi internal atau implementasi ganda, Anda mungkin juga menjadikannya kelas di muka. Anda harus menggunakan penilaian terbaik Anda di sini.

JacquesB
sumber
+1 untuk "tidak perlu membuat kelas jika Anda dapat menyelesaikannya dengan suatu fungsi". Terkadang seseorang perlu mengatakan yang sebenarnya.
tchrist
5

Apakah benar membuat kelas yang tidak mewakili satu hal tetapi melakukan satu hal?

Secara umum itu tidak masalah.

Tanpa sedikit deskripsi yang lebih spesifik apa yang FeatureExtractorseharusnya dilakukan kelas sebenarnya sulit untuk dikatakan.

Bagaimanapun, bahkan jika FeatureExtractormengekspos hanya extract_features()fungsi publik , saya bisa memikirkan mengonfigurasinya dengan Strategykelas, yang menentukan bagaimana tepatnya ekstraksi harus dilakukan.

Contoh lain adalah kelas dengan fungsi Templat .

Dan ada lebih banyak Pola Desain Perilaku , yang didasarkan pada model kelas.


Ketika Anda menambahkan beberapa kode untuk klarifikasi.

Dan jika extract_features () akan terlihat seperti itu: apakah layak membuat kelas khusus untuk menampung metode itu?

Garis

 sent = SentimentAnalyser()

persis terdiri dari apa yang saya maksudkan bahwa Anda dapat mengkonfigurasi kelas dengan Strategi .

Jika Anda memiliki antarmuka untuk SentimentAnalyserkelas itu, Anda bisa meneruskannya ke FeatureExtractorkelas pada titik konstruksi, alih-alih langsung menyambungkan ke implementasi spesifik dalam fungsi Anda.

πάντα ῥεῖ
sumber
2
Saya tidak melihat alasan untuk menambahkan kompleksitas ( FeatureExtractorkelas) hanya untuk memperkenalkan kompleksitas yang lebih (antarmuka untuk SentimentAnalyserkelas). Jika decoupling diinginkan, maka extract_featuresdapat mengambil get_sentimentfungsi sebagai argumen ( loadpanggilan tampaknya independen dari fungsi dan hanya dipanggil untuk pengaruhnya). Perhatikan juga bahwa Python tidak memiliki / mendorong antarmuka.
Warbo
1
@warbo - bahkan jika Anda menyediakan fungsi sebagai argumen, dengan menjadikannya fungsi, Anda membatasi potensi implementasi yang sesuai dengan format fungsi, tetapi jika ada kebutuhan untuk mengelola kondisi persisten antara satu permintaan dan selanjutnya (misalnya a CacheingFeatureExtractoratau a TimeSeriesDependentFeatureExtractor) maka suatu objek akan jauh lebih cocok. Hanya karena tidak perlu untuk objek saat ini tidak berarti tidak akan pernah ada.
Jules
3
@ Jules Pertama Anda Tidak Akan Membutuhkannya (YAGNI), kedua fungsi Python dapat merujuk keadaan persisten (penutupan) jika Anda membutuhkannya (Anda tidak akan), ketiga menggunakan fungsi tidak membatasi apa pun karena benda apa pun dengan objek __call__Metode akan kompatibel jika Anda membutuhkannya (Anda tidak akan), keempat dengan menambahkan pembungkus seperti FeatureExtractorAnda membuat kode tidak kompatibel dengan semua kode lain yang pernah ditulis (kecuali jika Anda memberikan __call__metode, dalam hal ini fungsi akan jelas lebih sederhana )
Warbo
0

Pola dan semua bahasa mewah / konsep samping: apa yang Anda temui adalah Pekerjaan atau Proses Batch .

Pada akhirnya, bahkan sebuah program OOP murni perlu entah bagaimana didorong oleh sesuatu, untuk benar-benar melakukan pekerjaan; pasti ada titik masuknya. Dalam pola MVC, misalnya, ontroller "C" menerima peristiwa klik dll dari GUI dan kemudian mengatur komponen lainnya. Dalam alat baris perintah klasik, fungsi "utama" akan melakukan hal yang sama.

Apakah benar membuat kelas yang tidak mewakili satu hal tetapi melakukan satu hal?

Kelas Anda mewakili entitas yang melakukan sesuatu dan mengatur segalanya. Anda dapat menamainya Pengendali , Pekerjaan , Utama atau apa pun yang terlintas dalam pikiran.

Dan jika extract_features () akan terlihat seperti itu: apakah layak membuat kelas khusus untuk menampung metode itu?

Itu tergantung pada keadaan (dan saya tidak terbiasa dengan cara biasa ini dilakukan dengan Python). Jika ini hanyalah alat baris perintah satu-shot kecil, maka metode alih-alih kelas harus baik-baik saja. Versi pertama dari program Anda pasti bisa lolos dengan metode. Jika, kemudian, Anda mendapati bahwa Anda berakhir dengan puluhan metode seperti itu, mungkin bahkan dengan variabel global yang tercampur, maka inilah saatnya untuk refactor ke dalam kelas.

AnoE
sumber
3
Perhatikan bahwa dalam skenario seperti ini, memanggil prosedur mandiri "metode" dapat membingungkan. Sebagian besar bahasa, termasuk Python, menyebutnya "fungsi". "Metode" adalah fungsi / prosedur yang terikat pada instance kelas tertentu, yang merupakan kebalikan dari penggunaan Anda terhadap istilah :)
Warbo
Cukup benar, @Warbo. Atau kita bisa menyebutnya prosedur atau defun atau sub atau ...; dan mereka mungkin metode kelas (sic) yang tidak terkait dengan sebuah instance. Saya harap pembaca yang lembut akan mampu mengaburkan makna yang dimaksud. :)
AnoE
@Warbo itu bagus untuk diketahui! Sebagian besar materi pembelajaran yang saya temui menyatakan bahwa fungsi dan metode istilah dapat dipertukarkan, dan itu hanya preferensi yang bergantung pada bahasa.
Dom
@ Tom Secara umum a ("pure") "function" adalah pemetaan dari nilai input ke nilai output; "prosedur" adalah fungsi yang juga dapat menyebabkan efek (misalnya menghapus file); keduanya secara statis dikirim (yaitu melihat ke dalam lingkup leksikal). "Metode" adalah fungsi atau (biasanya) prosedur yang secara dinamis dikirim (memandang ke atas) dari suatu nilai (disebut "objek"), yang secara otomatis terikat pada argumen (secara implisit thisatau eksplisit self) dari metode tersebut. Metode objek saling "terbuka" secara rekursif, jadi mengganti foopenyebab semua self.foopanggilan menggunakan penggantian ini.
Warbo
0

Kita dapat menganggap OOP sebagai pemodelan perilaku suatu sistem. Perhatikan bahwa sistem tidak harus ada di 'dunia nyata', meskipun metafora dunia nyata kadang-kadang bisa berguna (misalnya "jaringan pipa", "pabrik", dll.).

Jika sistem yang kita inginkan terlalu rumit untuk memodelkan sekaligus, kita dapat memecahnya menjadi potongan-potongan kecil dan memodelkan mereka ("domain masalah"), yang mungkin melibatkan penguraian lebih lanjut, dan seterusnya sampai kita menemukan bagian-bagian yang perilakunya cocok (kurang lebih) dari beberapa objek bahasa bawaan seperti angka, string, daftar, dll.

Setelah kita memiliki potongan-potongan sederhana itu, kita dapat menggabungkannya untuk menggambarkan perilaku potongan yang lebih besar, yang dapat kita gabungkan menjadi bagian yang lebih besar, dan seterusnya hingga kita dapat menggambarkan semua komponen domain yang diperlukan untuk keseluruhan sistem.

Ini adalah fase "menggabungkan bersama" di mana kita dapat menulis beberapa kelas. Kami menulis kelas ketika tidak ada objek yang ada yang berperilaku seperti yang kita inginkan. Misalnya, domain kami mungkin berisi "foo", koleksi foo yang disebut "bar", dan koleksi bar yang disebut "bazs". Kami mungkin memperhatikan bahwa foo cukup sederhana untuk dimodelkan dengan string, jadi kami melakukannya. Kami menemukan bahwa bilah memerlukan isinya untuk mematuhi batasan tertentu yang tidak cocok dengan apa pun yang disediakan oleh Python, dalam hal ini kami mungkin menulis kelas baru untuk menegakkan batasan ini. Mungkin baz tidak memiliki kekhasan seperti itu, jadi kita bisa mewakili mereka dengan daftar.

Perhatikan bahwa kita dapat menulis kelas baru untuk setiap komponen itu (foos, bar dan bazs), tetapi kita tidak perlu jika sudah ada sesuatu dengan perilaku yang benar. Secara khusus, agar suatu kelas berguna, ia perlu 'menyediakan' sesuatu (data, metode, konstanta, subkelas, dll.), Jadi bahkan jika kita memiliki banyak lapisan kelas khusus kita pada akhirnya harus menggunakan beberapa fitur bawaan; misalnya, jika kita menulis kelas baru untuk foos mungkin hanya berisi string, jadi mengapa tidak melupakan kelas foo dan minta kelas bar berisi string itu? Perlu diingat bahwa kelas juga merupakan objek bawaan, mereka hanya sangat fleksibel.

Setelah kita memiliki model domain kita, kita dapat mengambil beberapa contoh potongan-potongan itu dan mengaturnya menjadi "simulasi" dari sistem tertentu yang ingin kita model (misalnya "sistem pembelajaran mesin untuk ...").

Setelah kita memiliki simulasi ini, kita dapat menjalankannya dan hei presto, kita memiliki kerja (simulasi a) sistem pembelajaran mesin untuk ... (atau apa pun yang kita pemodelan).


Sekarang, dalam situasi khusus Anda, Anda mencoba memodelkan perilaku komponen "extractor fitur". Pertanyaannya adalah, adakah objek bawaan yang berperilaku seperti "ekstraktor fitur", atau akankah Anda perlu memecahnya menjadi hal-hal yang lebih sederhana? Sepertinya ekstraktor fitur berperilaku sangat mirip dengan objek fungsi, jadi saya pikir Anda akan baik-baik saja menggunakannya sebagai model Anda.


Satu hal yang perlu diingat ketika mempelajari konsep-konsep semacam ini adalah bahwa bahasa yang berbeda dapat menyediakan fitur dan objek bawaan yang berbeda (dan, tentu saja, beberapa bahkan tidak menggunakan terminologi seperti "objek"!). Oleh karena itu solusi yang masuk akal dalam satu bahasa mungkin kurang bermanfaat dalam bahasa lain (ini bahkan dapat berlaku untuk versi berbeda dari bahasa yang sama!).

Secara historis, banyak literatur OOP (terutama "pola desain") telah berfokus pada Jawa, yang sangat berbeda dari Python. Sebagai contoh, kelas Java bukan objek, Java tidak memiliki objek fungsi sampai saat ini, Java memiliki pemeriksaan tipe yang ketat (yang mendorong antarmuka dan subkelas) sementara Python mendorong bebek-mengetik, Java tidak memiliki objek modul, Java integers / mengapung / dll. bukan objek, meta-pemrograman / introspeksi di Jawa membutuhkan "refleksi", dan sebagainya.

Saya tidak mencoba memilih di Jawa (sebagai contoh lain, banyak teori OOP berputar di sekitar Smalltalk, yang sekali lagi sangat berbeda dari Python), saya hanya mencoba menunjukkan bahwa kita harus berpikir dengan sangat hati-hati tentang konteks dan kendala di mana solusi dikembangkan, dan apakah itu cocok dengan situasi kita sekarang.

Dalam kasus Anda, objek fungsi sepertinya merupakan pilihan yang baik. Jika Anda bertanya-tanya mengapa beberapa pedoman "praktik terbaik" tidak menyebutkan objek fungsi sebagai solusi yang mungkin, itu mungkin saja karena pedoman itu ditulis untuk versi Jawa yang lama!

Warbo
sumber
0

Secara pragmatis, ketika saya memiliki "hal lain yang melakukan sesuatu yang penting dan harus dipisahkan", dan tidak memiliki rumah yang jelas, saya meletakkannya di Utilitiesbagian dan menggunakannya sebagai konvensi penamaan saya. yaitu. FeatureExtractionUtility.

Lupakan jumlah metode di kelas; satu metode hari ini mungkin perlu tumbuh menjadi lima metode besok. Yang penting adalah struktur organisasi yang jelas dan konsisten, seperti area utilitas untuk koleksi fungsi lainnya.

Dom
sumber