MVC принцип на работа.

Galli

Registered
Имам нещо като теоретичен въпрос за Model-View-Controller. Въпросът ми е по-скоро за софтуерна архитектура. Каква е разликата между модела, контролера и вюто при реализация на фреймуорка. Не питам за това как се използва. Чел съм книжки, но не си спомням това да съм го чел. Правил съм си мой МВЦ, но не знам дали правилно съм го направил. Примерно в основния клас модел зареждам класовете като базаданни, форми, и т.н., с които ще се работи по логиката. И след като си направя нов модел за приложението, той наследява основния и аз имам достъп до всичките чрез $дис и да им правя инстанции. В контролера зареждам само клас, чрез, който създавам инстанции на моделите и вютата.
Другият ми въпрос е защо се препоръчва много код в моделите, малко в контролерите? Но това май е следствие на предишния въпрос. Общо взето работи като МВЦ ама май не е. Затова ако някой има желание нека да обясни.
 
Няма "правилен" начин да направиш MVC Framework. MVC не се интересува от това как е направен и дали изобщо има framework или просто си събрал няколко класа с различни функции, които се припокриват с MVC.

Ако работи като MVC значи Е MVC.

Другият ми въпрос е защо се препоръчва много код в моделите, малко в контролерите?

Това е свързано с ролите на всеки компонент от MVC. Моделите трябва да управляват информацията, да дават готов интерфейс на контролерите, така че те просто да реализират логиката на приложението (не логиката на работа с БД/друг източник на данни).

Тоест модела маскира къде и как се съхранява информацията, а контролера просто работи като свързващ механизъм между потребителя и моделите. За това, за да ти е добър контролера (да върши само това, което е негова отговорност) той трябва да е колкото се може по-тънък. Това не значи, че на всяка цена трябва да махаш от него и неща, които трябва да са там. Просто в 90% от случаите в един метод от контролера ще има просто извикване на функции от модела и render на view.
 
Аз бих направил контролера да филтрира входните данни, цялата "мръсна" работа да се върши в контролера и да се праща колкото може по чиста информация към модела. Тоест модела да се ползва само и единствено за връзка със базата данни и методите за заявките. Единствено само за информацията. А самият контролер да се грижи за това как да валидирана и да прати нужните неща към модела.

Защо смятам така:

Тъй като контролера, най - вероятно ще извиква разни библиотеки - разни помощни класове, сесиини класове, cache engine - и и др. подобни неща, които е логично да се извикват от контролера, защо да не и филтрира и входните данни в него? Така и така ще ползва някой от същите функции за защита както при модела, защо трябва да извикваме отново класа за защита и във модела? Според мен по - добре всички проверки да се извършват на едно място (в контролера) от колкото във модела и контролера.

А пък и в крайна сметка това като казвате че модела трябва да върши всички валидации и др. подобни неща, то това е HMVC, тоест контролера се грижи да свърже единствено view със модела и те вече взаймоно си контактуват и си пращат необходимата информация. Вие правите точно това.Тогава контролера си губи смисъла.
 
eddyy93 каза:
Аз бих направил контролера да филтрира входните данни, цялата "мръсна" работа да се върши в контролера и да се праща колкото може по чиста информация към модела. Тоест модела да се ползва само и единствено за връзка със базата данни и методите за заявките. Единствено само за информацията. А самият контролер да се грижи за това как да валидирана и да прати нужните неща към модела.

Защо смятам така:

Тъй като контролера, най - вероятно ще извиква разни библиотеки - разни помощни класове, сесиини класове, cache engine - и и др. подобни неща, които е логично да се извикват от контролера, защо да не и филтрира и входните данни в него? Така и така ще ползва някой от същите функции за защита както при модела, защо трябва да извикваме отново класа за защита и във модела? Според мен по - добре всички проверки да се извършват на едно място (в контролера) от колкото във модела и контролера.

А пък и в крайна сметка това като казвате че модела трябва да върши всички валидации и др. подобни неща, то това е HMVC, тоест контролера се грижи да свърже единствено view със модела и те вече взаймоно си контактуват и си пращат необходимата информация. Вие правите точно това.Тогава контролера си губи смисъла.

HMVC е йерархично MVC, не MVC при което модела управлява вютата.

Ами от гледна точка на абстракцията (чисто теоритично) валидациите трябва да са в модела, защото той е нещото, което трябва да се грижи за данните. Сесиите и кешовете също трябва да са в някакви модели, защото те също обработват (съхраняват/изваждат) някакви данни.

Един пример защо тези неща трябва да са в моделите:
Преди време бях направил един доста голям сайт с MVC и още не бях толкова навътре с този модел на абстракция. И всички проверки за валидност, извиквания на сесии и т.н. ми бяха в контролерите.
След определено време ми се наложи за този проект да правя API. Тоест да имам същите операции върху информацията, но потребителите да могат да ги достъпват чрез REST API. За това се правят нови контролери. И понеже всички проверки ми бяха в контролерите трябваше да дублирам огромно количество код, вместо само да си използвам готови функции на моделите (които да си правят валидацията).

Така се получава много дублиран код, със съвсем малки разлики, който като прометиш на 1 място трябва да промениш и на другото. Всяка промяна на логиката трябваше да я правя на минимум 2 места. Обаче това не е просто една и съща промяна - трябва да се съобразиш и на двете места какво точно правиш и дали няма да счупиш нещо, защото имаше разлики.

Истината е, че когато някой каже MVC има хора, на които веднага им излиза в главата CodeIgniter. CodeIgniter е лош пример за MVC framework. При него контролерите взимат ролите на моделите, а моделите са станали просто слой на database абстракция (място, в което да си пъхнем acrtiverecord кода)
 
