Saya berasal dari Jawa, dan sekarang saya lebih banyak bekerja dengan Ruby.
Salah satu fitur bahasa yang saya tidak kenal adalah module
. Saya bertanya-tanya apa sebenarnya itu module
dan kapan Anda menggunakannya, dan mengapa menggunakan module
lebih dari satu class
?
Jawaban:
Jawaban pertama adalah baik dan memberikan beberapa jawaban struktural, tetapi pendekatan lain adalah memikirkan apa yang Anda lakukan. Modul adalah tentang memberikan metode yang dapat Anda gunakan di beberapa kelas - pikirkan tentang mereka sebagai "perpustakaan" (seperti yang akan Anda lihat di aplikasi Rails). Kelas adalah tentang objek; modul tentang fungsi.
Misalnya, sistem otentikasi dan otorisasi adalah contoh modul yang baik. Sistem otentikasi bekerja di beberapa kelas level aplikasi (pengguna diautentikasi, sesi mengelola otentikasi, banyak kelas lain akan bertindak secara berbeda berdasarkan status autentikasi), sehingga sistem otentikasi bertindak sebagai API bersama.
Anda mungkin juga menggunakan modul ketika Anda telah berbagi metode di beberapa aplikasi (sekali lagi, model perpustakaan baik di sini).
sumber
sumber
Saya terkejut ada yang belum mengatakan ini.
Karena penanya berasal dari latar belakang Jawa (dan saya juga), inilah analogi yang membantu.
Kelas hanya seperti kelas Java.
Modul seperti kelas statis Java. Pikirkan tentang
Math
kelas di Jawa. Anda tidak instantiate, dan Anda menggunakan kembali metode di kelas statis (mis.Math.random()
).sumber
extend self
), membuat metode mereka tersedia untukself
metaclass mereka. Ini memungkinkan untuk mengirim metode sepertirandom()
padaMath
modul. Tetapi pada dasarnya, metode modul tidak dapat dipanggil sendiriself
. Ini berkaitan dengan gagasan Ruby tentangself
metaclasses-nya, dan cara kerja metode pencarian. Lihat "Metaprogramming Ruby" - Paolo Perlotta untuk detailnya.Pada dasarnya, modul tidak dapat digunakan. Ketika kelas menyertakan modul, superclass proksi dihasilkan yang menyediakan akses ke semua metode modul serta metode kelas.
Modul dapat dimasukkan oleh beberapa kelas. Modul tidak dapat diwarisi, tetapi model "mixin" ini menyediakan jenis "pewarisan berganda" yang bermanfaat. OO purists akan tidak setuju dengan pernyataan itu, tetapi jangan biarkan kemurnian menghalangi pekerjaan.
(Jawaban ini awalnya ditautkan
http://www.rubycentral.com/pickaxe/classes.html
, tetapi tautan itu dan domainnya tidak lagi aktif.)sumber
extend
menggunakan kelas. Ruby sebenarnya tidak membedakan antara metode "instance" dan "class / static" sama sekali, hanya penerimanya saja.Module
di Ruby, pada tingkat tertentu, sesuai dengan kelas abstrak Java - memiliki metode instance, kelas dapat mewarisi darinya (viainclude
, orang-orang Ruby menyebutnya "mixin"), tetapi tidak memiliki instance. Ada perbedaan kecil lainnya, tetapi informasi sebanyak ini cukup untuk Anda mulai.sumber
namespace: modules adalah namespaces ... yang tidak ada di java;)
Saya juga beralih dari Java dan python ke Ruby, saya ingat punya pertanyaan yang persis sama ...
Jadi jawaban yang paling sederhana adalah modul itu adalah namespace, yang tidak ada di Java. Di java, pola pikir terdekat ke namespace adalah sebuah paket .
Jadi modul di ruby seperti apa di java:
class? Tidak ada
antarmuka? Tidak ada
kelas abstrak? Tidak ada
paket? Ya mungkin)
metode statis di dalam kelas di java: sama seperti metode di dalam modul di ruby
Dalam java, unit minimum adalah kelas, Anda tidak dapat memiliki fungsi di luar kelas. Namun dalam ruby ini mungkin (seperti python).
Jadi apa yang masuk ke modul?
kelas, metode, konstanta. Modul melindungi mereka di bawah namespace itu.
Tidak ada contoh: modul tidak dapat digunakan untuk membuat instance
Mixed ins: kadang model inheritance tidak baik untuk kelas, tetapi dalam hal fungsionalitas ingin mengelompokkan satu set kelas / metode / konstanta bersama-sama
Aturan tentang modul dalam ruby:
- Nama modul adalah UpperCamelCase
- konstanta dalam modul adalah SEMUA CAPS (aturan ini sama untuk semua konstanta ruby, tidak spesifik untuk modul)
- metode akses: gunakan. operator
- konstanta akses: gunakan :: simbol
contoh sederhana dari sebuah modul:
cara menggunakan metode di dalam modul:
cara menggunakan konstanta modul:
Beberapa konvensi lain tentang modul:
Gunakan satu modul dalam file (seperti kelas ruby, satu kelas per file ruby)
sumber
Intinya: Modul adalah persilangan antara kelas statis / utilitas dan mixin.
Mixin adalah bagian implementasi "parsial" yang dapat digunakan kembali, yang dapat digabungkan (atau disusun) dengan cara mix & match, untuk membantu menulis kelas baru. Kelas-kelas ini juga dapat memiliki status dan / atau kode sendiri.
sumber
Kelas
Saat Anda mendefinisikan kelas, Anda menentukan cetak biru untuk tipe data. class hold data, memiliki metode yang berinteraksi dengan data itu dan digunakan untuk instantiate objek.
Modul
Modul adalah cara pengelompokan bersama metode, kelas, dan konstanta.
Modul memberi Anda dua manfaat utama:
=> Modul menyediakan namespace dan mencegah bentrokan nama. Namespace membantu menghindari konflik dengan fungsi dan kelas dengan nama yang sama yang telah ditulis oleh orang lain.
=> Modul menerapkan fasilitas mixin.
sumber
Pertama, beberapa kesamaan yang belum disebutkan. Ruby mendukung kelas terbuka, tetapi modul juga terbuka. Bagaimanapun, Kelas mewarisi dari Modul dalam rantai warisan Kelas dan sehingga Kelas dan Modul memiliki beberapa perilaku serupa.
Tetapi Anda perlu bertanya pada diri sendiri apa tujuan memiliki Kelas dan Modul dalam bahasa pemrograman? Kelas dimaksudkan untuk menjadi cetak biru untuk membuat instance, dan setiap instance adalah variasi realisasi cetak biru. Sebuah instance hanyalah variasi yang disadari dari cetak biru (Kelas). Tentu saja, Kelas berfungsi sebagai objek penciptaan. Selain itu, karena kami terkadang ingin satu cetak biru berasal dari cetak biru lain, Kelas dirancang untuk mendukung warisan.
Modul tidak dapat dipakai, tidak membuat objek, dan tidak mendukung warisan. Jadi ingat satu modul TIDAK mewarisi dari yang lain!
Jadi apa gunanya memiliki Modul dalam bahasa? Salah satu penggunaan Modul yang jelas adalah untuk membuat namespace, dan Anda akan melihat ini dengan bahasa lain juga. Sekali lagi, apa yang keren tentang Ruby adalah Modul dapat dibuka kembali (seperti halnya Kelas). Dan ini adalah penggunaan besar ketika Anda ingin menggunakan kembali namespace dalam file Ruby yang berbeda:
Tetapi tidak ada warisan antar modul:
Modul Apple tidak mewarisi metode apa pun dari modul Hijau dan ketika kami memasukkan Apple dalam kelas Buah, metode modul Apple ditambahkan ke rantai leluhur instans Apple, tetapi bukan metode modul Green, meskipun Green Modul didefinisikan dalam modul Apple.
Jadi bagaimana kita mendapatkan akses ke metode hijau? Anda harus secara eksplisit memasukkannya ke dalam kelas Anda:
Tetapi Ruby memiliki penggunaan penting lainnya untuk Modul. Ini adalah fasilitas Mixin, yang saya jelaskan dalam jawaban lain pada SO. Tetapi untuk meringkas, mixin memungkinkan Anda untuk mendefinisikan metode ke dalam rantai objek warisan. Melalui mixin, Anda bisa menambahkan metode ke rantai turunan instance objek (termasuk) atau singleton_class of self (extended).
sumber