Apakah objek dalam OOP harus mewakili entitas?

82

Apakah suatu objek harus mewakili suatu entitas?

Oleh entitas yang saya maksud sesuatu seperti Product, Motor, a ParkingLotdll, fisik, atau bahkan benda konseptual non-fisik yang jelas - sesuatu yang didefinisikan dengan baik, dengan beberapa data inti jelas milik objek, dan beberapa fungsi / metode yang jelas beroperasi pada data inti.

Sebagai contoh, saya bisa memiliki objek dari Demon, suatu entitas dalam dirinya sendiri, satu imajiner mungkin dan bukan fisik tapi sebuah entitas tetap

Bisakah suatu objek hanya kumpulan metode , seperangkat prosedur umum yang terkait dengan tujuan bersama?

Contoh: dapat kelas dipanggil MotorOperationsatau MotorActions, di mana tidak ada entitas, tetapi metode di dalam kelas melakukan hal-hal seperti

  • getMotorDataFromHTMLForm ()
  • getMotorManufacturers ()
  • selectMotorFromUserRequirements ($ persyaratan)
  • canMotorCanHandleOperatingConditions ($ conditions)
  • computePowerConsumptionForMotor ($ id)

Kelas biasanya didefinisikan sebagai pusat data untuk objek + operasi pada data. Jadi untuk Motormungkin ada beberapa variabel motor yang berkaitan dengan spesifikasi motor, dan mungkin ada operasi yang menggabungkan data tersebut untuk menghasilkan sesuatu.

Dalam kasus saya itu lebih seperti saya memiliki kelas dengan operasi pada data + data yang melewati kelas, tidak ada data sentris untuk "Operasi Motor", selain data sementara pass-through-the-class.

Pertanyaan

Bisakah kelas mewakili objek tanpa entitas? Jika tidak, mengapa mereka buruk / tidak lengkap / non-OOP-sentris? Apakah ada cara mereka perlu diubah / ditingkatkan secara konseptual agar sejalan dengan OOP?

Dennis
sumber
2
+1. Tetapi apakah "ya" berarti bahwa ia harus mewakili suatu entitas, atau apakah itu berarti bahwa mereka dapat mewakili objek tanpa entitas?
Panzercrisis
1
Hal pertama yang terlintas di benak saya: java.awt dan kelas-kelas "Op" -nya (mis. Docs.oracle.com/javase/7/docs/api/java/awt/image/… ), jika itu yang Anda maksud. Ini merupakan operasi. Sekarang, saya tidak yakin apakah ini praktik yang baik (memang terlihat aneh dan jelek), tetapi sudah termasuk dalam perpustakaan standar Java, dan Java adalah OOP. Sebagian besar.
Luke
1
Tidak, tapi itu tidak berarti MotorActionsatau MotorOperationside yang bagus atau tidak.
user253751
1
Pertanyaan ini dapat mengambil manfaat dari spesifikasi kaleng lebih lanjut .
reinierpost
3
@ Dennis Saya benar-benar merasa seperti Anda menanyakan semua pertanyaan yang salah. Pertama karena tidak ada satu definisi pasti tentang OOP, kedua karena paradigma hanya sarana untuk mencapai tujuan. Satu-satunya pertanyaan yang penting adalah "apakah menulis kode dengan cara ini memudahkan untuk beralasan tentang kebenarannya?" dan "apakah menulis kode dengan cara ini membuatnya lebih mudah untuk digunakan kembali?"
Doval

Jawaban:

109

Tidak , suatu objek tidak harus mewakili suatu entitas.

Bahkan, saya berpendapat bahwa ketika Anda berhenti berpikir tentang objek sebagai entitas fisik adalah ketika Anda akhirnya mendapatkan manfaat yang dijanjikan OOP.

Ini bukan contoh terbaik, tetapi desain Pembuat Kopi mungkin di mana cahaya mulai menyala untuk saya.

Objek adalah tentang pesan. Mereka tentang tanggung jawab. Itu bukan tentang Mobil, Pengguna, atau Pesanan.

Saya tahu kita mengajar OO dengan cara ini, tetapi menjadi jelas setelah beberapa kali mencoba betapa frustrasinya itu untuk mencari tahu ke mana perginya ketika Anda mencoba melakukan MVC, MVVM atau MV apa pun. Entah model Anda menjadi kembung sangat konyol atau pengendali Anda melakukannya. Untuk navigasi, senang mengetahui bahwa apa pun yang menyentuh Kendaraan ada dalam file Vehicle.ext, tetapi ketika aplikasi Anda tentang Kendaraan, Anda pasti akan mendapatkan 3000 baris spageti dalam file itu.

