Linux за българи: Форуми

Програмиране => Web development => Темата е започната от: VladSun в Mar 17, 2010, 12:06



Титла: [MVC] Основни положения
Публикувано от: VladSun в Mar 17, 2010, 12:06
За прочит http://bg.wikipedia.org/wiki/Model-View-Controller ($2)

Ще се опитам да дам и аз мое тълкуване на MVC архитектурата:

* Модел - съдържа единствено и цялата "бизнес" логика - "вътрешното" състояние на системата. Моделът не се интересува от това как е представен (т.е. неговите данни и вътрешно състояние) пред потребителя (който може да е и друг софтуер, не е задължително човек). Моделът също така не се интересува от къде идват новите данни и команди за промяна на състоянието му. Моделът се грижи за съхраняването и извличането на данните (ДБ, файлове и т.н.) ;

* Изглед - всеки един от тези компоненти има достъп до всички публични данни и методи на Модела и определя кои от тях и как да бъдат изобразени;

* Контролер - всеки един от тези компоненти има достъп до всички публични данни и методи на Модела. Контролерът също така определя какво е действието предприето от потребителя и какви са новите данни предоставени от потребителя. В зависимост от исканото действие, Контролерът извиква определена команда и/или променя определени данни на Модела. Контролерът също така решава кой Изглед ще се използва за визуализирането на Модела.

Цитат
Защо се прави всичко това? Ще се опитам да изясня чрез пример:

Искаме да направим софтуер за прост калкулатор - да може да вади, събира, умножава и дели числа. Създаваме web вариант на този софтуер. Ако сме следвали MVC архитектурата, то ще можем:

* да променим форматът на резултата (прим. в PDF) само чрез добавяне на нов компонент за Изглед - без да променяме нищо друго.
* да създадем CLI вариант като само променим компонентите за Контролер/Изглед.

Т.е. Моделът не се променя никога, което е от особена важност в реалните случаи, когато Моделът може да бъде изключително сложен.

Съществува така наречения Front Controller - това е специален Контролер, който осигурява една единствена входна точка (представете си main() в C ) за целия софтуер. Front Controller-а определя кой Action Controller трябва да се извика и да му се предадат входните данни. Action Controller са Контролерите, които вие ще трябва да пишете и те ще се грижат за описаните в горната дефиниция действия.

Добре е Моделът да бъде напълно капсулиран - т.е. да няма възможност за пряко модифициране или четене на данните му. Това се постига чрез използването на данни с ограничен достъп (protected/private) и публични методи за тяхното модифициране/четене.


Титла: Re: [MVC] Основни положения
Публикувано от: VladSun в Mar 17, 2010, 12:37
Ще дам вариант за реализирането на примерът за калкулатор. Ще използвам CodeIgniter-подобни дефиниции, защото смятам, че така ще бъде най-разбираемо.