Здравейте имам голям интерес на тази тема, жалко че няма уроци тук. Бих помолил ако имате време да пуснете някаква поредица за изграждане на прост сайт по MVC модела.

А иначе може и да греша но по този цитат

"И понеже всички проверки ми бяха в контролерите трябваше да дублирам огромно количество код, вместо само да си използвам готови функции на моделите (които да си правят валидацията). "

нали затова има наследяване и презаписване на функции
 
teroristd каза:
А иначе може и да греша но по този цитат

"И понеже всички проверки ми бяха в контролерите трябваше да дублирам огромно количество код, вместо само да си използвам готови функции на моделите (които да си правят валидацията). "

нали затова има наследяване и презаписване на функции

Няма да стане с наследяване, защото представи си следната ситуация:

Имаш 1 контролер, който се използва за логин система. В него имаш метод за регистриране на потребител, който прави проверки дали мейла е валиден, дали има друг потребител с това име, дали има друг с този мейл, регистрира потребител и праща мейл за потвърждение. В модела има методи от рода на: loginUser, registerUser, checkEmail, checkUsername, sendEmail, които не правят проверки за валидност на данните.
Този контролер използва директно данни подадени от форма чрез POST и като си свърши работата показва на екрана някакво view.

Сега да речем, че ми се налага да направя API за сайта. Да, ама API-тата не ползват форми, пък и не трябва да показват view, а да показват някакви JSON/XML съобщения. Следователно същия контролер не мога да го ползвам, защото той ще работи само с форми и вюта. Пък и за API-то ми трябват още проверки като например проверка за API ключ, проверка за това какъв резултат да връщам (json или xml) и т.н.

Не мога и да наследя този контролер, защото няма смисъл - не мога да ползвам същия код, ще трябва да се попромени. Ще трябва да копирам всичко в контролера за API-то, да променя това, което работи с view-тата и формата и вече ще трябва да поддържам по 2 копия на тези проверки.

Ако методите на модела ми правеха проверки и просто ми съобщаваха за грешките (чрез exceptions например) първия контролер щеше да ми изглежда по този начин:

PHP:
class TestController
{
    public function register()
    {
        if (isset($_POST['submit']))
       {
            try
           {
                $model->register($_POST['username'], $_POST['password'], ....);
           }
           catch (ValidationException $e)
           {
                $view->error($e);
           }
       }

       $view->render();
    }

    [...]
}

Сега много лесно мога да си направя втория контролер, така че логиката да е същата, но да не взима информацията от форма и да не показва view, ами да праща нещо друго като json/xml. Просто ще сменя параметрите на $model->register, ще сменя кода за render на view с функции, които принтират json/xml и всичко ще е ОК, защото проверките са в модела - ще са на 1 място и могат да се използват отвсякъде.
 
StormBreaker ти ми разби представата за сложност на шаблона. Излиза, че е само за подреденост и прегледност, а няма никакви правила. Сигурен ли си в това, чел ли си го в някакви книги...? Виждам, че е eddyy93 разсъждава самостоятелно като мен. А аз искам да знам има ли някаква теория и правила по реализацията.
teroristd ако не се сещаш как да си направиш МВЦ, значи още не ти е дошло времето. Трябва ти опит в php. Ако тръгнеш да четеш някакви статии в интернет съм убеден, че те ще са от хора като нас "туристи", на които им е интересно да пишат. А не от специалисти. Ето аз сега се чудя качествено ли съм го направил или не. И ако взема да предам това на теб, най-много да те заблудя. Специалистите ме съмнява, че пишат уроци из разни сайтове.
 
Galli каза:
StormBreaker ти ми разби представата за сложност на шаблона. Излиза, че е само за подреденост и прегледност, а няма никакви правила. Сигурен ли си в това, чел ли си го в някакви книги...? Виждам, че е eddyy93 разсъждава самостоятелно като мен. А аз искам да знам има ли някаква теория и правила по реализацията.
teroristd ако не се сещаш как да си направиш МВЦ, значи още не ти е дошло времето. Трябва ти опит в php. Ако тръгнеш да четеш някакви статии в интернет съм убеден, че те ще са от хора като нас "туристи", на които им е интересно да пишат. А не от специалисти. Ето аз сега се чудя качествено ли съм го направил или не. И ако взема да предам това на теб, най-много да те заблудя. Специалистите ме съмнява, че пишат уроци из разни сайтове.

Ами да - за подреденост, за разделяне на ролите. За да знаеш кое къде да търсиш и кое как взаимодейства с другите неща. Реализацията няма значение.
Все едно да имаш един стек или опашка - има правила как трябва да работи един стек, а това как ще е реализиран няма значение, важното е да работи като стек. Дали вътрешно ще е направен със свързан списък, с разширяващ се масив или всичко ще пише във файл и после ще го чете от файла не променя факта, че това е стек и работи като стек.

MVC, както и всички други шаблони имат правила, но тези правила са само на ниво взаимодействие между компонентите и начин на работа. Те не се занимават с това как са реализирани. Ако имаше правила за реализация те нямаше да са толкова универсални. Пък и начина, по който ти можеш да реализираш един шаблон в PHP може да е невъзможен в друг език. Това с магическите методи например (__get, __getStatic, ...) до колкото знам на Java/C#/C++ няма да се получи.
MVC казва просто един набор от правила, по които компонентите си взаимодействат. Ако някъде пише, че един MVC framework трябва да е реализиран по точно определен начин значи нещо не е както трябва.

Замисли се - има стотици различни MVC фреймуърка. Ако в шаблона MVC имаше ограничения за имплементацията щеше да има само 1 (или всички да са еднакви).
 

Back
Горе