Ketika Anda memiliki pesan baru untuk dikirim, Anda memiliki setidaknya satu objek baru, dan mungkin sepasang objek. Jadi, dalam pertanyaan Anda tentang seikat metode, saya berpendapat bahwa Anda berpotensi berbicara tentang seikat pesan. Dan masing-masing bisa menjadi objeknya sendiri, dengan tugasnya sendiri. Dan itu tidak masalah. Ini akan menjadi jelas ketika Anda memisahkan hal-hal mana yang benar-benar perlu disatukan. Dan Anda menyatukannya. Tetapi Anda tidak segera menjatuhkan setiap metode di laci yang samar-samar sesuai untuk kenyamanan jika Anda ingin menikmati OO.

Mari kita bicara tentang sekumpulan fungsi

Objek dapat berupa kumpulan metode dan masih menjadi OO, tetapi "aturan" saya cukup ketat.

  1. Koleksinya harus memiliki satu tanggung jawab, dan tanggung jawab itu tidak boleh sebesar generik seperti "Melakukan barang untuk motor". Saya mungkin melakukan hal semacam itu sebagai fasad lapisan layanan, tetapi saya sangat sadar bahwa saya malas untuk alasan navigasi / penemuan, bukan karena saya mencoba menulis kode OO.

  2. Semua metode harus pada lapisan abstraksi yang konsisten. Jika satu metode mengambil objek Motor dan yang lain mengembalikan Horsepower, itu mungkin terlalu jauh.

  3. Objek harus bekerja pada "jenis" data yang sama. Objek ini melakukan hal-hal untuk motor (mulai / berhenti), yang ini melakukan hal-hal dengan panjang engkol, yang satu ini menangani urutan pengapian, yang ini mengambil bentuk html. Data ini dapat berupa bidang pada objek dan itu akan tampak kohesif.

Saya biasanya membangun objek semacam ini ketika saya melakukan transformasi, komposisi, atau hanya tidak ingin khawatir tentang mutabilitas.

Saya menemukan fokus pada tanggung jawab objek membawa saya ke arah kohesi. Harus ada suatu kohesi untuk menjadi objek, tetapi tidak perlu ada bidang atau perilaku yang terlalu banyak untuk menjadi objek. Jika saya sedang membangun sistem yang membutuhkan 5 metode motor itu, saya akan mulai dengan 5 objek berbeda yang melakukan hal-hal itu. Ketika saya menemukan kesamaan, saya akan mulai menggabungkan hal-hal bersama atau menggunakan benda-benda "pembantu" yang umum. Itu memindahkan saya ke masalah terbuka / tertutup - bagaimana saya bisa mengekstrak sedikit fungsionalitas ini sehingga saya tidak perlu memodifikasi file tertentu lagi tetapi masih menggunakannya di mana diperlukan?

Objek adalah tentang pesan

Bidang nyaris tidak berarti bagi suatu objek - mendapatkan dan mengatur register tidak mengubah dunia di luar program. Berkolaborasi dengan objek lain menyelesaikan pekerjaan. Namun, kekuatan OO adalah kita dapat membuat abstraksi sehingga kita tidak harus memikirkan semua detail individu sekaligus. Abstraksi yang bocor atau tidak masuk akal bermasalah, jadi kami berpikir secara mendalam (terlalu banyak, mungkin) tentang membuat objek yang cocok dengan model mental kita.

Pertanyaan kunci: Mengapa kedua benda ini perlu berbicara satu sama lain?

Pikirkan objek tersebut sebagai organ dalam diri seseorang - ia memiliki tujuan default dan hanya mengubah perilaku ketika menerima pesan tertentu yang ia pedulikan.

Bayangkan sebuah skenario di mana Anda berada di penyeberangan dan sebuah mobil melaju kencang. Sebagai objek otak, saya mendeteksi stresor. Saya memberi tahu hipotalamus untuk mengirim hormon pelepas kortikotropin. Kelenjar hipofisis mendapatkan pesan itu dan melepaskan hormon kortikotrofik adrenal. Kelenjar adrenal mendapatkan pesan itu dan membuat adrenalin. Ketika objek otot mendapatkan pesan adrenalin itu berkontraksi. Ketika hati menerima pesan yang sama, jantung berdetak lebih cepat. Ada seluruh rantai pemain yang terlibat dalam memulai perilaku kompleks berlari di seberang jalan dan itu adalah pesan yang penting. Objek otak tahu bagaimana membuat hipotalamus mengirimkan peringatan, tetapi tidak tahu rantai benda yang pada akhirnya akan membuat perilaku terjadi. Demikian juga hati tidak tahu dari mana adrenalin berasal,

Jadi, dalam contoh ( disederhanakan ) ini, objek kelenjar adrenal hanya perlu tahu cara mengambil ACTH dan membuat adrenalin. Tidak perlu bidang apa pun untuk melakukan itu, namun masih tampak seperti objek bagi saya.