Модел
Код
GeSHi (PHP):
  1. class Calculator_Model extends Model
  2. {
  3. protected $errors = array();
  4. protected $result = 0;
  5.  
  6. public function add($a, $b)
  7. {
  8. if (!$this->validate($a) || !$this->validate($b))
  9. return;
  10.  
  11. $this->result = $a + $b;
  12. }
  13.  
  14. public function substract($a, $b)
  15. {
  16. if (!$this->validate($a) || !$this->validate($b))
  17. return;
  18.  
  19. $this->result = $a - $b;
  20. }
  21.  
  22. public function multiply($a, $b)
  23. {
  24. if (!$this->validate($a) || !$this->validate($b))
  25. return;
  26.  
  27. $this->result = $a * $b;
  28. }
  29.  
  30. public function divide($a, $b)
  31. {
  32. if (!$this->validate($a) || !$this->validate($b))
  33. return;
  34.  
  35. if ($b == 0)
  36. {
  37. $this->errors[] = "Деление на нула";
  38. return;
  39. }
  40.  
  41. $this->result = $a / $b;
  42. }
  43.  
  44. public function hasError()
  45. {
  46. return count($this->errors) > 0;
  47. }
  48.  
  49. public function getErrors()
  50. {
  51. return $this->errors;
  52. }
  53.  
  54. public function getResult()
  55. {
  56. return $result;
  57. }
  58.  
  59. public function clear()
  60. {
  61. $this->result = 0;
  62. $this->errors = array();
  63. }
  64.  
  65. protected function validate($a)
  66. {
  67. if (!is_numeric($a)
  68. {
  69. $this->errors[] = "Операндът не е число";
  70. return false;
  71. }
  72. return true;
  73. }
  74.  
  75. }

Controller
Код
GeSHi (PHP):
  1. class Calculator extends Controller
  2. {
  3. public function __construct()
  4. {
  5. parent::__construct();
  6. $this->load->model('Calculator_Model', 'calculator'); // зареди инстанция на класа Calculator_Model в $this->calculator
  7. }
  8.  
  9. public function index()
  10. {
  11. $this->calculator->clear();
  12. $this->load->view('input.html.php', $this->calculator);
  13. }
  14.  
  15. public function add()
  16. {
  17. $this->calculator->add($_POST['a'], $_POST['b']);
  18. $this->load->view('result.html.php', $this->calculator);
  19. }
  20.  
  21. public function substract()
  22. {
  23. $this->calculator->substract($_POST['a'], $_POST['b']);
  24. $this->load->view('result.html.php', $this->calculator);
  25. }
  26.  
  27. public function multiply()
  28. {
  29. $this->calculator->substract($_POST['a'], $_POST['b']);
  30. $this->load->view('result.html.php', $this->calculator);
  31. }
  32. }

View input.html.php
Код
GeSHi (PHP):
  1. <!DOCTYPE html  PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  2. <html>
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  5. <title>Calculator</title>
  6. </head>
  7. <body>
  8. <form method="post" action="/calculator/add">
  9. <input type="text" name="a" value=""/> + <input type="text" name="b" value="" /> = ?
  10. <input type="submit" value="Изчисли">
  11. </form>
  12.  
  13. <form method="post" action="/calculator/substract">
  14. <input type="text" name="a" value=""/> - <input type="text" name="b" value="" /> = ?
  15. <input type="submit" value="Изчисли">
  16. </form>
  17.  
  18. <form method="post" action="/calculator/multiply">
  19. <input type="text" name="a" value=""/> * <input type="text" name="b" value="" /> = ?
  20. <input type="submit" value="Изчисли">
  21. </form>
  22.  
  23. <form method="post" action="/calculator/divide">
  24. <input type="text" name="a" value=""/> / <input type="text" name="b" value="" /> = ?
  25. <input type="submit" value="Изчисли">
  26. </form>
  27.  
  28. </body>
  29. </html>

View result.html.php
Код
GeSHi (PHP):
  1. <!DOCTYPE html  PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  2. <html>
  3. <head>
  4. <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  5. <title>Calculator</title>
  6. </head>
  7. <body>
  8. <?php
  9. if ($calcualtor->hasError())
  10. {
  11. foreach ($calculator->getErrors() as $errorMessage)
  12. {
  13. echo '<div class="error">'.$errorMessage.'</div>';
  14. }
  15. }
  16. else
  17. {
  18. echo '<div class="result">Резултът е: '.$calculator->getResult().'</div>';
  19. }
  20. ?>
  21.  
  22. <a href="/calculator/index">Към калкулатора</a>
  23. </body>
  24. </html>


Титла: Re: [MVC] Основни положения
Публикувано от: b2l в Mar 17, 2010, 12:41
И една картинка за да стане по-ясно:
(http://www.symfony-project.org/images/jobeet/1_4/04/mvc.png)


Титла: Re: [MVC] Основни положения
Публикувано от: VladSun в Mar 17, 2010, 12:47
Честно казано не съм много съгласен с тази картинка - обикновено Изгледът има пълен достъп за четене на Модела, а Контролерът се прави възможно "най-тънък".

Освен това MVC е често даван като пример за приложението на Observer шаблона - Изгледът "наблюдава" Модела за промени и при възникването на такива се обновява.

Тази картинка е по-близо до моите разбирания:

http://upload.wikimedia.org/wikipedia/commons/2/2e/ModelViewControllerDiagram.svg


Титла: Re: [MVC] Основни положения
Публикувано от: senser в Mar 17, 2010, 13:07
Нека да пробвам да дам и аз моите 20 ст. по темата - те са изцяло базирани на опита ми, който имам с CakePHP. Там картинката на backtolife пасва доста повече от тази на VladSun, в смисъл, че почти никога в изгледа не достъпваш директно данни от модела. Другото, което ми прави впечатление в примера на VladSun, може би не е свързано директно с MVC архитектурата, но все пак: използването на $this->validate($a),  за да не се повтаря във всяка функция е удобно да се изнесе в отделна callback функция, която да се изпълнява преди всяко действие (или след него, според зависи).


Титла: Re: [MVC] Основни положения
Публикувано от: VladSun в Mar 17, 2010, 13:19
Да, съгласен съм, че MVC архитектурата може да се интерпретира по различен начин. Един от основните избори при нея е колко и каква работа да се върши в Контролера - "тънък" или "дебел" Контролер. Моят личен избор е за "тънък" Контролер.

По отношение на "validate" - исках да дам по-прост пример, конкретизиран върху MVC шаблона.
В реалните случаи е най-добре Моделът да съдържа инстанция на Validator клас, с който да се проверяват универсални ограничения, несвързани с бизнес логиката ( validate() в този случай ), а самият Модел да проверява за валидност по отношение на бизнес логиката - if ($b == 0) блокът в този случай.


Титла: Re: [MVC] Основни положения
Публикувано от: VladSun в Mar 17, 2010, 23:45
Явно имаме потребители на достатъчно много MVC PHP frameworks, та предлагам всеки да започне с описание на инсталацията и bootstrap-а на избраната от него.

Аз поемам CodeIgniter :)

Така ще можем да помогнем на някои от потребителите в този форум да се отърват от спагети-кода, който имат в момента.

Идеята ми хрумна заради скорошната тема на toti84 - http://www.linux-bg.org/forum/index.php?topic=37436.0


Титла: Re: [MVC] Основни положения
Публикувано от: VladSun в May 01, 2010, 21:11
Една добра поредица от статии за "начинаещи" :

http://blog.dmcinsights.com/series/understanding-mvc/


Титла: Re: [MVC] Основни положения
Публикувано от: ivo3d в Jul 27, 2010, 02:46
Честно казано не съм много съгласен с тази картинка - обикновено Изгледът има пълен достъп за четене на Модела, а Контролерът се прави възможно "най-тънък".

Освен това MVC е често даван като пример за приложението на Observer шаблона - Изгледът "наблюдава" Модела за промени и при възникването на такива се обновява.

Тази картинка е по-близо до моите разбирания:

http://upload.wikimedia.org/wikipedia/commons/2/2e/ModelViewControllerDiagram.svg

Идеята да има директна връзка между модела и темплейта звучи добре, всъщност се спестява доста код. Но все пак не ми вдъхва много доверие, можеш ли да ми покажеш framework, в който това е описано в документацията като практика, аз досега не съм срещал - във framework-а, който пиша в момента за няколко специфични, но идентични проекта също няма да го предвиждам това като възможност. Още повече там по темплейтите ще пипат хора, на които предпочитам да им давам готови масиви и да не знаят имената на моделите и как се борави с тях...

И аз се стремя към "тънък" контролер, валидациите и връзките между таблиците са описани в моделите, кеширането също. В контролера само викам нужния модел, записвам/взимам информация и я пращам към view-to (или към responce обекта директно, ако ми трябва json или xml например). Също така подавам form класове към темплейта и това е... Helper-ите се зареждат "мързеливо" в темплейта, така че и за тях контролера няма грижа. Но информацията винаги минава през контролера.

Все пак ще ми е интересно да видя това което казваш реално, не бях се замислял досега и ми изникват доста въпроси.


Титла: Re: [MVC] Основни положения
Публикувано от: VladSun в Jul 27, 2010, 10:54
И аз много често съм използвал предаване на данни от контролера към изгледа чрез използването на асоциативен масив. Наистина по този начин се постига някакво ограничаване на възможностите за грешка от страна на дизайнерите.
Но, все пак :
Код
GeSHi (PHP):
  1. class User extends Controller
  2. {
  3. public function save()
  4. {
  5. if (empty($_POST['submit']))
  6. {
  7. $this->load->view('user/save/form');
  8. }
  9. else
  10. {
  11. $user = new UserModel();
  12. if ($user->save($_POST['id'], $_POST))
  13. {
  14. $this->load->view('user/save/success');
  15. }
  16. else
  17. {
  18. $this->load->view('user/save/form', array
  19. (
  20. 'name' => $user->getName(),
  21. 'phone' => $user->getPhone(),
  22. 'email' => $user->getEmail(),
  23. 'errors'=> $user->getErrors(),
  24. ));
  25. }
  26. }
  27. }
  28. }

Вижда се, че де факто превръщаме обекта на модела в асоциативен масив.

Второто нещо, което не ми харесва е да се слага логика както в контролера, така и в изгледа:
Код
GeSHi (PHP):
  1. $this->load->view('user/get', array
  2. (
  3. 'name' => $user->getName(),
  4. 'phone' => $user->getPhone(),
  5. 'email' => $user->getEmail(),
  6. 'isAdult' => $user->getAge() > 18
  7. ));
или
Код
GeSHi (PHP):
  1. echo $user->getAge() > 18 ? 'OK' : 'Not OK';

По-добре е да се добави isAdult() метод в модела и да се вика в изгледа (или контролера в твоя случай).

Функциите на контролера според мен са няколко:
- да създава контекст за модела (т.е. какво ще се прави);
- определя как и от къде ще се взимат входните данни и предаването им на модела (GET, POST, PUT и т.н. в света на www);
- зареждането на съответния изглед за контекста и предаването на модела към изгледа;

Ако предаваш директно модела на изгледа, то при разширяването на модела ще се пипа само в кода на изгледа.

Трябва да се спомене, че от MVC триадата единствено моделът може да се използва повторно. Т.е. трябва да се стремим всяко късче логика да е в модела.

Всичко това особено добре си проличава, когато приложението не е "stateless" (имам предвид HTTP протокола) - прим. desktop приложение. Тогава Observer шаблона е най-подходящата връзка между модела и изгледа.


Титла: Re: [MVC] Основни положения
Публикувано от: VladSun в Jul 27, 2010, 11:43
По отношение на притесненията ти за достъпа до модела от страна на дизайнерите, би могъл да използваш някакъв вид wrapper за да ограничиш действията с него:

Код
GeSHi (PHP):
  1. class ReadOnlyWrapper
  2. {
  3. protected $object = null;
  4.  
  5. public function __construct($object)
  6. {
  7. if (!$object)
  8. throw new Exception('Object instance required.');
  9.  
  10. $this->object = $object;
  11. }
  12.  
  13. public function __set($property, $value)
  14. {
  15. throw new ReadOnlyException('Object oproperties have read only access');
  16. }
  17.  
  18. public function __get($property)
  19. {
  20. if (is_object($this->object->{$property}))
  21. return new ReadOnlyWrapper($this->object->{$property});
  22. else
  23. return $this->object->{$property};
  24. }
  25.  
  26. public function __call($method, $arguments)
  27. {
  28. if (substr($method, 0, 3) === 'get')
  29. call_user_func_array(array($this->object, $name), $arguments);
  30. else
  31. throw new ReadOnlyException('Method ['.  get_class($this->object).'->'.$method.'] called is not a read only one.');
  32. }
  33. }
  34.  
  35. class ReadOnlyException extends Exception {}
  36.  

И съответно в контролера:

Код
GeSHi (PHP):
  1. $this->load->view('user/save/form', new ReadOnlyWrapper($user));


Титла: Re: [MVC] Основни положения
Публикувано от: ivo3d в Jul 27, 2010, 13:23
Явно в 2:30 е по-добре да се спи :D Не съм те разбрал, аз го правя по същия начин, естествено, че няма да разкъсвам модела в контролера и да пращам отделни фрагменти на view-то (макар, че така е най-strict да го кажем)... Пращам моделите на темплейта, в контролера единствено ги зареждам и ги предавам натам и после темплейта да си взима каквото му трябва. Освен разбира се в случаите, когато обработвам информация от get/post, но тогава теплейта така или иначе не играе роля.

Но все пак разговора ме подсеща, че ще е хубаво когато се обръщам към модел от темплейт, да е само read-only и по-късно ще го измисля да стане без допълнителни класове. Предвид, че контролера и view класа ги зареждам с reflection, няма да е особен проблем да проверявам какво се случва и кой кого и откъде вика.


Титла: Re: [MVC] Основни положения
Публикувано от: VladSun в Jul 27, 2010, 13:42
//offtopic

Но все пак разговора ме подсеща, че ще е хубаво когато се обръщам към модел от темплейт, да е само read-only и по-късно ще го измисля да стане без допълнителни класове. Предвид, че контролера и view класа ги зареждам с reflection, няма да е особен проблем да проверявам какво се случва и кой кого и откъде вика.

Ще ми е интересно да покажеш какво правиш точно. Имахме дискусия преди време - гледам, че не си се включвал в нея:
http://www.linux-bg.org/forum/index.php?topic=28455.0


Титла: Re: [MVC] Основни положения
Публикувано от: ivo3d в Jul 27, 2010, 14:34
Не съм, аз от около година пиша сериозно OOP, а и тогава бях позабравил малко линукса (заради едни аудио проекти, трябваше ми боза постоянно и бях занемарил убунтото)... Както и да е.

В момента, както казах, пиша собствен framework като идеята му (поне засега) не е за публично ползване, но нищо не ми пречи да я пусна. Общо взета има доста идеи, взаимствани от kohana и doophp. От кохана дори има някои неща, които съм изкопирал почти дословно, например utf8 функциите. От doohphp всъщност заимствах идеята повечето неща да са singleton и да се зареждат "мързеливо" - демек 1 път и то само когато трябва (ако потрябва).

Има и ORM, който всъщност е проекта phpActiveRecord с някои промени.

Framework-а изисква php 5.3, защото се използват namespaces и някои други нововъведения в 5.3. Главно гоня производителност, че съм се патил от годзилогрухти като zend и cake. Засега с използване на бази данни съм успял да постигна около 50% по-ниска производителност от чисто php, но в момента повечето неща са в разработка и или се зарежда съвсем малко код или не се зарежда нищо... Но ще гледам да не клякам повече от 60-65% под чистото php. При големите рамки разликата е в пъти, обикновено десетки, но не бива да се правят сравнения, тъй като при мен функционалността също е в пъти (десетки) по-малка от големите рамки, а и на мен идеята не ми е да се получи нещо универсално, а да решава точно конкретни задачи.

Всъщност каква ми е идеята - освен производителност, исках да знам на абсолютно всеки ред какво се случва, както се вика на ниво kernel. Не, че не мога във всеки един framework да разбера какво се случва, но общо взето всеки програмист има свой начин на мислене и за мен в доста framework-ове има неща, които са ми абсолютно нелогични, а има фрагменти, които просто не мога да разбера защо са написани точно така...

Другата причина да започна свой framework - трябва ми hmvc, ама не точно. Например на мен ми предстоят няколко идентични уеб приложения - сайт, който рекламира и продава услугата и самата услуга, като всеки потребител има поддомейн (виртуален разбира се)... Например:

www.webapp.bg рекламира и продава услугата
ivan.webapp.bg; dragan.webapp.bg - представляват самото уеб приложение
www.webapp.bg/admin - 3-то уеб приложение, с които да администрирам потребителите, както и www сайта.

Трябват ми едни и също модели, но различни контролери, темплейти, layout, acl. Дори и различна multilanguage поддръжка, примерно в ivan.webapp.bg и dragan.webapp.bg и www.webapp.bg искам български и английски, а в www.webapp.bg/admin/ не ми трябва.

За целта съм ги разделил на отделни модули, които ползват един framework и едни и същи модели, но останалите ресурси са си за всеки модул отделно. Например:

Код
GeSHi (PHP):
  1.  
  2. $modules = array(
  3. 'site' => array(
  4. 'type' => 'dir',
  5. 'path' => '/',
  6. 'multi-language' => 'yes'
  7. ),
  8. 'admin' => array(
  9. 'type' => 'dir',
  10. 'path' => '/admin/',
  11. 'multi-language' => 'no'
  12. ),
  13. 'webapp' => array(
  14. 'type' => 'subdomain',
  15. 'include' => '*',
  16. 'exclude' => 'feed',
  17. 'multi-language' => 'yes'
  18. )
  19. );
  20.  
  21.  

Както се вижда, има 3 модула, като за всеки си има директория със всичките ресурси. "site" се отделя на база път, като пътя е / в www.webapp.bg (webapp.bg). "admin" модула се зарежда, когато имаме www.webapp.bg/admin/. А "webapp" когато имаме какъвто и да е поддомейн ('include' => "*") освен 'feed' ('exclude' => 'feed'). Feed е просто пример, не е с някаква конкретна цел. Може да се зарежда и по обратната логика. Например ако имаме feed.webapp.bg, и няма конфигурация, която да е специално за feed, ще се зареди "site" модула. Затова накрая слагам един модул 'feed', в който 'exclude' e '*', а 'include' е 'feed'. Имам и един комбинирам тип, който е за път в поддомейна. Може би звучи объркващо, но на мен точно това ми трябва.

Точно това не можах да го намеря в рамките, които поразаучих, или не точно по този начин, а аз си го представям точно така... 100% го има, просто аз не можах да открия това, което ми трябва.

И последната причина, за която пиша framework (но не на последно място) - опит. За 2 седмици научих толкова нови неща, аз за сефте ползвам сериозно exceptions примерно. Досега съм ползвал try/catch, но никога не съм се замислял моите класове да плюят изключения.


Титла: Re: [MVC] Основни положения
Публикувано от: ghoof в Dec 10, 2010, 23:27
Брех пичове много хубаво си хортувате тук, ама май забравяте нещо. А? А това дето забравяте е, че сте изостанали с 10 години. Поне. Казвам поне да не Ви обидя. За MVP да сте чували? Не не го измислил М$, а IBM и Aplle го ползва в своя Smalltalk даже. А там ясно си е казано- вюто няма никаква работа с модела. Да така се спестява код, ама това си е процедурно писане в обекти, а не нещо ползваемо. Така, че никаква работа на вюто и точка. И какви са тия песни вюто да определя де, какво да се вижда. Това си е работа на контролера. Всички глави го казват. Вюто (изгледа) единствено и само представя данни, нищо друго. Изобщо скучна работа- няколко цикли вместени в html на дизайнерчето. Кой, какво и кога има право да вижда си е работа само на контролера и никой друг. Той определя и какво да даде на модела и какво от него и къде да даде на изгледа. А пък модела от своя страна си сверява и валидира там, каквото са му подали, обработва и връща. Ей толкова е просто, ама тук яко мешате спатийте и правите глупости.


Титла: Re: [MVC] Основни положения
Публикувано от: VladSun в Dec 11, 2010, 00:41
Добре, че си ти да ме просветиш!

Какво според теб е MVP?!? Пак е MVC, но с различна имплементация ...
Спорове за това колко да е тънък/дебел комнтролерът, колко да е активeн/пасивeн изгледът и т.н. винаги ще има ... но пак ще е MVC!

Нещо неясно?



Титла: Re: [MVC] Основни положения
Публикувано от: VladSun в Dec 11, 2010, 00:49
На мен понякога ми харесва Изгледът да има пълен достъп до Модела ... всичко зависи от случая.
Пример:

Controller
Код
GeSHi (PHP):
  1. class User extends CollectionController
  2. {
  3.    ...
  4.    public function getUsers
  5.    {
  6.        $this->model = new UserCollectionModel();
  7.        $this->view('getUsers', $this->model);
  8.    }
  9. }

View:
Код
GeSHi (PHP):
  1. $model = new GridCollection($this->model);
  2. $users = $model->getAll();
  3. ...
  4. (... DO SOMETHING WITH $users ...)

Изненада:
Код
GeSHi (PHP):
  1. class GridCollection extends DecoratorCollection_Model
  2. {
  3.        public function  __construct($model, $conf = null)
  4.        {
  5.                parent::__construct(new FilteredCollection(new OrderedCollection(new LimitedCollection($model, $conf), $conf), $conf), $conf);
  6.        }
  7. }

Моделът се подавя на Изгледа, който решава какъв декоратор ще му сложи. Все пак странициране, подреждане и т.н. са функции на Изгледа, не на Модела или Контролера... Пример: csv, excel изгледите не се нуждаят от странициране/филтриране(по принцип)/подреждане, докате html/pdf и други такива се нуждаят от някои от тези функции.

Та ... MVP концепцията не би свършила работа в този случай.


Титла: Re: [MVC] Основни положения
Публикувано от: SylaR в Dec 16, 2010, 13:24
Здравейте,  имам проблем отностно локигата на MVC.Значи проверявам да ли потребителя е логнат и след това ме интересува във контролера ли да проверявам това или във view-то, т.е ако е логнат да ми се показва view-то с профила примерно а ако не е отново формата.

Код
GeSHi (PHP):
  1. if($this->session->userdata( ' is_logged_in ' )){
  2.      $this->load->view( ' profile ' );
  3.  }
  4.  else{
  5.      $this->load->view( ' login_view ' );
  6.  }

И ако го правя в контролера после във всеки метод на този контролер ли трябва
отново да проверявам? Моля за съвет нов съм в МVC и ползвам Codeigniter


Титла: Re: [MVC] Основни положения
Публикувано от: VladSun в Dec 16, 2010, 13:35
Аз бих създал клас наследник на Controller, който проверява дали потребителя е логнат или не (в конструктора).
След това всички контролери освен контролерът за login са наследници на този контролер и викат parent::__construct().

Може да разгледаш и това: http://www.linux-bg.org/forum/index.php?topic=38926.0


Титла: Re: [MVC] Основни положения
Публикувано от: ivo3d в Dec 16, 2010, 17:50
Брех пичове много хубаво си хортувате тук, ама май забравяте нещо. А? А това дето забравяте е, че сте изостанали с 10 години. Поне. Казвам поне да не Ви обидя. За MVP да сте чували? Не не го измислил М$, а IBM и Aplle го ползва в своя Smalltalk даже. А там ясно си е казано- вюто няма никаква работа с модела. Да така се спестява код, ама това си е процедурно писане в обекти, а не нещо ползваемо. Така, че никаква работа на вюто и точка. И какви са тия песни вюто да определя де, какво да се вижда. Това си е работа на контролера. Всички глави го казват. Вюто (изгледа) единствено и само представя данни, нищо друго. Изобщо скучна работа- няколко цикли вместени в html на дизайнерчето. Кой, какво и кога има право да вижда си е работа само на контролера и никой друг. Той определя и какво да даде на модела и какво от него и къде да даде на изгледа. А пък модела от своя страна си сверява и валидира там, каквото са му подали, обработва и връща. Ей толкова е просто, ама тук яко мешате спатийте и правите глупости.

Предвид, че apple ти казват и как имаш право да си държиш телефона, мисля, че щом са намесени в нещо е по-добре да не употребяваме думата "права". Освен това, нещо много си се объркал с броя на годините. А и всички известни рамки позволяват използването на модела в изгледа, което освен това е напълно логично.

Не мога да разбера какъв е точно проблемът - моделът предоставя информация, какъв е смисълът да копираш една информация в контролера и после да я пускаш на парчета (ами ако ми трябват 20 масива в една страница?) на изгледа, като можеш да му пратиш директно инстанцията на модела и във view-то да взимаш каквото ти трябва. Хем се спестява писане, хем бързодействие, хем памет. Няма никаква логика, освен начесване на OOP краста, да пишеш повече и да тормозиш сървъра. Рамката и без това достатъчно се грижи за влаченето на приложенията, поне нека я използваме за това, за което е предназначена - писане на по-малко код. Вярно, че няма смисъл да правиш нещо повече с модела от взимане на информация от него, ама все си мисля, че никой не би и тръгнал да прави друго, в противен случай очевидно работиш с идиоти.


Титла: Re: [MVC] Основни положения
Публикувано от: VladSun в Dec 16, 2010, 18:01
Има логика в това да се използва пасивен Изглед - използваемост на кода на Изгледа. По този начин Изгледа се "развързва" от Модела и може да се използва с други модели.
Но това е въпрос на лично предпочитание. Повечето от хората, които познавам ползват "чисто" MVC, а не MVP. Има и такив, които ползват MVP.

За мен Изгледът ще си остане винаги само "Декоратор" на Модела.

Неща от типа:

Код
GeSHi (PHP):
  1. class Controller
  2. {
  3.   function action()
  4.   {
  5.       $this->model->action();
  6.       $this->view->load('action', new View_Action_Array_Adapter($this->model));
  7.   }
  8. }

не ми харесват.


Титла: Re: [MVC] Основни положения
Публикувано от: ivo3d в Dec 17, 2010, 08:21
Имаш предвид да се използва един изглед за различни модели ли? То това са редки случаи, освен това, когато моделът в изгледа се казва например $model, стига интерфейсът да е един и същ, винаги можеш да подаваш различни модели... Освен ако не съм те разбрал правилно, както се случва обикновено при часовете, които започват с "0" :)


