Dissecting an MVC application

Loading...

Flash Player 9 (or above) is needed to view presentations.
We have detected that you do not have it on your computer. To install it, go here.

0 comments

Post a comment

    Post a comment
    Embed Video
    Edit your comment Cancel

    9 Favorites, 1 Group & 1 Event

    Dissecting an MVC application - Presentation Transcript

    1. Dissecting an MVC Application Stefan Priebsch, thePHP.cc php|tek 09, Chicago, U.S.A.
    2. Stefan Priebsch Co-Founder and Principal Consultant
    3.  
    4. MVC
    5. Model View Controller
    6. Model
    7. View
    8. Controller
    9.  
    10.  
    11. Separate logic and presentation
    12. Where to put business logic?
    13. Where to put validation?
    14. Lean controllers
    15. MVC Application Components
      • Front Controller
      • Router
      • Controller
      • View
      • Domain Model
    16.  
    17. The controller selects the view
      • class Controller { public function executeAction() { ... return new View(); } }
      • class Controller { public function executeAction() { ... return 'ViewName'; } }
    18. Decoupling the view
      • class MyView extends View { public function render(...) { .... } ... }
      • interface ViewInterface { public function render(); }
      • class MyView implements ViewInterface { public function render(...) { ... } }
      • class MyView extends SomeView implements ViewInterface { public function render(...) { return $this->toHtml(...); } }
      • class MyView implements ViewInterface { public function render(...) { $view = new SomeView(); return $view->toHtml(...); } }
    19. Request and Response objects
      • class Controller { public function executeAction() { $user = $_POST['username']; … header('Content-type: ...'); … } ... }
      • class Request { public function __construct (array $get, array $post, array $cookies, array $server, …) public function getGet($key) public function getPost($key) public function hasCookie($name) public function getCookie($name) public function getServer($key) … }
      • class Response { protected $httpStatus = 200; protected $contentType = 'text/html'; protected $charset = 'UTF-8'; protected $viewName; ... public function setStatus($status) { $this->httpStatus = $status; } public function getStatus() { return $this->httpStatus; } ... }
      • class Controller { public function executeAction($request, $response) { $user = $request->getPost('username'); … $response->setContentType(...); … } }
    20. Clearly separate data access from logic
      • class SomeController { public function executeAction() { … $domainObject = DomainObject::findById($id); ... } }
      • class DomainObjectManager { public function findById($id) { ... return new DomainObject($id, ...); } public function findAll() { … return array($obj, $obj, $obj, ...); } public function findBySomeCriteria(...) { … return array(...); } ... }
      • class SomeController { public function executeAction() { … $manager = new DomainObjectManager(); $domainObject = $manager->findById($id); ... } }
      • class SomeController { protected $manager; public function __construct(Manager $manager) { $this->manager = $manager; } public function executeAction() { … $domainObject = $this->manager->findById($id); ... } }
      • class SomeController { protected $manager; public function __construct(Manager $manager = null) { if (!is_null($manager)) { $this->manager = $manager; } else { $this->manager = new DomainObjectManager(); } } public function executeAction() { … $domainObject = $this->manager->findById($id); ... } }
      • class SomeControllerTest { public function testExecuteAction() { $manager = new MockDomainObjectManager() $controller = new SomeController($manager); $controller->execute(); ... } } class MockDomainObjectManager { public function getById($id) { return new DomainObject($id, ...); } }
    21. Testing the authentication controller
      • class AuthenticationController { public function loginAction() { session_start(); $_SESSION['username'] = 'Stefan'; } public function logoutAction() { session_start(); unset($_SESSION['username']); session_destroy(); } }
      • require 'PHPUnit/Framework.php'; class AuthContrTest extends PHPUnit_Framework_TestCase { public function testLogin() { $controller = new AuthenticationController(); $controller->loginAction(); $this->assertEquals('Stefan', $_SESSION['username']); } }
      • class AuthenticationController { public function __construct($session) { $this->session = $session; } public function loginAction() { $this->session->start(); $this->session->register('username', 'Stefan'); } public function logoutAction() { $this->session->start(); $this->session->unregister('username'); $this->session->destroy(); } }
      • class Session { public function start() { session_start(); } public function register($key, $value) { $_SESSION[$key] = $value; } public function unregister($key) { unset($_SESSION[$key]); } public function destroy() { session_destroy(); } }
      • require 'PHPUnit/Framework.php'; class AuthContrTest extends PHPUnit_Framework_TestCase { public function testLogin() { $session = new Session(); $controller = new AuthenticationController($session); $controller->loginAction(); $this->assertEquals('Stefan', $_SESSION['username']); } public function testLogout() { $session = new Session(); $controller = new AuthenticationController($session); $controller->logoutAction(); $this->assertFalse(isset($_SESSION['username'])); } }
      • require 'PHPUnit/Framework.php'; class AuthContrTest extends PHPUnit_Framework_TestCase { public function testLogin() { $session = $this->getMock('Session'); $session->expects($this->once()) ->method('start'); $session->expects($this->once()) ->method('register') ->with('username', 'Stefan'); $controller = new AuthenticationController($session); $controller->loginAction(); } }
    22. Take-Aways Stefan's
    23. Stefan's Take-Aways
      • Strictly separate different concerns
        • No presentation in controller
        • No data access in controller or model
    24. Stefan's Take-Aways
      • Strictly separate different concerns
        • No presentation in controller
        • No data access in controller or model
      • Abstract from the global environment
        • Session, Request, and Response
    25. Stefan's Take-Aways
      • Strictly separate different concerns
        • No presentation in controller
        • No data access in controller or model
      • Abstract from the global environment
        • Session, Request, and Response
      • Unit test your MVC application
        • Use mock objects where possible
    26.  
    27.  
    28. http://www.thephp.cc Twitter: thephpcc [email_address] http://www.priebsch.de Twitter: spriebsch Xing, LinkedIn, Facebook
    29.  

    + Stefan PriebschStefan Priebsch, 6 months ago

    custom

    2367 views, 9 favs, 2 embeds more stats

    Almost every modern web application follows the MVC more

    More info about this document

    © All Rights Reserved

    Go to text version

    • Total Views 2367
      • 2031 on SlideShare
      • 336 from embeds
    • Comments 0
    • Favorites 9
    • Downloads 144
    Most viewed embeds
    • 330 views on http://www.priebsch.de
    • 6 views on http://www.mrkindy.com

    more

    All embeds
    • 330 views on http://www.priebsch.de
    • 6 views on http://www.mrkindy.com

    less

    Flagged as inappropriate Flag as inappropriate
    Flag as inappropriate

    Select your reason for flagging this presentation as inappropriate. If needed, use the feedback form to let us know more details.

    Cancel
    File a copyright complaint
    Having problems? Go to our helpdesk?

    Categories

    Groups / Events