Sekarang jika aplikasi kita dirancang hanya untuk berlari di seberang jalan, aku mungkin tidak membutuhkan kelenjar pituitari dan objek kelenjar adrenal. Atau saya hanya perlu objek kelenjar pituitari yang hanya melakukan sebagian kecil dari apa yang secara konseptual kita lihat sebagai "model kelenjar pituitari". Semua konsep ini ada sebagai entitas konseptual, tetapi merupakan perangkat lunak dan kita dapat membuat AdrenalineSender atau MuscleContractor atau apa pun dan tidak terlalu khawatir tentang "ketidaklengkapan" model kami.

Steve Jackson
sumber
4
Saya setuju dengan isi sebenarnya dari jawaban ini, tetapi saya merasa seperti itu salah paham pertanyaan. Secara khusus, pertanyaan termasuk dalam entitas "atau konsep, sesuatu yang didefinisikan dengan baik". Contoh tandingan untuk ini adalah " MotorOperationsatau MotorActions". Dari sini, saya cukup yakin bahwa baik desain kelas asli dan akhir dari contoh CoffeeMaker berada di bawah definisi OP tentang "mewakili suatu entitas"
Ben Aaronson
1
Arsitektur sistem postmodern DCI menangani ini tanpa abstraksi ekstrem yang diciptakan oleh insinyur yang mencintai struktur. Komputer harus memikirkan apa yang dipikirkan pengguna, bukan sebaliknya. fulloo.info/doku.php?id=what_is_dci
ciscoheat
@BenAaronson Saya merasa seperti Anda dapat berevolusi ke objek itu sebagai konsep kohesif dengan upaya yang cukup terpadu, tetapi saya telah menemukan kecenderungan untuk fokus entitas untuk memaksa hal-hal bersama yang harus terpisah. Entitas mendorong batasan atas nama kami, yang baik, tetapi mereka juga membawa gagasan tentang kebenaran / kelengkapan, yang cenderung menyakitkan. Dalam istilah yang paling konyol, saya untuk objek FirstNameValidator dan terhadap objek Nama yang juga melakukan validasi untuk nama depan dan belakang.
Steve Jackson
2
Objek adalah tentang pesan - jawaban Steve Jackson - ini benar sekali. MOP bukanlah apa yang dimaksud dengan "pesan" seperti yang dikandung oleh The Father of OO Alan Kay yang mengatakan ide besarnya adalah pengiriman pesan . Dan lebih jauh, saya minta maaf karena saya telah lama menciptakan istilah "objek" untuk topik ini karena membuat banyak orang fokus pada ide yang lebih rendah.
radarbob
21

Bisakah kelas mewakili objek tanpa entitas? Jika tidak, mengapa mereka buruk / tidak lengkap / non-OOP-sentris? Apakah ada cara yang perlu diubah / ditingkatkan?

Singkatnya, Anda dapat melakukan apa saja, tetapi skenario khusus ini akan bertentangan dengan prinsip OOP :)

Apa yang Anda gambarkan kadang-kadang disebut kelas "utilitas" - biasanya merupakan tanda dari bau kode. Anda ingin menghindari membuat kelas demi menjaga beberapa metode bersama.

Tidak setiap objek dalam aplikasi Anda harus ditautkan ke entitas kehidupan nyata seperti motor, atau mobil; itu adalah objek bisnis. Dalam aplikasi Anda, Anda cenderung menggunakan banyak objek bisnis Anda, tetapi Anda juga akan memerlukan beberapa pemisahan lagi untuk operasi lain yang bukan bagian dari entitas bisnis, seperti yang Anda daftarkan.

Anda harus melihat pola arsitektur umum - salah satunya adalah MVC (Model-View-Controller) .

Jika saya mendistribusikan metode yang Anda daftarkan menggunakan MVC, berikut adalah apa yang akan saya lakukan:

Lihat Kelas:

  • GetMotorDataFromHTMLForm ()

Kelas Model (Terutama Motor):

  • GetMotorManufacturer ()
  • CanMotorHandleOperationConditions ()
  • CalculatePowerConsumption ()

Kelas Pengendali (MotorsController):

  • GetAllMotors ()
  • GetMotorById ()
  • GetMotorByUserRequirements ()

Sepertinya Anda menggunakan PHP; kerangka kerja MVC yang bagus untuk dilihat adalah Laravel . Dalam contoh mereka, mereka menggambarkan dengan baik di mana metode apa milik

Sumber informasi lain yang lebih umum tentang cara memutuskan di mana metode tersebut berada adalah prinsip GRASP dan SOLID .

