Apakah pola ActiveRecord mengikuti / mendorong prinsip-prinsip desain SOLID?

43

Saya tertarik pada apakah pola ActiveRecord, yang dibuat terkenal dari Ruby on Rails, mendorong atau menghambat penggunaan prinsip-prinsip desain SOLID .

Sebagai contoh, menurut saya objek ActiveRecord mengandung logika domain, dan logika kegigihan, yang merupakan pelanggaran Single Responsibility.

nicholaides
sumber
6
Jim Weirich, di akhir SOLID Ruby Talk di Ruby Conference 2009, bertanya kepada hadirin: "Objek ActiveRecord menerapkan konsep domain dan konsep kegigihan. Apakah ini melanggar SRP (Prinsip Tanggung Jawab Tunggal)?" Penonton setuju bahwa itu melanggar SRP. Jim bertanya apakah ini mengganggu mereka. Banyak anggota audiens mengatakan ya. Mengapa? Itu membuat pengujian lebih sulit. Itu membuat objek kegigihan jauh lebih berat.
David J.

Jawaban:

56

Ada beberapa kritik valid pada ActiveRecord. Seperti biasa, Paman Bob menyimpulkannya dengan sempurna :

Masalah yang saya miliki dengan Rekaman Aktif adalah bahwa ia menciptakan kebingungan tentang dua gaya pemrograman yang sangat berbeda ini. Tabel database adalah struktur data. Ini telah membuka data dan tidak ada perilaku. Tetapi Rekaman Aktif tampaknya menjadi objek. Ini memiliki data "tersembunyi", dan perilaku terbuka. Saya menempatkan kata "tersembunyi" dalam tanda kutip karena data, pada kenyataannya, tidak disembunyikan. Hampir semua turunan ActiveRecord mengekspor kolom database melalui accessor dan mutator. Memang, Rekaman Aktif dimaksudkan untuk digunakan seperti struktur data.

Di sisi lain, banyak orang memasukkan metode aturan bisnis dalam kelas Rekaman Aktif mereka; yang membuatnya tampak seperti objek. Ini mengarah pada dilema. Di sisi baris mana Rekaman Aktif benar-benar jatuh? Apakah itu objek? Atau apakah itu struktur data?

Wikipedia meringkas kritik dalam masalah testability :

Dalam OOP konsep enkapsulasi sering bertentangan dengan konsep pemisahan keprihatinan. Secara umum, pola yang mendukung pemisahan masalah lebih cocok untuk uji unit terisolasi sementara pola yang mendukung enkapsulasi lebih mudah untuk menggunakan API. Rekaman Aktif sangat mendukung enkapsulasi ke titik di mana pengujian tanpa database cukup sulit.

Khusus untuk implementasi Ruby on Rails, Gavin King menulis (penekanan pada tambang):

Pada titik ini, sebagian besar pengembang berpikir um, ok, jadi bagaimana saya bisa tahu atribut apa yang dimiliki Perusahaan dengan melihat kode saya? Dan bagaimana IDE saya dapat melengkapinya? Tentu saja, orang-orang Rails memiliki jawaban cepat untuk pertanyaan ini. Oh, jalankan saja klien basis data Anda dan lihat di basis data !. Kemudian, dengan asumsi Anda tahu aturan kapitalisasi dan pluralisasi automagic dari ActiveRecord / dengan sempurna /, Anda akan bisa menebak nama-nama atribut dari kelas Perusahaan Anda sendiri, dan mengetiknya secara manual.

Juga tentang implementasi Ruby on Rails, John Januszczak menulis (penekanan saya):

MASALAH # 1: METODE STATIK

...

Beberapa orang akan mengatakan menggunakan metode Static hanya berjumlah pemrograman prosedural, dan karena itu desain Object Oriented buruk. Yang lain akan mengatakan metode statis adalah kematian untuk testabilitas.

MASALAH # 2: PENGATURAN KONFIGURASI GLOBAL

...

Oleh karena itu tidak ada injeksi ketergantungan pada kelas Akun dalam contoh saya, dan dengan ekstensi, pada instance Akun. Seperti yang harus kita ketahui sekarang, mencari hal-hal sangat, sangat buruk!

Beberapa sumber daya lebih lanjut tentang mengapa ActiveRecord dan ORM umumnya dianggap sebagai anti-pola:

ActiveRecord selalu terasa seperti anti-pola yang sangat berguna , tetapi saya setuju bahwa itu bertentangan dengan SRP dan juga bertentangan dengan prinsip inversi ketergantungan.

yannis
sumber
Pembaruan PENTING untuk rails 5+: "Dan bagaimana IDE saya dapat melengkapinya? Tentu saja, orang-orang Rails memiliki jawaban cepat untuk pertanyaan ini. Oh, jalankan saja klien basis data Anda dan lihat di database !." lagi. Dengan atribut API Anda dapat mendefinisikan semua kolom yang tersedia pada model
Filip Bartuzi
6

(Saya berasumsi bahwa kelas ActiveRecord diimplementasikan tanpa ada kemungkinan injeksi ketergantungan).

Dari pengalaman pribadi saya dapat mengatakan bahwa pola ActiveRecord menjadi hambatan utama untuk menulis tes unit. Penggabungan lapisan ketekunan dan logika bisnis dalam satu "kelas ActiveRecord" membuat tidak mungkin untuk menulis tes unit (kecuali jika Anda refactor terlebih dahulu). Oleh karena itu, satu-satunya pilihan adalah menulis tes integrasi; dan itu tidak seefektif tes unit. Ini menjadi masalah besar terutama jika Anda mengambil alih proyek dengan banyak kelas ActiveRecord; itu menghasilkan tes integrasi yang sangat rumit yang sulit dipertahankan.

Jadi, ActiveRecord datang cukup banyak terhadap SRP dan membuat beberapa sakit kepala pemeliharaan; tampaknya menghilangkan kekuatan untuk menulis unit-test.

Guven
sumber