2

I've seen plenty of questions and answers on whether to use getters / setters or not (such as this popular one), but I've also seen two different styles of getters / setters and very little information on which pattern is preferable and why. The first is to use 1 getter and 1 setter per class, either through named methods or using magic methods (my examples use PHP as that's what I use day to day, but my question applies to any Object Orientated Language).

<?php
class Foo {

    private $bar;
    private $baz;

    public function get($property)
    {
        if (property_exists($this, $property))
            return $this->$property;
    }

    public function set($property, $value)
    {
        if (property_exists($this, $property))
            $this->$property = $value;
    }

}

The second is to use 1 method per property

<?php
class Foo {

    private $bar;
    private $baz;

    public function getBar()
    {
        return $this->bar;
    }

    public function setBar($value)
    {
        $this->bar = $value;
    }

    public function getBaz()
    {
        return $this->baz;
    }

    public function setBaz($value)
    {
        $this->baz = $value;
    }

}

For the life of me I can't think of any reason to have individual methods for each property. Even if you needed individual validation you could use a switch inside one method such as:

<?php
class Foo {

    private $bar;
    private $baz;

    public function get($property)
    {
        if (property_exists($this, $property))
            return $this->$property;
    }

    public function set($property, $value)
    {
        if (property_exists($this, $property))
        {
            switch ($property)
            {
                case 'bar':
                    $this->validateBar($value);
                    break;
                case 'baz':
                    $this->validateBaz($value);
                    break;
            }
            $this->$property = $value;
        }
    }

    private function validateBar( & $value)
    {
        // do some validation...
    }

    private function validateBaz( & $value)
    {
        // do some validation...
    }

}

Am I missing something or is there ever any need for one method per property? Is it just good practise to use one getter / setter per class?

Another option that has been brought up is the use of getsetters, a single function per property to alternatively get/set the value. I always thought this violated the single responsibility principle of SOLID, but as it's been given as an answer below I thought I would update the question to include it.

Community
  • 1
  • 1
Styphon
  • 10,304
  • 9
  • 52
  • 86
  • Do note that having one get/set per class could also be interpreted as violating the single responsibility principle since the set() function is now responsible for setting the bar property, and responsible for setting the baz property, perhaps with validation for either or both. Also, other OOP languages (like C#) have built-in syntax for creating get/set per property, like : `public baz { get;set; }`. – Heretic Monkey Aug 20 '15 at 15:30
  • See this question: http://stackoverflow.com/questions/6184337/best-practice-php-magic-methods-set-and-get – Master_ex Aug 21 '15 at 13:15

5 Answers5

1

I'd suggest to use separate getters and setters for each property, as you can type-hint setters, and docblock comment return values of each getter, making code much more understandable, and easier to edit when using an IDE (auto-completion, go-to declaration etc).

Valdas
  • 1,074
  • 13
  • 20
1

I am in favor of the second more verbal way but I think that this is more a matter of taste.

The pros of using getters/setters per property are:

  • Easier for other team members to read and understand
  • Easier to find usages of a specific setter/getter
  • Easier to search/find a getter/setter method from within your IDE
  • IDE autocomplete is better used
  • Not sure but possibly static analysis for bugs is more precise
  • Better understanding of a code revision when checking the history
  • I guess it's a bit faster than always calling property_exists()
  • You can write better/more precise documentation

Also, have in mind that if you always use getters/setters then you may as well make the properties public.

Otherwise, use getters/setters to provide limited access (provide only getter) or additional behavior i.e. setBar($value) will do $this->value = $value ; updateOtherData();

Master_ex
  • 789
  • 6
  • 12
0

IMO, it's much better to use one getter & setter per property. This promotes proper use of the object so that an invalid can't be used on the object.

It also enhances understanding of the object, as you can easily see what properties are available for the object. It's also clear what properties are read-only (i.e., it has a getter but no setter).

David G
  • 3,940
  • 1
  • 22
  • 30
0

It is recommended that you use setter / getter function per property to encapsulate each field of the class with proper functions, we can use one setter method in the constructor of the class.

eyadMhanna
  • 2,412
  • 3
  • 31
  • 49
  • Sorry, what do you mean "one setter method in the constructor of the class"? Can you expand on that please? – Styphon Aug 18 '15 at 14:16
  • the only time it is acceptable to use one setter method for all properties in a class is the constructor method, because we can use it to set new values for each property in the class. – eyadMhanna Aug 18 '15 at 14:19
0

Your second example is a common way. And for example Symfony2 actually creates such getters/setters for ORM entities.

Another interesting solution that results leaner code: Getsetters

  • Passing a param: Set-mode
  • Passing no param: Get-mode
  • Return on Set-mode: ALWAYS $this

So you code like this (almost like jQuery)

// Setting
$myobject->name('foo')
         ->age(26);
// Getting
echo $myobject->age();
class Foo {
    private $name;
    private $age;

    public function name($name = null) {
        if( ! is_null($name)) {
            $this->name = $name;
            return $this;
        } else {
            return $this->name;
        }
    }

    public function age($age = null) {
        if( ! is_null($age)) {
            $this->age= $age;
            return $this;
        } else {
            return $this->age;
        }
    }
}
Styphon
  • 10,304
  • 9
  • 52
  • 86
fabpico
  • 2,628
  • 4
  • 26
  • 43
  • Doesn't this break the single responsibility principle of SOLID though? – Styphon Aug 20 '15 at 14:37
  • The single responsibility in the SOLID principe is based on the **class**. A class must perform only one task, like being a service for Mails, or a DB connection, etc.. This has nothing to do which how you can setting/getting the object's properties. – fabpico Aug 21 '15 at 12:18