Alexus
sumber
Terima kasih. Pada intinya, tampak bagi saya bahwa apa yang saya miliki adalah kelas Controller dengan beberapa kotoran tercampur (Model, View, dll). Apakah itu berarti bahwa jika saya mengubah nama MotorOperationsuntuk MotorsControllerdan membersihkannya sedikit, saya koleksi fungsi akan sejalan dengan OOP?
Dennis
@ Dennis, Belum tentu, lihat koleksi metode saya di bawah setiap kelas. Kontroler bukan kelas yang berisi semuanya :) Kelas yang beroperasi pada model Anda, dan tidak lebih. Satu-satunya dependensi pengontrol umumnya adalah DAL (Lapisan Akses Data) secara langsung, atau layanan yang memberi Anda akses ke DAL. Anda tidak pernah ingin mengakses View dari controller (contoh: getMotorDataFromHTMLForm), sebagai gantinya, View Anda harus menjadi yang bergantung pada controller.
Alexus
2
Bisakah Anda menguraikan mengapa Utilskelas akan menjadi contoh bau kode? Hanya ingin tahu, karena saya sendiri menikmati menikmati fungsi-fungsi util acak yang dibungkus dalam Utilskelas yang bertentangan dengan hanya menjadi fungsi yang berdiri sendiri ... dalam pengalaman saya itu membuat kode sedikit lebih mudah dibaca, tetapi pengalaman saya terbatas.
HC_
3
@HC_ Memiliki kelas Utils sama dengan memiliki folder "Lain-lain" dalam koleksi gambar Anda. Ini menunjukkan bahwa Anda malas untuk menetapkan tanggung jawab pada objek Anda dengan benar / berpotensi kehilangan objek dan menggunakan Utils untuk mengimbanginya. Ada ruang untuk kelas Util, terutama dengan fungsi statis, dan ekstensi ke kelas lain, tetapi sebelum Anda membuat koleksi seperti itu, periksa apakah Anda dapat memasukkannya ke dalam kelas OOP yang tepat :) Alasan lain terkadang kelas hanya dapat memiliki satu metode. Tapi ke depan, Anda perlu menambahkan lebih banyak dan kelas Utils menjadi kekacauan yang lebih besar.
Alexus
Saya sering berakhir dengan Utils PERPUSTAKAAN, tetapi saya biasanya mencoba untuk mengelompokkan dan memberi nama kelas-kelas utils saya sedikit lebih deskriptif. Saat ini, ada banyak perpustakaan open source "utilitas umum" di luar sana yang sudah memiliki utilitas keperluan umum yang dibutuhkan sebagian besar orang, jadi saya akan melihat-lihat sedikit sebelum menulis milik Anda sendiri.
Guy Schalnat
15

Bisakah kelas mewakili objek tanpa entitas?

Bisa? Iya. Harus? Mungkin tidak - atau setidaknya, bukan bagaimana Anda mengutarakan sesuatu.

Objek sebenarnya adalah yang terbaik ketika tidak mewakili objek fisik secara langsung karena kenyataan sehingga jarang memetakan dengan baik ke kode. Tetapi mereka perlu mewakili konsep kohesif atau objek kode. Mereka perlu mewakili satu tanggung jawab kohesif.

Hanya bundling sekelompok fungsi terkait tangensial bersama adalah namespace atau modul - bukan objek dalam bahasa OOP. Itu bisa bermanfaat, tetapi tidak sama, dan membutuhkan jenis penggunaan / pemikiran yang berbeda untuk bekerja secara efektif.

Telastyn
sumber
3
bundling a bunch of tangentially related functions together is a namespace: itu lebih mirip paradigma prosedural daripada berorientasi objek.
Dennis
@dennis - persis (atau fungsional jika Anda menyebutnya Modul). Paradigma pencampuran bisa jadi kuat. Atau bisa sangat berantakan.
Telastyn
Atau keduanya :) - - - - -
Alexus
@ Dennis: Atau keduanya - menggabungkan satu-satunya fungsi yang berhubungan secara tangensial adalah praktik yang meragukan dalam paradigma apa pun.
sdenham
Saya berurusan dengan kode yang dimulai sebagai basis kode prosedural. Pada titik tertentu upaya untuk mengubahnya menjadi OOD dibuat tetapi, sebagian besar kelas diciptakan untuk "menyimpan fungsi dan metode", tanpa desain OO yang sebenarnya. Saya telah menemukan beberapa hal seperti ini yang mencoba menjembatani kesenjangan antara paradigma tetapi tidak dalam satu atau yang lain
Dennis
11

Kelas harus memodelkan sesuatu - jika tidak, tidak ada gunanya. Namun, apa yang dimodelkan mungkin bukan "benda" fisik; sebagai gantinya, itu mungkin merupakan representasi dari sesuatu yang tidak 'nyata', tetapi yang diperlukan untuk mengendalikan sistem yang dimodelkan. Misalnya, dalam sistem kontrol lampu lalu lintas Anda bisa memiliki semacam kelas ControlSignal, mewakili sinyal yang dikirim dari satu bagian sistem ke yang lain untuk menunjukkan bahwa beberapa tindakan perlu dilakukan. Dalam "dunia nyata", sinyal-sinyal ini mungkin terdiri dari impuls listrik yang dikirim melalui kabel dari satu kotak ke kotak lainnya. Proses pemodelan sesuatu yang tidak "nyata" sebagai objek konkret disebut sebagai "reifikasi".