Титла: Re: [MVC] Основни положения
Публикувано от: VladSun в Dec 17, 2010, 12:34
Имаш предвид да се използва един изглед за различни модели ли? То това са редки случаи, освен това, когато моделът в изгледа се казва например $model, стига интерфейсът да е един и същ, винаги можеш да подаваш различни модели... Освен ако не съм те разбрал правилно, както се случва обикновено при часовете, които започват с "0" :)
Да, това имам предвид. Интерфейсът се "уеднаквява" чрез използването на Адаптери, както съм показал по-горе. Случаите наистина са рядкост (поне при мен). Макар че, като се замисля, винаги може да се използва Адаптер за самия Модел и пак да се "развърже" Изгледа от Модела - т.е. да се програмира по интерфейс.

Другото, което не ми харесва в MVP е, че трябва да се "пъхне" (push) информацията в Изгледа, а не той да си я "поиска" (pull) сам от Модела.


Титла: Re: [MVC] Основни положения
Публикувано от: ivo3d в Dec 17, 2010, 13:11
Другото, което не ми харесва в MVP е, че трябва да се "пъхне" (push) информацията в Изгледа, а не той да си я "поиска" (pull) сам от Модела.

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

Макар че има едно изключение, при което и в MVC трябва да пишеш повече - ако в изгледа използваш една информация няколко пъти, модела ти трябва да кешира информацията, в противен случай изпълняваш една заявка същия брой пъти. Но това също не се случва чак толкова често, така, че пак плюсът е за MVC.


