Menjaga model MVC secara longgar digabungkan dari DB?

9

Saya suka menjaga kode saya dapat diuji dan telah memutuskan untuk pergi dengan strategi Dependency-Injection untuk kerangka kerja MVC saya saat ini, yang pasti telah terbukti menjadi cara yang bagus untuk memastikan kode yang digabungkan secara longgar, testability dan modularitas.

Tetapi sebagai jauh dari master di pola Desain, saya memiliki waktu yang sulit mencari cara yang baik untuk menjaga Model saya sebagai longgar digabungkan dari kelas konektor Database, mungkin.

Bagaimana ini bisa dilakukan?
Karena saya belum memberikan kode fisik apa pun bersama dengan pertanyaan ini, saya akan sangat menghargai beberapa contoh logika / kode atau info yang dapat mengarahkan saya ke arah untuk memahami masalah yang dijelaskan di atas.

Industri
sumber
Pertanyaan ini termasuk dalam Rekayasa Perangkat Lunak , karena lebih banyak tentang penataan dan pemikiran seputar topik ini, lebih dari itu tentang penerapannya dalam kode.
Lasse V. Karlsen

Jawaban:

6

Salah satu caranya adalah mendesain model Anda sebelum mendesain basis data Anda. Saat mendesain model Anda, fokusnya adalah menangkap logika bisnis dan makna dalam domain masalah. Ini harus ditangkap dengan cara yang masuk akal bagi bisnis, termasuk lebih dari sekadar entitas dan bidang data. Beberapa elemen data diinterpretasikan dari yang lain, beberapa bergantung pada yang lain, dll. Selain itu Anda akan menambahkan ke model ini setiap logika dasar yang Anda butuhkan, seperti bagaimana objek merespons secara internal ketika elemen tertentu diatur ke nilai tertentu.

Sangat mungkin bahwa Anda akan berakhir dengan sesuatu yang 90 +% identik dengan bagaimana Anda akhirnya mempertahankan data. Tidak apa-apa. Itu bisa sepenuhnya identik tanpa digabungkan.

Perhatikan juga bahwa memodelkan domain dalam kabut ketidaktahuan kegigihan sejati adalah sedikit grail suci untuk desain perangkat lunak. Jika Anda bisa melakukannya, fantastis. Tetapi jika domain masalah sama sekali signifikan dan memiliki kerumitan untuk itu maka itu masih merupakan ide yang baik untuk mundur dari pemodelan domain dari waktu ke waktu untuk melakukan pemeriksaan kewarasan pada ketekunan data untuk memastikan Anda belum melukis diri Anda ke sudut.

Ingat peran sebenarnya dari berbagai komponen dan pisahkan peran tersebut saat Anda mendesainnya. Untuk setiap keputusan desain yang diberikan, tanyakan pada diri Anda apakah ada peran yang dilanggar:

  1. Database - Menyimpan data, menjaga integritas data, menjaga data tetap diam.
  2. Model - Berisi logika bisnis, modelkan domain masalah, pertahankan data dalam gerakan, respons terhadap peristiwa di tingkat bisnis, dll.
  3. Tampilan - Sajikan data kepada pengguna, lakukan logika sisi pengguna (validasi dasar sebelum validasi sejati dilakukan dalam model, dll.).
  4. Pengendali - Menanggapi peristiwa pengguna, memberikan kontrol pada model, permintaan rute, dan mengembalikan respons.
David
sumber
Hai David. Terima kasih atas balasan Anda yang luas! Sementara mempertahankan kopling longgar tingkat tinggi, bagaimana Anda menghubungkan model dengan konektor basis data?
Industri
1
@Industrial: Ada sejumlah cara untuk menghubungkan model ke kegigihan, tetapi sejauh ini satu-satunya metode yang saya temukan yang benar-benar memuaskan keinginan saya untuk memisahkan masalah adalah memiliki antarmuka repositori dalam domain yang diterapkan secara eksternal oleh DAL. Metode repositori menerima dan mengembalikan model domain, dan secara internal mengkonversi antara mereka dan entitas database yang dihasilkan. (Sejujurnya, saya belum melakukan ini dalam PHP.) Jadi Anda dapat menggunakan kerangka kerja DAL untuk secara otomatis menghasilkan semua DB CRUD Anda, dll. Dan kemudian menulis repositori Anda sebagai antarmuka antara barang-barang itu dan model Anda.
David
@Industrial: Misalnya, jika Anda menggunakan ORM, maka ORM itu akan dirujuk oleh DAL Anda (yang diisolasi dari model domain) dan akan mengubah model Anda menjadi akses data yang sesuai. Atau jika Anda melakukan akses database langsung dengan SQL manual, Anda akan melakukannya dalam metode repositori DAL Anda dan menerjemahkan hasil query SQL ke dalam model domain sebelum mengembalikannya.
David
@Industrial: Perlu diingat juga bahwa metode repositori tidak harus hanya menjadi CRUD. Banyak kecerdasan dapat dimasukkan ke dalam kode itu. Banyak yang lebih kompleks dapat memiliki banyak kode internal yang mengubah data dari database. Atau, jika yang rumit melibatkan banyak perjalanan ke database, maka untuk keuntungan kinerja Anda dapat menempatkan logika dalam prosedur tersimpan dan metode DAL hanya lolos ke prosedur itu dan menerjemahkan hasilnya ke dalam model.
David
Hai David! Hanya ingin mengucapkan terima kasih lagi atas jawaban ini. Pasti salah satu yang terbaik yang saya terima di StackExchange!
Industri
2

Anda ingin memiliki dua hal.

  1. Model Anda (pengakses DBAL dan melakukan sebagian besar logika aplikasi).
  2. "Model Domain" Anda alias Entitas Data, ini mewakili entitas sistem Anda seperti pengguna, posting, produk, dll.

    class PPI_Model_User {
    
        protected $_conn = null;
    
        function __construct(array $options = array()) {
            if(isset($options['dsnData'])) {
                $this->_conn = new PPI_DataSource_PDO($options['dsnData']);
            }
        }
    
        function getAll() {
            $rows = $this->_connect->query("SELECT .....")->fetchAll();
            $users = array();
            foreach($rows as $row) {
                $users[] = new PPI_Entity_User($row);
            }
            return $users;
        }
    
    }

Kode Penggunaan

    $model = new PPI_Model_User(array('dsnData' => $dsnData));
    $users = $model->getAll();
    foreach($users as $user) {
        echo $user->getFirstName();
    }

Di sana Anda memilikinya, itulah cara Anda membuat model domain (Entitas) dan memiliki model MVC melakukan konektivitas DB dan manipulasi data.

Jika Anda bertanya-tanya apa itu PPI, cari "Kerangka Kerja PPI".

Semoga berhasil dengan pencarian Anda.

Salam, Paul Dragoonis.

Paul Dragoonis
sumber
1

Ingat, MVC muncul di smalltalk, yang memiliki kegigihan otomatis untuk semua objek. Jadi pola MVC tidak menentukan solusi untuk pemisahan model / kegigihan.

Preferensi saya adalah menyediakan objek "Repositori" yang tahu cara membuat objek Model dari database dan menyimpan objek Model ke database. Kemudian Model tidak tahu apa-apa tentang kegigihan. Namun beberapa tindakan pengguna harus memicu penyimpanan, jadi sepertinya Pengendali akan tahu tentang Repositori. Saya biasanya menggunakan beberapa bentuk Dependency Injection untuk menjaga Controller dari digabungkan ke Repositori.

Sean McMillan
sumber