Come fare MVC nel modo giusto [chiuso]

5

Ho fatto MVC da alcuni mesi usando il framework CodeIgniter in PHP, ma non so ancora se sto davvero facendo le cose per bene.

Quello che faccio attualmente è:

Modello : è qui che inserisco le query del database (selezionare, inserire, aggiornare, eliminare). Ecco un esempio di uno dei modelli che ho:

function register_user($user_login, $user_profile, $department, $role) {

    $department_id = $this->get_department_id($department);
    $role_id = $this->get_role_id($role);

    array_push($user_login, $department_id, $role_id);

    $this->db->query("INSERT INTO tbl_users SET username=?, hashed_password=?, salt=?, department_id=?, role_id=?", $user_login);
    $user_id = $this->db->insert_id();

        array_push($user_profile, $user_id);

    $this->db->query("
            INSERT INTO tbl_userprofile SET firstname=?, 
            midname=?, lastname=?, user_id=?
        ", $user_profile);
}

Controller - parla al modello, richiama i metodi nel modello che interroga il database, fornisce i dati che verranno visualizzati dalle visualizzazioni (avvisi di successo, avvisi di errore, dati dal database), eredita un controller genitore che controlla se l'utente è loggato. Ecco un esempio:

function create_user(){
    $this->load->helper('encryption/Bcrypt');
    $bcrypt = new Bcrypt(15);

     $user_data = array(
        'username' => 'Username', 'firstname' => 'Firstname',
        'middlename' => 'Middlename', 'lastname' => 'Lastname',
            'password' => 'Password', 'department' => 'Department', 
            'role' => 'Role'
    );

    foreach ($user_data as $key => $value) {
        $this->form_validation->set_rules($key, $value, 'required|trim');
    }

    if ($this->form_validation->run() == FALSE) {
        $departments = $this->user_model->list_departments();
        $it_roles = $this->user_model->list_roles(1);
        $tc_roles = $this->user_model->list_roles(2);
        $assessor_roles = $this->user_model->list_roles(3);

        $data['data'] = array('departments' => $departments, 'it_roles' => $it_roles, 'tc_roles' => $tc_roles, 'assessor_roles' => $assessor_roles);

        $data['content'] = 'admin/create_user';

            parent::error_alert();
            $this->load->view($this->_at, $data);

        } else {
        $username = $this->input->post('username');
        $salt = $bcrypt->getSalt();
        $hashed_password = $bcrypt->hash($this->input->post('password'), $salt);
        $fname = $this->input->post('firstname');
        $mname = $this->input->post('middlename');
        $lname = $this->input->post('lastname');
        $department = $this->input->post('department');
        $role = $this->input->post('role');

            $user_login     = array($username, $hashed_password, $salt);
            $user_profile   = array($fname, $mname, $lname);
        $this->user_model->register_user($user_login, $user_profile, $department, $role);

        $data['content'] = 'admin/view_user';

            parent::success_alert(4, 'User Sucessfully Registered!', 'You may now login using your account');


        $data['data'] = array('username' => $username, 'fname' => $fname, 'mname' => $mname, 'lname' => $lname, 'department' => $department, 'role' => $role);
        $this->load->view($this->_at, $data);
    }

}

Viste - questo è il posto in cui inserisco codice html, css e JavaScript (codice di convalida del modulo per il modulo corrente, looping dei dati forniti dal controller, alcune istruzioni if per nascondere e mostrare le cose a seconda dei dati forniti dal controller).

<!--User registration form-->
<form class="well min-form" method="post">
    <div class="form-heading">
        <h3>User Registration</h3>
    </div>

    <label for="username">Username</label>
    <input type="text" id="username" name="username" class="span3" autofocus>

    <label for="password">Password</label>
    <input type="password" id="password" name="password" class="span3">

    <label for="firstname">First name</label>
    <input type="text" id="firstname" name="firstname" class="span3">

    <label for="middlename">Middle name</label>
    <input type="text" id="middlename" name="middlename" class="span3">

    <label for="lastname">Last name</label>
    <input type="text" id="lastname" name="lastname" class="span3">

    <label for="department">Department</label>
    <input type="text" id="department" name="department" class="span3" list="list_departments">

    <datalist id="list_departments">
        <?php foreach ($data['departments'] as $row) { ?>
            <option data-id="<?php echo $row['department_id']; ?>" value="<?php echo $row['department']; ?>"><?php echo $row['department']; ?></option>
        <?php } ?>
    </datalist>

    <label for="role">Role</label>
    <input type="text" id="role" name="role" class="span3" list="">

    <datalist id="list_it">
        <?php foreach ($data['it_roles'] as $row) { ?>
            <option data-id="<?php echo $row['role_id']; ?>" value="<?php echo $row['role']; ?>"><?php echo $row['role']; ?></option>
        <?php } ?>
    </datalist>

    <datalist id="list_collection">
        <?php foreach ($data['tc_roles'] as $row) { ?>
            <option data-id="<?php echo $row['role_id']; ?>" value="<?php echo $row['role']; ?>"><?php echo $row['role']; ?></option>
        <?php } ?>  
    </datalist>

    <datalist id="list_assessor">
        <?php foreach ($data['assessor_roles'] as $row) { ?>
            <option data-id="<?php echo $row['role_id']; ?>" value="<?php echo $row['role']; ?>"><?php echo $row['role']; ?></option>
        <?php } ?>  
    </datalist>

    <p>
        <button type="submit" class="btn btn-success">Create User</button>
    </p>
</form>

<script>
    var departments = [];
    var roles = [];

    $('#list_departments option').each(function(i){
        departments[i] = $(this).val();
    });

    $('#list_it option').each(function(i){
        roles[roles.length + 1] = $(this).val();
    });

    $('#list_collection option').each(function(i){
        roles[roles.length + 1] = $(this).val();
    });

    $('#list_assessor option').each(function(i){
        roles[roles.length + 1] = $(this).val();
    });

    $('#department').blur(function(){

        var department = $.trim($(this).val()); 
        $('#role').attr('list', 'list_' + department);
    });

    var password = new LiveValidation('password');
    password.add(Validate.Presence);
    password.add(Validate.Length, {minimum: 10});
    $('input[type=text]').each(function(i){
        var field_id = $(this).attr('id');
        var field = new LiveValidation(field_id);
        field.add(Validate.Presence);
        if(field_id == 'department'){
            field.add(Validate.Inclusion, {within : departments});
        }
        else if(field_id == 'role'){
            field.add(Validate.Inclusion, {within : roles})
        }
    });
</script>

I codici sopra riportati sono in realtà codice dell'applicazione che sto attualmente lavorando. Ci sto lavorando da solo, quindi non ho davvero qualcuno che riveda il mio codice per me e indichi le cose sbagliate, quindi lo posterò qui nella speranza che qualcuno possa indicare le cose sbagliate che ho fatto qui. Sto anche cercando alcune linee guida per scrivere codice MVC come quelle che dovrebbero essere e non dovrebbero essere incluse in viste, modelli e controller. In quale altro modo posso migliorare il codice corrente che ho adesso. Ho scritto un codice veramente terribile prima (duplicazione della logica, ecc.) È per questo che voglio migliorare il mio codice in modo che possa mantenerlo facilmente in futuro. Grazie!

    
posta Wern Ancheta 09.07.2012 - 04:50
fonte

2 risposte

6
risposta data 09.07.2012 - 05:05
fonte
3

Sono un po 'un purista, penso. Per me, i modelli dovrebbero contenere tutta la logica necessaria per interagire con il modello dati, mentre il controller dovrebbe contenere la logica aziendale, manipolare i dati e quindi passare i dati alle viste. Le viste non dovrebbero contenere alcuna logica reale, anche se penso che la logica di visualizzazione (ad esempio se questo utente veda questo pulsante con l'etichetta A o l'etichetta B?) Sia ok.

Finora, il miglior esempio che ho trovato di questo è nel Framework Yii. Joomla, pur dichiarando di usare MVC, ha generalmente controller e modelli di grasso molto sottili: troppa dell'effettiva elaborazione avviene nel modello quando dovrebbe essere nel controller.

Alla fine, la logica deve andare dove si adatta meglio. Di tanto in tanto mi trovo a mettere la logica che non è strettamente interazione dei dati nel modello, ma di solito questa è una funzione statica che ho bisogno di chiamare da diversi altri controller. In questo caso, sento che il principio di DRY supera la struttura MVC pura. A volte c'è questo atto di bilanciamento, e alla fine è la chiamata del programmatore su cosa va dove.

    
risposta data 09.07.2012 - 05:55
fonte

Leggi altre domande sui tag