Титла: Re: [MVC] Основни положения
Публикувано от: ivo3d в Dec 17, 2010, 13:22
А, и още нещо, което пропуснах, нищо, че е малко offtopic:

ghoof, преди да се изкаваш компетенто, моля промени си малко стила на писане и понамали малко заяжданията. Тази тема е създадена за да коментираме MVC (както може би си забелязал в заглавието) и по-специално теоретичната част, а не кой използвал архаични технологии, колко сме били изостанали и бабената ти трънкена. Като си толкова добре запознат с MVP, пускаш една тема в раздела, в която разасняваш какво представлява, плюсовете спрямо MVC и т.н., а не да нападаш в типично тийнеджърски стил "аз съм мноооо голям, а вие сте смешни".

- Иво


Титла: Re: [MVC] Основни положения
Публикувано от: SylaR в Dec 17, 2010, 15:01
Аз бих създал клас наследник на Controller, който проверява дали потребителя е логнат или не (в конструктора).
След това всички контролери освен контролерът за login са наследници на този контролер и викат parent::__construct().

Може да разгледаш и това: http://www.linux-bg.org/forum/index.php?topic=38926.0


По принцип правилно ли съм се насочил към CI ? Когато избирах с какво да почна като + се изтъква много пълната документация  също че бил бърз лек и тн...