Semoga berhasil.

Bob Jarvis
sumber
Ya, itu hampir persis seperti yang saya katakan. Kelas tidak lebih dari model untuk kata benda . Itu dia. Tidak lebih, tidak kurang. Kelas adalah kata benda, dan metode adalah kata kerja (atau pesan jika Anda mau). Seorang insinyur yunior yang berpikir dalam istilah-istilah sederhana itu dapat pergi jauh sebelum analogi-analogi itu rusak (tidak seperti mencoba berpura-pura bahwa kelas adalah deskripsi benda-benda fisik - sebuah analogi yang mulai runtuh pada hampir proyek pertama Anda).
Calphool
7

Tidak. (Judul diedit untuk menanyakan pertanyaan sebaliknya!)

misalnya:

Public class MyRepository
{
    public MyObject GetObject(string id)
    {
        //get data from the DB and build an object
    }
}

atau

Public class MyService
{
    public MyObject3 ProcessData(MyObject1 obj1, MyObject2 obj2)
    {
         //perform a process which is not a sole responsiblity of obj1 or obj2
    }
}

Namun, secara umum ideal di balik OOP adalah untuk menjauh

public struct Car
{
    public Wheel[] Wheels;
}

public int CountWheelsOnCar(MyCarStruct car)
{
   return car.Wheels.Length;
}

untuk

public class Car
{
    private Wheel[] wheels;
    Public int CountWheels()
    {
        return this.wheels.Length;
    }
}
Ewan
sumber
Apakah maksud Anda bahwa mereka dapat mewakili objek tanpa entitas? (Lihat komentar yang saya tinggalkan pada pertanyaan.)
Panzercrisis
3
Saya telah memprogram OO terlalu lama, saya kira - ketika saya melihat MyRepository, saya langsung membayangkan sebuah mangkuk kaca di lemari saya dengan seikat koin dan membuangnya. Jangkau dan ambil satu sen, atau tombol ....
Bill K
@pan ya, seperti layanan dan repo dalam contoh saya
Ewan
@bill Anda bodoh tua gila !!! Itulah kelas MyButtonAndOrPennyBowl! clean coding ftw
Ewan
1
Contoh kedua Anda terlihat seperti fungsi yang didandani sebagai objek, yang menurut saya tidak dibenarkan untuk kepentingannya sendiri, meskipun mungkin ada beberapa pembenaran lain (misalnya jika fungsi bukan entitas kelas satu dalam bahasa tersebut. )
sdenham
5

Saya pikir memvisualisasikan sesuatu di dunia nyata sangat membantu ketika mengkodekan kelas tetapi tidak perlu.

Faktanya, tergantung pada seberapa literal yang Anda inginkan, banyak objek yang bekerja dengan kami tidak memiliki representasi fisik sama sekali. Misalnya - pertimbangkan arsitektur MVC. Di dunia nyata tidak ada Model atau Pengendali meskipun mereka umumnya diwakili oleh kelas. Tiga bersama sering mewakili sesuatu, tetapi tidak selalu - tetapi seperti yang saya katakan Anda mungkin bisa memaksakan kecocokan menjadi sesuatu jika Anda benar-benar ingin (dan mampu membayangkan SESUATU membantu! Saya memvisualisasikan sebagian besar objek dengan cara tertentu - hanya saja tidak apa-apa Anda akan pernah melihat di dunia nyata).

Sebagian besar "Aturan" yang akan Anda pelajari tentang OO ini hanyalah pedoman yang dimaksudkan untuk membuat Anda berorientasi pada pemikiran dalam OO, belum tentu hal-hal yang sangat Anda khawatirkan begitu Anda menggunakannya untuk kode setiap hari.

Ngomong-ngomong, OO itu sendiri bukan obat mujarab dan itu tidak banyak membantu Anda sama sekali saat lulus pertama Anda dalam coding beberapa solusi, tapi saya pikir jika dilakukan dengan benar itu adalah cara yang benar-benar fantastis untuk mengatur kode sehingga bisa lebih mudah dipahami nanti. Menulis kode yang dapat dipelihara mungkin merupakan salah satu tugas tersulit dalam pengembangan perangkat lunak dan dalam banyak kasus (apa pun yang memerlukan debugging / pemeliharaan yang sedang berlangsung) itu sejauh ini yang paling penting.

Bill K
sumber
5

Apakah suatu objek harus mewakili suatu entitas?

Pertanyaan: Entitas mana yang Loggerdiwakili?

Tidak secara metaforis - secara harfiah.

Ketika menjelaskan OOP kepada siswa, akan sangat membantu untuk menjelaskan objek dengan analogi dengan dunia fisik.

Alan Kay - salah satu bapak OOP - menulis sebagai berikut:

[...]

Konsepsi orisinilnya memiliki bagian-bagian berikut.

  • Saya memikirkan benda yang seperti sel biologis dan / atau komputer individu pada jaringan, hanya dapat berkomunikasi dengan pesan
  • Saya ingin menyingkirkan data.

