#1
  1. Mad Scientist
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Oct 2007
    Location
    North Yorkshire, UK
    Posts
    3,661
    Rep Power
    4123

    Dependency Injection and Testable Code


    I've been trying to get my head round automated testing for a while now; and while I understand the concept my code is too tightly coupled to run any unit tests on at the moment - one would have to run it in the API mode and simulate requests...more like a series of system wide tests to test every eventuality rather than unit tests for individual blocks of code.

    Anyway, after my first found of regfactoring/pseudo coding I came up with this logic for creating a new user and would welcome anyone's thoughts...... my first question, however, is where would I put the code that currently sits in the add class - as this is supposed to only be the create class here.

    (I've decided to rebuild my form manager to behave more like a data service....I'll think about where to abstract the actual form html out to later)

    PHP Code:
    namespace \modules\user;

    class 
    add {

        public function 
    __construct($request,$response) {
            
    $this->request $request;
            
    $this->response $response;
        }
        
        public function 
    Execute() {
            
    $formService = \libs\forms\Factory::Load('NewUser'); //conceptualized only
            
    $model = \libs\models\Factory::Load('user');  //conceptualized only

            
    $c = new Create($formService,$model); //see below
            
            
    $c->Execute();
            
            
    $v $c->getView();
            
            
    $view = \views\Factory::Build($v);
            
            
    $view->setFormService($formService);
            
            
    $this->response->setView($view);

        }

    }

    class 
    create {

        public function 
    __construct($formService,$model) {
        
            
    $this->formService $formService;
            
    $this->model $model;
        
        }
        
        public function 
    Execute() {
            try {

                if(
    $this->formService->ready()) {

                    if(
    $this->formService->isValid()) {
                        
                        
    $data $this->formService->getData();
                        
                        
    $this->model->create($data);
                        
                        
    $this->view 'create-success';
                        
                        
                    } else {
                        throw new \
    libs\forms\formNotValidException();
                    }
                } else {
                    throw new \
    libs\forms\formNotSubmittedException();
                }

            } catch (\
    libs\forms\formNotValidException $fnse) {

                
    $this->view 'create-form-invalid';

            } catch (\
    libs\forms\formNotSubmittedException $fnve) {

                
    $this->view 'create-form-new';

            } catch (\
    Exception $e) {
                
    $this->view 'unexpected-exception';
            }
        }
        
        public function 
    getView() {
            return 
    $this->view;
        }


    I said I didn't like ORM!!! <?php $this->model->update($this->request->resources[0])->set($this->request->getData())->getData('count'); ?>

    PDO vs mysql_* functions: Find a Migration Guide Here

    [ Xeneco - T'interweb Development ] - [ Are you a Help Vampire? ] - [ Read The manual! ] - [ W3 methods - GET, POST, etc ] - [ Web Design Hell ]
  2. #2
  3. No Profile Picture
    Lost in code
    Devshed Supreme Being (6500+ posts)

    Join Date
    Dec 2004
    Posts
    8,317
    Rep Power
    7170
    One idea:
    PHP Code:
    <?php

        
    namespace ?
        {
            class 
    endpoint
            
    {
                protected 
    $request;
                protected 
    $response;
                protected 
    $viewFactory;
            
                public function 
    __construct($deps = [])
                {
                    
    $this->request = isset($deps['request']) ? $deps['request'] : singleton or factory load;
                    
    $this->response = isset($deps['response']) ? $deps['response'] : singleton or factory load;
                    
    $this->viewFactory = isset($deps['viewFactory']) ? $deps['viewFactory'] : singleton or factory load;
                }
            }
        };
        
        namespace 
    modules\user
        
    {
            class 
    create extends \?\endpoint
            
    {
                protected 
    $formService;
                protected 
    $model;
            
                public function 
    __construct($deps = [])
                {
                    
    parent::__construct($deps);
                    
                    
    $this->formService = isset($deps['formService']) ? $deps['formService'] : singleton or factory load;
                    
    $this->model = isset($deps['model']) ? $deps['model'] : singleton or factory load;
                }
                
                public function 
    Execute()
                {
                    
    code from old create::Execute
                    
                    
    // second argument to build is $deps for the view class constructor
                    
    $view $this->viewFactory->build($this->getView(), ['formService'$this->formService]);
                    
    $this->response->setView($view);
                }
            }
            
            public function 
    getView()
            {
                return 
    $this->view;
            }
        };
    PHP FAQ

    Originally Posted by Spad
    Ah USB, the only rectangular connector where you have to make 3 attempts before you get it the right way around
  4. #3
  5. Mad Scientist
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Oct 2007
    Location
    North Yorkshire, UK
    Posts
    3,661
    Rep Power
    4123
    I like where your thinking's going....I've worked out where to put the code....I've got an API only section (modules - create class above) and then packages (the add class above) which will use the API. I'll then interface a generic 'dataService', of which 'formService' will implement....that way the end point code will be agnostic to how it's been called.

    I think I'll then take the view stuff out and put it back into the 'package' and get the module code to return/set a status or state - which can then be tested for.

    It also reminds me that my production server is still using PHP 5.3...and you've peppered your response with the nice short array syntax introduced in 5.4
    I said I didn't like ORM!!! <?php $this->model->update($this->request->resources[0])->set($this->request->getData())->getData('count'); ?>

    PDO vs mysql_* functions: Find a Migration Guide Here

    [ Xeneco - T'interweb Development ] - [ Are you a Help Vampire? ] - [ Read The manual! ] - [ W3 methods - GET, POST, etc ] - [ Web Design Hell ]

IMN logo majestic logo threadwatch logo seochat tools logo