Титла: Re: [MVC] Основни положения
Публикувано от: VladSun в Dec 17, 2010, 15:26
В момента аз съм изоставил CI и ползвам Zend Framework.
CI ми хареса в началото и доста пописах с него. Така че, когато се появи въпрос за CI все още имам ресурс да помагам :)
CI се научава сравнително лесно според мен, което е друг голям плюс. Попиши малко с него и сам ще решиш дали ти харесва или не. Рано или късно ще минеш на нещо друго :)


Титла: Re: [MVC] Основни положения
Публикувано от: ivo3d в Dec 17, 2010, 15:39
Като за начало е добре, та даже и за постоянно ползване. Там не ми харесва че все още не е изцяло OOP, и повечето неща са направени съвместими с php4. Но пък има страхотна документация и бързо ще навлезеш.

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

VladSun, евала ти правя, аз с тоя хипопотам не можах да се оправя. Прекалено тромав ми е, а и това едно нещо да можеш да го направиш по 10000 начина нещо не ми се понрави. Въпрос на вкус де, а и може би си по-напред в материала.


Титла: Re: [MVC] Основни положения
Публикувано от: SylaR в Dec 20, 2010, 12:39
Здравейте правя http://www.ifadey.com/2010/06/crud-using-jquery-and-codeigniter/ това обаче имам питана относно json защо в урока използва echo не е ли грешно или идва от това че се ползва и jquery tpl ?
Код
GeSHi (PHP):
  1. public function read() {
  2. echo json_encode( $this->mUsers->getAll() );
  3. }