[...]

OOP bagi saya berarti hanya olahpesan, penyimpanan lokal dan perlindungan dan

menyembunyikan proses negara, dan sangat mengikat semua hal.

arsitektur HW hampir tidak bisa dipercaya. Saya menyadari bahwa itu

metafora sel / seluruh komputer akan menghilangkan data

sumber

Dari ini, objek dipahami sebagai

  • objek autarkik mengenkapsulasi / menyembunyikan data

  • berkomunikasi dengan objek lain melalui pesan

Bisakah kelas mewakili objek tanpa entitas?

Jelas: Pikirkan Math


Mengenai contoh Anda:

Contoh: dapat kelas disebut MotorOperations atau MotorActions, di mana tidak ada entitas, tetapi metode di dalam kelas melakukan hal-hal seperti

  • getMotorDataFromHTMLForm ()

  • getMotorManufacturers ()

  • selectMotorFromUserRequirements ($ persyaratan)

  • canMotorCanHandleOperatingConditions ($ conditions)

  • computePowerConsumptionForMotor ($ id)

Untuk memutuskan, di mana harus meletakkan metode ini, Anda harus melihat responsibilities: siapa yang bertanggung jawab untuk apa .

getMotorDataFromHTMLForm ()

Konteks metode semacam itu adalah membangun objek motorik . Bukan tanggung jawab motor untuk membuat sendiri dari Data yang diambil melalui formulir . Setidaknya ada dua objek yang terlibat; satu adalah motor dan yang lainnya adalah pencipta motor .

getMotorManufacturers ()

Konteks khas di mana seseorang akan menulis metode seperti itu adalah a service.

selectMotorFromUserRequirements ($ persyaratan)

Ini juga akan digunakan dalam service-context

canMotorCanHandleOperatingConditions ($ conditions)

Ini adalah pertanyaan untuk motor-object

computePowerConsumptionForMotor ($ id)

Ini juga pertanyaan terbaik yang diajukan motor itu sendiri.


tl; dr

Metafora objectssebagai objek fisik lebih menjengkelkan daripada membantu.

Thomas Junk
sumber
wow jawaban Anda menghembuskan kehidupan ke dalam OOP! Saya harus mengatakan bahwa saya tidak bermaksud fisik untuk mengakhiri semuanya. maksud pertanyaan saya adalah lebih "apakah objek harus thingdengan data di mana data jelas milik hal dan fungsi yang jelas beroperasi pada data yang milik benda". Jadi Logger dalam hal ini, meskipun bukan hal fisik, itu adalah konsep yang mirip dengan "buku log fisik". Apakah memiliki data yang merupakan inti dari kondisinya, dan tidak hanya bersifat sementara, itu mungkin tergantung pada implementasi dan interpretasi .. dan lebih dari itu kemana pertanyaan saya akan pergi ..
Dennis
tetapi ya, jawaban harus ditujukan pada bias fisik saya
Dennis
3

Ya, Anda bisa melakukan ini. Tetapi pada dasarnya Anda membuat kelas untuk menyediakan fungsionalitas yang sama dengan pustaka prosedural. Satu-satunya alasan untuk melakukan itu adalah jika bahasa Anda tidak memiliki modul prosedural (misalnya, Java atau Ruby).

Dalam bahasa dengan modul prosedural (saya pikir PHP memiliki modul prosedural), Anda dapat mempertimbangkan hanya menggunakan modul prosedural.

Anda juga bisa mempertimbangkan mendesain ulang kelas Anda sehingga instance kelas mewakili objek yang koheren.

Tetapi hanya gunakan notasi OO ketika memberi Anda kekuatan ekstra, tidak hanya demi menjadi OO!

Jonathan Cast
sumber
3

Dalam kata-kata awam

  • Apa yang Anda gambarkan disebut kelas utilitas.
  • Ini tidak memiliki keadaan, berarti Anda tidak akan pernah benar-benar perlu memiliki beberapa contoh itu
  • Semua metode bersifat statis, artinya Anda harus melewati semuanya sebagai parameter

Kelas-kelas semacam itu memang ada, misalnya Java SDK memiliki kelas Koleksi yang secara eksklusif terdiri dari metode statis yang beroperasi pada atau mengembalikan koleksi.

Jadi jawabannya adalah tidak, tidak semua kelas perlu dimodelkan dari entitas domain.

Di sisi lain, kelas-kelas semacam itu hanya beberapa atau seharusnya hanya sedikit dalam program yang dibuat dalam bahasa OOP, karena kekuatan OOP yang sebenarnya terletak pada polimorfisme dan enkapsulasi.

Itu akan seperti menggunakan pesawat untuk pergi dari satu tempat ke tempat lain bukan dengan terbang tetapi dengan mengendarainya di sekitar jalan raya. Pesawat memiliki roda seperti mobil, tetapi dimaksudkan untuk terbang.

