Model MVC-də necə qurulmalıdır?

Mən MVC-nin strukturunu anlayıram və tez-tez modelə daxil olmaq üçün nə qədər kodu girməyini merak edərəm. Mən belə üsulları olan məlumatlara giriş sinifinə malik olmağı bacarıram:

 public function CheckUsername($connection, $username) { try { $data = array(); $data['Username'] = $username; //// SQL $sql = "SELECT Username FROM" . $this->usersTableName . " WHERE Username = :Username"; //// Execute statement return $this->ExecuteObject($connection, $sql, $data); } catch(Exception $e) { throw $e; } } 

Mənim modellərim ümumiyyətlə bir verilənlər bazası masasına təsnif olunan bir müəssisə sinfidir.

Model obyekti bütün verilənlər bazası Xəritəçəkmə xüsusiyyətlərinə, eləcə də yuxarıdakı kodlara malik olmalı və ya həqiqətən verilənlər bazasında işləyən bu kodu ayırmaq normaldırmı?

Sonda dörd qatım var?

510
03 мая '11 в 3:28 2011-05-03 03:28 Dietpixel 03 may 2011-ci il tarixdə 3: 28-də təyin olunub. 2011-05-03 03:28
@ 5 cavab

Disclaimer: PHP-based web applications kontekstində MVC kimi nümunələri necə başa düşdüyümdən aşağıdakı təsviri. Məzmunda istifadə olunan bütün xarici əlaqələr şərtləri və konsepsiyaları izah etmək üçün nəzərdə tutulub və bu məsələdə öz etibarlılığımı nəzərdə tutmur.

Mənə aydınlıq gətirmək üçün lazım olan ilk şey modelin bir qat olmasıdır .

İkincisi: klassik MVC və web inkişafı ilə nə arasında fərq var. Burada yazdığım bir neçə cavan cavablar, qısaca necə fərqləndiklərini təsvir edir.

Nə model deyil?

Model bir sinif və ya hər hansı bir obyekt deyil. Bu çox yaygın bir səhvdir (mən də mənə başqa cür öyrənməyə başladığımda orijinal cavab yazılmış olmasına baxmayaraq), əksər çərçivələr bu yanlışlığı davam etdirir.

Bu da bir obyekt-relational mapping (ORM) metodu və verilənlər bazası masalarının bir abstraksiyasıdır. Bunu söyləyən hər kəs, ehtimal ki, tamamilə yeni bir ORM və ya bütün infrastrukturu satmağa çalışır.

Hansı model:

Müvafiq uyğunlaşma şəraitində, MVC M domenin bütün biznes məntiqlərini ehtiva edir və model qat əsasən üç növ strukturdan ibarətdir:

  • Domain obyektləri

    Domen obyekti təmiz domain məlumatının məntiqi bir konteyneridir; adətən problem sahəsinin məkanında mantıksal bir şəxsdir. Adətən iş məntiqi adlanır.

    Burada fakturanı göndərmədən və ya sifarişin ümumi dəyərini hesablamaqdan əvvəl məlumatları necə yoxlayacağınızı müəyyənləşdirəcəksiniz. Eyni zamanda, domen obyektləri (SQL verilənlər bazası, REST API, mətn faylı və s.) Harada saxlanılsın və ya alınmırsa belə, saxlanmanın tam fərqində deyildir.

  • Məlumat göstəriciləri

    Bu obyektlər yalnız saxlama üçün məsuliyyət daşıyır. Bir məlumat bazasında məlumat saxlasanız, SQL yaşayır. Və ya ehtimal ki, məlumatların saxlanması üçün bir XML faylı istifadə edirsiniz və Data Mappers XML faylları və XML faylları işlədir.

  • Xidmətlər

    Bunları "daha yüksək səviyyəli domen obyektləri" kimi düşünə bilərsiniz, lakin biznes məntiqinin yerinə, Domen obyektləri ilə Mappers arasında qarşılıqlı təsirlərdən məsuldur. Bu strukturlar nəticədə domen biznes məntiqiylə əlaqə qurmaq üçün "açıq" bir interfeys yaradır. Onlardan qaçınmaq olar, amma bəzi domen mantığını nəzarətçiləri sızdırdıqda.

    ACL tətbiqində bu suala müvafiq cavab var - bu faydalı ola bilər.

Model səviyyəsi ilə MVC triadının digər hissələri arasında əlaqə yalnız Xidmətlər vasitəsilə baş verməlidir. Açıq ayrılma bir neçə əlavə üstünlüyə malikdir:

  • bu , tək məsuliyyət prinsipi (SRP) prinsipinin təmin edilməsinə kömək edir.
  • mantığın dəyişməsi halında əlavə manevr qurmaq imkanı verir.
  • nəzarətçi mümkün qədər asandır
  • heç bir xarici API lazımdırsa, aydın bir sxem verir

Modellə qarşılıqlı əlaqə necədir?

Ön şərtlər: "Qlobal Dövlət və Təkliklər"" Nəyə Baxın!" "Net kod söhbətləri" dən.

Xidmət Nümunələrinə Erişmə

View və Controller nümunələri üçün ("istifadəçi interfeysi qatını" adlandırdığınız) bu xidmətlərə daxil olmaq üçün iki ümumi yanaşma var:

  • Görüşlərinizin və nəzarətçilərinizin qurucularında lazımlı xidmətləri daxil edə bilərsiniz, tercihen DI konteynerindən istifadə edə bilərsiniz.
  • Bütün fikirləriniz və nəzarətçiləriniz üçün məcburi asılılıq kimi xidmətlər üçün zavoddan istifadə edin.

Şübhələndiyiniz kimi DI konteyner çox daha zərif bir həlldir (başlanğıc üçün asan olmasa da). Bu funksiyanı nəzərdən keçirməyi təklif edən iki kitabxana Syfmony bağımsız komponentləri DependencyInjection və ya Auryn .

Fabrika konteynerini və DI-dən istifadə edən hər iki həlli, seçilmiş nəzarətçi ilə verilən sorğu-cavab dövrü üçün görünüşü paylaşmaq üçün müxtəlif serverlərin nümunələrini paylaşmağa imkan verir.

Model vəziyyətinin dəyişməsi

İndi nəzarətçiləri model səviyyəsinə çıxa biləcəyiniz üçün, həqiqətən, onları istifadə etməyə başlamaq lazımdır:

 public function postLogin(Request $request) { $email = $request->get('email'); $identity = $this->identification->findIdentityByEmailAddress($email); $this->identification->loginWithPassword( $identity, $request->get('password') ); } 

Kontrolörleriniz çox dəqiq bir tapşırıqa sahibdirlər: istifadəçi girişini götürün və bu girişə əsasən, biznes mantığının mövcud vəziyyətini dəyişdirin. Bu misalda, "anonim istifadəçi" və "qeydə alınmış istifadəçi" arasında dəyişiklik olduğunu bildirir.

Nəzarətçi, iş qaydalarının bir hissəsi olduğundan, istifadəçi girişini təsdiqləməyə görə məsuliyyət daşımır və nəzarətçi, məsələn, burada və ya burada gördüyünüz (məsələn, nifrət etməyin, pis deyil, pis deyil) SQL sorgularını tetiklemez.

Istifadəçi bir dövlət dəyişikliyini göstərir.

Bəli, istifadəçi daxil olub (və ya olmasa). İndi nə? Göstərilən istifadəçi hələ də bunu bilmir. Beləliklə, əslində cavab vermək lazımdır və təqdimat üçün məsuliyyət daşıyır.

 public function postLogin() { $path = '/login'; if ($this->identification->isUserLoggedIn()) { $path = '/dashboard'; } return new RedirectResponse($path); } 

Bu vəziyyətdə təqdimat model qatın mövcud vəziyyətinə əsasən iki mümkün cavabdan birini yaratdı. Başqa bir istifadə hal üçün, "hazırda seçilmiş məqalə" kimi bir şeyə əsaslanaraq müxtəlif göstərmə şablonlarını seçən bir görünüş olacaq.

Təqdimat mərtəbəsi burada təsvir olunduğu kimi olduqca mürəkkəb ola bilər: PHP-də MVC baxışları haqqında ümumi məlumat .

Amma yalnız REST API yaratmaq!

Əlbəttə ki, çoxdan çox hallarda vəziyyət var.

MVC sadəcə problemlərin ayrılması prinsipi üçün konkret bir həlldir . MVC istifadəçi interfeysini biznes məntiqindən ayırır və istifadəçi interfeyində istifadəçi giriş işini və təqdimatını ayırır. Bu vacibdir. İnsanlar tez-tez onu "üçbucaq" kimi təsvir etsələr də, əslində üç müstəqil hissədən ibarət deyildir. Quruluş belədir:

2019

819
03 мая '11 в 3:56 2011-05-03 03:56 03 may '11 tarixində saat 03:56 'də tereškoya verilən cavab 2011-05-03 03:56

İşgəncə olan hər şey modeldir, məlumat bazası sorğusu, hesablama, REST çağırışı və s.

Modeldən verilən məlumatlara giriş əldə edə bilərsiniz, MVC nüsxəsi bu sizi məhdudlaşdırmır. Şəkər onu xidmətlər, kartoqrafçılar və nə ilə əhatə edə bilər, amma modelin faktiki tərifi iş mantığını işləyən qat, başqa heç bir şey yoxdur. İstəyirsinizsə, bu, bir təbəqə, bir funksiya və ya gazili obyektlərlə tam bir modul ola bilər.

Doğrudan modeldə çalışan birbaşa verilənlər bazası sorgularını yerinə yetirən ayrı bir obyektin olması həmişə asandır: bu, modulları test etdirərkən xüsusilə faydalıdır (modelinizə verilən verilənlər bazası bağımlılıklarının asanlığı səbəbindən):

border=0
 class Database { protected $_conn; public function __construct($connection) { $this->_conn = $connection; } public function ExecuteObject($sql, $data) { // stuff } } abstract class Model { protected $_db; public function __construct(Database $db) { $this->_db = $db; } } class User extends Model { public function CheckUsername($username) { // ... $sql = "SELECT Username FROM" . $this->usersTableName . " WHERE ..."; return $this->_db->ExecuteObject($sql, $data); } } $db = new Database($conn); $model = new User($db); $model->CheckUsername('foo'); 

Əlavə olaraq, PHP-də nadir hallarda istisnaların qarşısını almaq / ləğv etmək lazımdır, çünki geri qaytarma xətti qorunur, xüsusən də nümunə kimi. Yalnız istisnanın atılmasına icazə verin və nəzarətçiyə tutun.

32
03 мая '11 в 3:42 2011-05-03 03:42 cavab 03 may 2011-ci il saat 03: 00-da Netcoderə verilir

Web MVC-də istədiyiniz hər şeyi edə bilərsiniz.

Orijinal konsepsiya (1) modelini işgüzar məntiq kimi təsvir etmişdir. Ərizənin vəziyyətini təmsil etməlidir və məlumatların uyğunluğunu təmin etməlidir. Bu yanaşma tez-tez "yağ modeli" kimi təsvir olunur.

PHP çərçivəsinin əksəriyyəti modelin sadəcə bir verilənlər bazası interfeysi olduğu kiçik bir yanaşma təqib edir. Lakin ən azı bu modellər daxil olan məlumatları və əlaqələri hələ də doğrulamalıdır.

Hər halda, SQL maddi və ya verilənlər bazası çağırışlarını başqa səviyyəyə bölsəniz, çox uzaq deyilik. Beləliklə, faktiki saxlama API'sinə deyil, faktiki məlumatlara / davranışlara diqqət yetirmək lazımdır. (Lakin, əvvəlcədən hazırlanmadığı təqdirdə, bir verilənlər bazası arxivini fayl qovluğu ilə əvəz edə bilməzsiniz.)

18
03 мая '11 в 3:41 2011-05-03 03:41 Cavab mario 03 May '11 da 3:41 2011-05-03 03:41 verilir

Çoğu zaman, proqramların çoxunda məlumat, görüntü və proses hissələri olacaq və biz onları M , VC hərflərinə qoyuruq.

Model ( M ) → Proqramın vəziyyətini ehtiva edən xüsusiyyətlərə malikdir və VC haqqında heç bir şey bilmir.

View ( V ) → Proqramın formatını göstərir və yalnız onu necə modelləşdirə biləcəyini və C

Controller ( C ) ----> Bir işləmə hissəsi var və M və V arasındakı siqnal kimi fəaliyyət göstərir və M və V ə qarşı M , V asılıdır V

Ümumiyyətlə hər bir narahatlıq bölünməsi var. Gələcəkdə hər hansı bir dəyişiklik və ya təkmilləşdirmə asanlıqla əlavə edilə bilər.

4
30 июня '14 в 16:09 2014-06-30 16:09 cavabı yaxşı hiss etmək və proqramlaşdırma üçün verilir 30 İyun 2014, 16:09 2014-06-30 16:09

Mənim vəziyyətimdə, bir sorgu, bir nümunə və s. Kimi birbaşa məlumat bazası ilə bütün qarşılıqlı əlaqələri idarə edən verilənlər bazası sinfi var. Buna görə, MySQL- dən PostgreSQL verilənlər bazasını dəyişmək məcburiyyətində olsaydı, heç bir problem olmayacaqdı. Buna görə ek bir qat əlavə edərək faydalı ola bilər.

Hər bir masanın öz sinfi var və öz xüsusi metodlarına malik ola bilər, lakin məlumatların faktiki alınması üçün verilənlər bazası sinifini işləməyə imkan verir:

Fayl Database.php

 class Database { private static $connection; private static $current_query; ... public static function query($sql) { if (!self::$connection){ self::open_connection(); } self::$current_query = $sql; $result = mysql_query($sql,self::$connection); if (!$result){ self::close_connection(); // throw custom error // The query failed for some reason. here is query :: self::$current_query $error = new Error(2,"There is an Error in the query.\n<b>Query:</b>\n{$sql}\n"); $error->handleError(); } return $result; } .... public static function find_by_sql($sql){ if (!is_string($sql)) return false; $result_set = self::query($sql); $obj_arr = array(); while ($row = self::fetch_array($result_set)) { $obj_arr[] = self::instantiate($row); } return $obj_arr; } } 

ClassL masa obyekti

 class DomainPeer extends Database { public static function getDomainInfoList() { $sql = 'SELECT '; $sql .='d.`id`,'; $sql .='d.`name`,'; $sql .='d.`shortName`,'; $sql .='d.`created_at`,'; $sql .='d.`updated_at`,'; $sql .='count(q.id) as queries '; $sql .='FROM `domains` d '; $sql .='LEFT JOIN queries q on q.domainId = d.id '; $sql .='GROUP BY d.id'; return self::find_by_sql($sql); } .... } 

Я надеюсь, что этот пример поможет вам создать хорошую структуру.

0
ответ дан Ibu 03 мая '11 в 3:47 2011-05-03 03:47

Другие вопросы по меткам или Задайте вопрос