и това е във view-то
Код
GeSHi (HTML):
  1. <script type="text/template" id="readTemplate">
  2.        <tr>
  3.            <td>${id}</td>
  4.            <td>${name}</td>
  5.            <td>${email}</td>
  6.        </tr>
  7.    </script>


Извинявам се, ако линка е в разрез с правилата просто за по-удоно


Титла: Re: [MVC] Основни положения
Публикувано от: VladSun в Dec 20, 2010, 13:51
Правилно си забелязал, че е грешно :)
Би трябвало да е поне:


Код
GeSHi (PHP):
  1. class Home extends Controller {
  2.  
  3. public function __construct() {
  4. parent::__construct();
  5. $this->load->model( 'mUsers' );
  6. }
  7.  
  8. public function index()
  9. {
  10. $this->load->view( 'home' );
  11. }
  12.  
  13. public function read() {
  14. $this->load->view('json', array('data' =>$this->mUsers->getAll()));
  15. }
  16. }

/views/json.php
Код
GeSHi (PHP):
  1. echo json_encode( $data );



Титла: Re: [MVC] Основни положения
Публикувано от: SylaR в Dec 20, 2010, 23:14
А нещо като добра литература(книги видео уроци) освен юсър гайда, може ли да ми препоръчате защото ми е по-лесно нещо да го видя като пример в реална ситуация