Tulains Córdova
sumber
2

Tidak, kelas hanya mewakili sesuatu yang dapat dipakai, memiliki anggota, dan dapat diwarisi dari.

Bahkan, bahasa Anda mungkin memiliki kelas statis, yang bahkan tidak dipakai lebih dari satu kali.

.NET'sMath adalah contoh yang bagus dari kelas "profesional" yang tidak mewakili entitas (kecuali jika Anda ingin mendapatkan filosofi tentang apa itu matematika ...), dan juga menggambarkan kasus penggunaan yang sah dari kelas semacam itu. Ini hanya memiliki metode dan 2 bidang (keduanya mewakili konstanta individu).

Hirarki kelas dari perpustakaan yang sama Math.Net,, mengelompokkan metode matematika / numerik ke dalam kelas berdasarkan tipe. Di sini kelas mewakili bukan entitas, tetapi kategori logis.

Saya sendiri sering berakhir dengan membuat kelas (statis) yang tidak lebih dari sekantong fungsi terkait (statis), atau sekelompok konstanta yang dengan mudah dikelompokkan dalam satu tempat sentral. Saya tidak akan mengklaim bahwa ini adalah desain yang baik, tetapi kadang-kadang itu solusi yang paling mudah.

Hebat
sumber
1
Fakta bahwa metode yang berhubungan dengan matematika ditempatkan di .NET / BCL ke dalam kelas yang terpisah sebagai metode statis bukanlah suatu keharusan atau pertimbangan desain tetapi konsekuensi dari kenyataan bahwa tidak ada metode yang berdiri sendiri dalam C #. Dalam C ++ fungsi-fungsi seperti itu bisa saja dikelompokkan ke dalam namespace.
Vlad
1

Jawaban atas pertanyaan Anda pada akhirnya bergantung pada seberapa tepatnya seseorang mendefinisikan istilah seperti "kelas" dan "entitas." Anda melakukan pekerjaan yang baik untuk mendefinisikan yang terakhir, memungkinkan entitas fisik dan konseptual. Tetapi istilah "kelas" untuk puritan akan selalu menjadi "pabrik untuk instantiasi objek dengan representasi internal tertentu" dan untuk pragmatis istilah tersebut akan mencakup hal-hal Jawa atau C ++ yang dibenci oleh puritan. Ditto untuk istilah "OOP," yang mungkin dikatakan oleh para pragmatis tentang Java dan C ++, tetapi para puritan mana yang akan berarti apa yang dimaksud Alan Kay ketika dia berkomentar ["Saya menemukan istilah berorientasi objek, dan saya dapat mengatakan kepada Anda bahwa saya tidak melakukannya. memiliki C ++ dalam pikiran "] ( Jadi * apa yang * Alan Kay benar-benar maksud dengan istilah" berorientasi objek "? ).

Jika Anda mengambil pandangan pragmatis, Anda dapat menerima kelas utilitas tanpa instance Anda. Namun pandangan purist lebih menarik. OOP, menurut Kay, selalu lebih banyak tentang pesan daripada kelas. Jadi untuk pertanyaan Anda:

Bisakah kelas mewakili objek tanpa entitas?

Kelas mengklasifikasikan objek. Kelas menurut definisi entitas yang Anda kirimi pesan seperti newuntuk menghasilkan objek. Objek adalah entitas yang dibuat dari kelas. Kelas ada untuk memproduksi, dan memang mengklasifikasikan, objek. Itu yang dilakukan kelas. Kelas membuat objek. Kami menggunakan kelas untuk mengklasifikasikan objek. Jadi, jika C hanyalah kumpulan metode yang tidak mengizinkan instantiasi atau subkelas, tidak mungkin ada objek yang diklasifikasikan oleh C, jadi C bukan kelas.

Jika tidak, mengapa mereka buruk / tidak lengkap / non-OOP-sentris?

Itu tidak buruk. Hanya saja, jangan sebut mereka kelas. Satu bundel metode adalah OOPable: sesuatu yang bisa Anda kirimi pesan untuk memanggil suatu metode, tetapi itu bukan kelas kecuali ia bisa membuat instance objek. Apakah Anda kenal Ruby? Di Ruby modul adalah kumpulan metode. Sebuah kelas adalah modul yang dapat instantiate objek. Tidak ada yang buruk tentang modul . Tetapi hal yang membuat kelas berbeda dari modul (dalam istilah OOP murni) adalah bahwa kelas dapat memiliki instance. Modul hanyalah beberapa metode. Kebingungannya adalah bahwa C ++ dan Java dan bahasa lain menggunakan istilah "kelas" untuk kelas dan modul .

