Is it worth making get and set methods in OOP?

12,369

Solution 1

Is it worth doing this way?

It depends.

Abstracting a field from the user by exposing a "smart" property (i.e. getter and/or setter) has two disadvantages:

  1. You need to write more code; if the property doesn't really do anything smart, this is code that does nothing useful.
  2. The user of the property is slightly inconvenienced because they have to type a little more as well.

And it has one advantage:

  1. In the future you can add logic to the properties even if there was none before without breaking your users' code.

If this advantage is meaningful (e.g. you are writing a reusable software library) then it makes great sense to write properties instead of bare fields. If not, you are doing work for no benefit.

What is the best way to handle such thing?

You can override the magic __get and __set functions (perhaps in a base class so you can inherit the override as well) to automatically forward property accesses to your getters and setters. Simplified code:

public function __get($name) {
    $getter = 'get'.$name;
    if (method_exists($this, $getter)) {
        return $this->$getter();
    }

    $message = sprintf('Class "%1$s" does not have a property named "%2$s" or a method named "%3$s".', get_class($this), $name, $getter);
    throw new \OutOfRangeException($message);
}

public function __set($name, $value) {
    $setter = 'set'.$name;
    if (method_exists($this, $setter)) {
        return $this->$setter($value);
    }

    $getter = 'get'.$name;
    if (method_exists($this, $getter)) {
        $message = sprintf('Implicit property "%2$s" of class "%1$s" cannot be set because it is read-only.', get_class($this), $name);
    }
    else {
        $message = sprintf('Class "%1$s" does not have a property named "%2$s" or a method named "%3$s".', get_class($this), $name, $setter);
    }
    throw new \OutOfRangeException($message);
}

Caveat emptor: Since __get and __set are overridden, __isset and __unset should be overridden as well!

Is there any security concerned doing it in this way?

No, none at all (assuming you don't insert bugs accidentally).

Solution 2

In languages that do not have properties (public member "variables" which actually lead to function calls) using getter/setters instead of public variables is usually recommended. Otherwise you cannot add logic (e.g. when setting a variable) later if people are already using your plain field.

Since PHP is such a language (unfortunately) the answer is yes, use them.

Solution 3

Making setters and getters helps enforce OOP encapsulation. Im not sure for PHP, but for many other languages (Java, C++), a good IDE (eclipse/netbeans) will auto-generate these setters and getters for you.

It may not be immediately obvious for simple types, but if any sort of more complex processing has to be performed, then it becomes more obvious.

Solution 4

An example as to why to sometimes use getters and setters: I have code that sets a value in 200 different files:

$cat->name = 'Fery'          // in file one
$favoriteCat->name = 'Tery'  // in another file
$fatCat->name = 'jery'             // in another file
// 200 more calls in alot of places

Imagine the customer suddenly has a new requirement: "all cat names must be prepended by 'Sweet'

Now we must find all declarations of cats and replace their assignments:

$cat->name = 'Sweet '.'Fery'
// times 200   

On the other hand, If we used a setter method all we need to do is add the code to add 'Sweet ' in one place:

public function setCatname($catname)
{
  $this->catName = 'Sweet ' . $catname;
}
Share:
12,369

Related videos on Youtube

Salman Khimani
Author by

Salman Khimani

merge delete

Updated on June 04, 2022

Comments

  • Salman Khimani
    Salman Khimani almost 2 years

    I have seen some some projects in which classes are having get and set methods to manipulate insert data. Let me have an example here :

        class Student extends dbClass
    {
        private $TableID;
        private $FullName;
        private $Gender;
        private $Address;
    
    
    
    
        function setTableID($Value)
        {
            $this->TableID = $Value;
        }
    
        function getTableID()
        {
            return $this->TableID;
        }
    
        function setFullName($Value)
        {
            $this->FullName = $Value;
        }
    
        function getFullName()
        {
            return $this->FullName;
        }
    
        function setGender($Value)
        {
            $this->Gender = $Value;
        }
    
        function getGender()
        {
            return $this->Gender;
        }
    
        function setAddress($Value)
        {
            $this->Address = $Value;
        }
    
        function getAddress()
        {
            return $this->Address;
        }
    
    
        function UpdateStudent()
        {
            $sql = "UPDATE INTO usertable SET
            FullName = '".$this->getFullName()."',
            Gender = '".$this->getGender()."',
            Address = '".$this->getAddress()."'
            where TableID='".$this->getTableID()."'";
            $this->query($sql);
        }
    }
    

    Above is the example class that i have seen. And below is the process how they are using it :

    $student = new Student;
    $student->setTableID = 1;
    $student->setFullName('My Name');
    $student->setGender('Male');
    $student->setAddress('this is my address');
    
    $studen->UpdateStudent();
    

    Is it worth doing this way? I personally think its useless to set field and then get and update records in it. It really takes a lot of time to make it for every module. What is the best way to handle such thing? Is there any security concerned doing it in this way?

    • mario
      mario almost 12 years
      Access modifiers (like private) are often misinterpreted as security feature. In their current C++ incarnation they were actually intended to constrain the ABI (not API) exposure; which isn't that relevant to PHP and scripting languages really. Requiring setters and getters is thus often a side-effect, but it's not very object-oriented. See also PHP Getters and setters: evil or necessary evil? and Java: Getters and setters are evil
  • ThiefMaster
    ThiefMaster almost 12 years
    They don't really improve OOP encapsulation but are rather a workaround for the lack of properties in a language.
  • Brady
    Brady almost 12 years
    @ThiefMaster, I think it does indeed help if any sort of logic/processing is necessary to store the value.
  • Salman Khimani
    Salman Khimani almost 12 years
    I dont think there will be any future logic in it. The people in my new company uses that for just performing database thing. They think its secure. I dont know how is it securing.
  • Waihon Yew
    Waihon Yew almost 12 years
    @SalmanKhimani: People are very bad at predicting the future. If it's company code, go for getters and setters and don't look back.
  • ThiefMaster
    ThiefMaster almost 12 years
    Yes, but they are still a nasty workaround. In python you can use public vars for example and simply create a property (which accesses custom getter/setter functions) if you ever need additional logic. In C# you create properties and either let the compiler create the "simple" getter/setter for it internally (you never see them and they are not actual functions you can call directly) and if you ever need custom logic, you simply implement those functions on your own. However, accessing the property - no matter if there are getter/setters or not - is always done via obj.prop like a variable
  • Brady
    Brady almost 12 years
    @ThiefMaster, Strictly speaking private vars dont exist in Python, but that's just a detail :) I understand your point, but in the languages I usually program in, I prefer to keep them. In general, I always like to have getters/setters for all attributes that can be set/got, thus making the class interface homogeneous for those that have logic and those that dont. This also keeps the class future-proof so you wont have to change the class interface in the future.