About setters and getters

In a nutshell, not all the time.

I want to discuss their use.

Disclaimer

I know it is an old debate, but I do think it’s still worth it. This article reflects my opinion.

Basics

You might be familiar with the following code:

class Character {

    private $name;
    
    public function setName(string $name){
        $this->name = $name;
    }
    public function getName(){
        return $this->name;
    }
}

That’s what we call getters and setters. You don’t use them only to access private properties. That would be a weird use (some might even say a poor use). It allows adding a layer of validation around your data.

Murphy’s law

Anything that can go wrong will go wrong.

It’s good enough for your objects. If it can be misused, it will be misused. It happens a lot, mostly when you create mutable classes. In other words, it’s when you can change the state after the class creation:

$character = new Character();
$character->setName("Gokû");
$character->setName("Freezer");
echo $character->getName();// displays "Freezer"

Gokû is now Freezer. Universe 7 does not make sense anymore.

Not a big deal? Hum, you might be surprised. What about payments and e-commerce? Would you let something like that happen with money?

Do not allow crazy usages

Instead of using a setter in our code, we could use the constructor like that:

class Character {

    private $name;
    
    public function __construct(string $name){
        $this->name = $name;
    }
    public function getName(){
        return $this->name;
    }
}

$character = new Character("Gokû");
echo $character->getName();// displays "Gokû"

This way, the name gets injected when you create the object, and it’s immutable. There are no setters, and the attributes remain private.

When to use

One thing that might be unclear with this article is when to use setters and getters. We just saw setters are sometimes the wrong choice.

It’s not rare, especially for beginners, to consider setters and getters as a powerful way to encapsulate data. Well, in that perspective, if anybody can change your object’s state multiple times like that, it’s probably not a good idea.

So, it seems it breaks encapsulation?

To a certain extent and depending on your usage, yes, but the idea with accessors is to check values before applying them (setters), and to get values whenever you are and whatever processing is applied.

In other words, setters and getters are meant to allow only specific types and retrieve something you expect as a developer.

Object design

What is a good object design? It’s such a vast topic. We won’t talk about that specifically here cause I want this article to be short.

However, I would say it’s best if you don’t know implementation details, which is definitely not the case with setters and getters. You may read that post for more explanations.

Moreover, if you don’t have any validation layer, then setters and getters have very little interest.

Some IDEs (Integrated development environments) encourage the use of setters and getters, often with automating features (e.g. “set getters and setters for all properties”). While it’s undoubtedly handy (you don’t have to type all the things over and over), it is, IMHO, not ideal.

Some developers consider setters and getters as an anti-pattern.

Conclusion

IMHO, immutability is a better choice when it’s possible, so no setters. It’s especially useful for new developers in your team. They might introduce some bugs just because your class is mutable while it should not.

It does not mean you should never use setters (some developers say that, though). Don’t use them systematically, even if you think it solves your problem, it’s a trap.