Sekarang, untuk melihat salah satu contoh spesifik Anda, Anda bertanya tentang MotorOperationskelas di mana Anda dapat mengirim pesan computePowerConsumptionForMotordengan argumen id. Apakah itu buruk? Setidaknya itu tidak melanggar Prinsip Tell Don't Ask . Apakah kita harus membuat kelas motor dan mengirimkannya powerConsumptionpesan? Mungkin tidak 100% dari waktu, tetapi mungkin mencoba melakukan hal-hal seperti itu akan menyebabkan beberapa wawasan yang bagus tentang kode Anda. Atau, itu dapat menyebabkan ledakan kelas kecil yang akan menjadi buruk.

Apakah ada cara mereka perlu diubah / ditingkatkan secara konseptual agar sejalan dengan OOP?

Jika "melakukan OOP" penting bagi Anda, maka Anda perlu mencari cara untuk merancang sistem menjadi komponen yang berkomunikasi dengan mengirim pesan satu sama lain. Itu hanya apa OOP adalah , atau setidaknya apa yg berfantasi saja istilah yang ada dalam pikiran. Kelas utilitas bukan OOP dalam tampilan ini. Tetapi bagi sebagian orang, mereka mungkin saja demikian.

Mencoba membuat keseluruhan sistem besar dari jutaan makhluk hidup, pernapasan, benda, semuanya berasal dari kelas, dapat bekerja untuk beberapa proyek. Tetapi jika Anda menemukan diri Anda membuat kelas buatan, salah terdengar, maka modul harus diperkenalkan. Cobalah untuk menekankan kelas, dan gunakan modul ketika kelas yang tidak berguna akan konyol.

Bundel TL; DR - metode tidak selalu buruk. Cobalah untuk menggunakan kelas instantiable terlebih dahulu. Kembali ke "modul" hanya bila diperlukan.

Ray Toal
sumber
0

Mengambil contoh yang diberikan:

getMotorDataFromHTMLForm()
selectMotorFromUserRequirements($requirements)

Ini terlihat seperti metode "pabrik", yang akan mengembalikan Motorobjek. Yang kedua menyiratkan bahwa Anda sedang membuat objek baru untuk memenuhi persyaratan, atau Anda memiliki database atau koleksi motor dalam memori yang sedang Anda periksa. Dalam hal ini harus menjadi metode untuk itu. Atau bisa juga metode pada objek persyaratan.

getMotorManufacturers()

Dari mana Anda mendapatkannya? Itulah yang seharusnya menjadi metode.

canMotorCanHandleOperatingConditions($conditions)
computePowerConsumptionForMotor($id)

Ini sepertinya harus menjadi metode Motor.

pjc50
sumber
Iya. itu adalah "kumpulan metode yang mungkin tidak terkait" (BOPUM singkatnya). Saya setuju dengan komentar Pabrik dan Motor. getMotorManufacturersadalah mengembalikan semua pabrikan motor dari basis data. Saya tidak yakin ke mana perginya. Butuh beberapa waktu untuk mengungkap BOPUM ini untuk meletakkan barang-barang ke mana mereka harus pergi ..
Dennis
Saya dapatkan getMotorManufacturersdari Database. Basis data tidak dapat memiliki metode ... Saat ini saya memiliki pola DataMapper yang menanyakan basis data, menginisialisasi array, dan mengisinya dengan Motor Objects (juga berisi informasi Produsen), dan kemudian mengembalikan array itu ke pemanggil. Penelepon adalah MotorOperationskelas saya , yang pada gilirannya dipanggil dari ProductSelectionkelas (yang berisi algoritma yang digunakan untuk memilih Motors, dan informasi motor yang dimuat adalah data untuk algoritme itu)
Dennis
0

Objek adalah kumpulan metode dan data yang memiliki kohesi tinggi. Mereka termasuk dalam kelas karena mereka sangat saling terkait dan negara dipertahankan.

Ini benar apakah Anda menggunakan desain depan yang besar dan mencoba memodelkan segalanya, atau desain yang muncul di mana Anda beralih dan mengembangkan objek menjadi apa pun yang sesuai dengan kebutuhan sistem pada saat itu.

Jika Anda tidak memiliki alasan untuk mempertahankan status, Anda mungkin tidak memiliki alasan untuk membuat instance objek yang berarti mungkin tidak ada alasan untuk memiliki kelas. Kecuali, bahasa yang Anda gunakan tidak memiliki kemampuan untuk mendefinisikan namespace selain menggunakan kelas. Di mana menggunakan kelas harus baik-baik saja karena akan idiomatik.

Saya tidak bisa memikirkan aspek negatif untuk menggunakan kelas dengan cara ini selain tipikal. Biaya dan kerumitan mengundang Anda yang tidak perlu dengan harus membuat instantiate "namespace". Siapa pun yang mendukung kode ini akan bertanya-tanya di mana data ini menambah beban kognitif tambahan (kemungkinan besar biaya satu kali per orang). Ini adalah penggunaan yang tidak biasa tanpa nilai tambahan.

dietbuddha
sumber