Protected mutators (setters)

288 views Asked by At

Problem

Suppose you have a class user. You want to be able to return this user object to others so they can use it to extract information using getters. However, you don't want people to be able to readily set the internal state because the internal information should directly relate to a row in the database. Does it make sense to have protected mutators (setters) so that only an extended class could set the variables? Is this a bad practice, irrelevant, overkill or useless?

I have considered trying to limit __construct to one use ( I believe this is sometimes refereed to as a singleton pattern - although I am not sure if I understand entirely. )

I am an amateur programer, forgive any ignorance. Thanks.

Example:

<?php

    class user
    {

    private username;

    protected function set_username($username)
    {
        $this->username = $username;
    }

    public function get_username()
    {
        return $this->username;
    }

?>
3

There are 3 answers

0
GordonM On BEST ANSWER

Depends. If nothing in particular needs to happen when the state is changed then you can leave the setters out altogether. Any subclass will have direct access to the properties that are set protected or looser.

If you need something to happen when the state changes (for example having a database UPDATE happen when the state changes) then the setters will make your life a lot easier, as the call to the database updating code be put in the setter. This means if you always go through the setter then the DB will always update when you change the object's state.

So in short, it depends.

0
hoppa On

If you have a constructor that accepts an id for instance, why would you want to have setters at all. There is no rule forcing you to give an object setters just because it has getters. If your usecase is constructing the object somewhere and after that only use it to extract data from it, simply create no setter at all.

Extending objects can manipulate the protected class variables itself so they don't require any form of setter as well. If you don't want the "outside world" to be able to set something to the class, don't allow it.

2
tuergeist On

Your code is totaly fine and IMHO it encapsulates perfectly. Tt also supports loose coupling.

For easier use, you can add all needed (must have) members as constructor parameters.

Regarding the singleton pattern, use it with care. Users in common aren't singletons. Refer to Refactoring to Patterns (Joshua Kerievsky).