When to use Setters and Getters?

15

I'm studying OOP and in the encapsulation part I have a question about when to use getters and setters , besides being able to validate the parameter passed, what is the utility of using ?

I could just "get" the given by __construct .

Example:

public function __construct ($valor1 , $valor2) { 
    $this->valor1 = $valor1;
    $this->valor2 = $valor2;
}

and

function setValor($valor){
    $this-valor = $valor;
}
    
asked by anonymous 12.12.2014 / 07:50

3 answers

20

The visibility of a property ( public , private and protected ) is part of Concealment Concept >, which is important for achieving greater data consistency.

For example, the code below:

class Db_Table {

    public $dbAdapter;

    public function __constructor( Db_Adapter $dbAdapter ) {

        $this -> dbAdapter = $dbAdapter;
    }
}

Nothing prevents Cletus's asshole from catching this code from doing something like:

$this -> dbAdapter = 'Oi, eu sou o Goku!';

And send the pro space code by defining an anime endpoint in what should be an object that implements an interface to the database or extends that superclass.

This problem is resolved by changing the visibility of the property and creating a setter :

class Db_Table {

    private $dbAdapter;

    public function __constructor( Db_Adapter $dbAdapter ) {

        $this -> setAdapter( $adapter );
    }

    public function setAdapter( Db_Adapter $dbAdapter ) {

        $this -> dbAdapter = $dbAdapter;

        return $this;
    } 
}

And the code is now foolproof because the DB_Table :: $ dbAdapter property will invariably be an instance of Db_Adapter .

In addition setting the visibility of a property with private without a set set makes it read-only in the context of the object.

>

However, you can yes manipulate the private and protected visibility property value through Reflection :

$obj = new Db_Table( new Db_Adapter );

try {

    $reflector = new ReflectionProperty( 'Db_Table', 'dbAdapter' );

    $reflector -> setAccessible( TRUE );

    $reflector -> setValue( $obj, 'Oi, eu sou Goku!' );

    var_dump( $reflector, $obj );

} catch( ReflectionException $e ) {

    echo $e -> getMessage();
}

Though Reflection does not serve this purpose. u

Encapsulation is already a totally different animal. It involves the principle of code reuse (DRY - Do not Repeat Yourself) that does not exist only in Object Orientation.

Of course, simply creating a function to store a repetitive piece of code is already a form of encapsulation.

The difference is that with Object Orientation we have inheritance, composition, polymorphism, and all these strange words that elevates the potential of the encapsulation to the maximum of its potential.

Finally, the Validation you mentioned, already covered by the examples, is only possible through a setter because you can not have polymorphism or even conditionals in a public property. They accept whatever happens to them.

Original Author: Henrique Barcelos

    
12.12.2014 / 11:38
10

You use setters and getters to provide management of the attributes of your object. That is, you can change the object variables after it is created.

In contrast, by encapsulating the attributes and not creating getter and setter its object becomes fixed. That is, you will not be able to change the data once it has been created. You should pass the initial data in the constructor and after that they no longer change, since since the attributes are encapsulated ( private ) and you have not set any setter , you can not change them. Usually, in languages like Java the attributes are declared as final (in PHP I do not know if we can declare variables like end , only in methods and classes, and in that case indicate otherwise) to indicate that they are fixed. These cases are often used to create immutable classes, which do not change state during their existence.

Another reason, as you yourself commented, is to encapsulate the class data. One of the basic concepts of OO is just this, encapsulation . So if you leave your public properties, it does not make sense to use getter and setter , since it will not have encapsulation.

One of the most important points of the getter and setter is scalability . Imagine that you have a class with getter and setter and in several lines of your project you make use of the attribute directly, without getter or < in> setter . When you need to do a maintenance you would have to change all of these lines manually. Now if you had the getter and setter , you would only need to change the getter or setter function, and the reflect on all its uses.

For the same reason, using getter and setter is good for debug . Whenever you need to debug this attribute within your project, simply put a breakpoint in the getter or setter function instead of each line in that the property was used without the use of getter or setter .

    
12.12.2014 / 10:51
4

You'll have people think, "I know what I do, so I can leave the attributes public and that's it!"

Getters and Setters go way beyond that, let's look at some utilities:

To make validations:

public function setIdade($idade) 
{
    if ($idade < 0 || $idade > 200) {
        throw new InvalidArgumentException('Idade invalida');
    }

    $this->idade = $idade;
}

To provide a fluent interface, returning $ this

public function execute()
{
    # executa alguma coisa
    return $this;
}

To organize the presentation of information

public function getInformacoes()
{
    $informacoes = array('nome' => $this->nome,
        'idade' => $this->idade,
        'sexo' => $this->sexo,
        'identificacao' => $this->identificacao);

    return $informacoes;     
}

In the constructor must be passed what is necessary for that object to exist, for example, it does not make sense to have a birthday without a name and date of birth, then this data must be passed in the construction of the object, not after

Already gifts received, will be added or not later

class Aniversariante
{
    private $nome;
    private $dataNascimento;
    private $presentes;

    public function __construct($nome, $dataNascimento)
    {
        $this->nome = $nome;
        $this->dataNascimento = $dataNascimento;
    }
    public function addPresentes(Convidado $presente)
    {
        $this->presentes[] = $presente;
    }
}

One mistake that many make, is to leave all attributes as private, and create getters and setters for all these even without need. In this case, the attributes that are private, practically become "public", since it is possible to read and write in all.

Getters and setters should only be created if need be, otherwise the attributes will be exposed unnecessarily, leaking encapsulation.

    
28.01.2017 / 02:46