Титла: Re: [MVC] Основни положения
Публикувано от: b2l в Aug 16, 2012, 14:12
Къде се ползва Ajax в цялата MVC архитектура?


Титла: Re: [MVC] Основни положения
Публикувано от: senser в Aug 16, 2012, 16:39
Къде се ползва Ajax в цялата MVC архитектура?

В изгледа (V, view) накратко казано.
Контролерът (C, controller) връща отговорът на ajax request-a, но като цяло самия request и обработката на данните от него са в изгледа.


Титла: Re: [MVC] Основни положения
Публикувано от: b2l в Aug 16, 2012, 16:52
А ако искам да използвам json къде трябва да го рендирам? В другите "системи" имам един service.php (примерно), който ми връща като резултат json и аз после правя каквото си искам с данните, а при MVC-то?


Титла: Re: [MVC] Основни положения
Публикувано от: senser в Aug 16, 2012, 17:04
А ако искам да използвам json къде трябва да го рендирам? В другите "системи" имам един service.php (примерно), който ми връща като резултат json и аз после правя каквото си искам с данните, а при MVC-то?

При мен (CakePHP) съм го направил така:
Всеки контролер наследява базовия за фреймуърка AppController. В него (AppController) имам callback bеforeRender(), който се изпълнява преди предаването на данните към изгледа (view). Във въпросния callback проверявам, дали request-a идва от AJAX (XHR), ако е така данните се предават към един общ изглед (view), в който просто правя
Код:
echo json_encode($jsonData); //$jsonData е сетната в контролера

По този начин не ми се налага във всеки един контролер поотделно да проверявам дали да върна JSON или html - така или иначе всички ajax calls, които правя очакват да работят с JSON, както и няма нужда за всяко действие в контролера да имам отделен изглед, а ползвам един общ.


Титла: Re: [MVC] Основни положения
Публикувано от: b2l в Aug 16, 2012, 17:13
Благодаря за отговора :).


Титла: Re: [MVC] Основни положения
Публикувано от: borovaka в Aug 16, 2012, 20:31
Ммм щом очакваш различно предтавяне на еднакви данни, според мен е най-добре да се запознаеш с decorator шаблона. Можеш да го реализираш по различни начини в контекта на MVC.


Титла: Re: [MVC] Основни положения
Публикувано от: nickbass в Sep 30, 2012, 20:13
http://www.agavi.org/ ($2)

Един невероятно добре измислен MVC фреймуорк. Много гъвкав, достатъчно лек и без малоумните "автоматизации" на разни Симфонии и тем подобни, които уж ти пишат сами 90% от кода, а ти стъжняват живота с останалите 10% и то за елементарни неща, което всъщност не съкращава, а увеличава development time. :) Генерирате си проекта и имате ОСНОВАТА за приложение, в което САМИ да решавате кое как да става, а не да се борите как да хакнете феймуорка заради някое специфично дребно изискване.