Immutable objects in PHP?

后端 未结 6 1272
暗喜
暗喜 2020-12-31 06:34

Is it a good idea to create objects that cannot be changed in PHP?

For example a date object which has setter methods, but they will always return a new instance of

6条回答
  •  盖世英雄少女心
    2020-12-31 07:25

    In my opinion objects should be immutable for value objects. Other than that it does not have much benefits unless you're sharing your object across your whole application.

    There is some wrong answers here, an immutable object can have setters. Here's some implementation of immutable objects in PHP.

    Example #1.

    class ImmutableValueObject
    {
        private $val1;
        private $val2;
    
        public function __construct($val1, $val2)
        {
            $this->val1 = $val1;
            $this->val2 = $val2;
        }
    
        public function getVal1()
        {
            return $this->val1;
        }
    
        public function getVal2()
        {
            return $this->val2;
        }
    }
    

    As you can see once instantiated you cannot changed any value.

    Example 2: with setters:

    class ImmutableValueObject
    {
        private $val1;
        private $val2;
    
        public function __construct($val1, $val2)
        {
            $this->val1 = $val1;
            $this->val2 = $val2;
        }
    
        public function getVal1()
        {
            return $this->val1;
        }
    
        public function withVal1($val1)
        {
            $copy = clone $this;
            $copy->val1 = $val1;
    
            return $copy;    // here's the trick: you return a new instance!
        }
    
        public function getVal2()
        {
            return $this->val2;
        }
    
        public function withVal2($val2)
        {
            $copy = clone $this;
            $copy->val2 = $val2;
    
            return $copy;
        }
    }
    

    There is several implementation possible and this is by no means an exclusive list. And remember that with Reflection there is always a way to get around that in PHP, so immutability is all in your head in the end!

    It is also often good practice to put immutable objects as final.

    EDIT:

    • changed setX for withX
    • added comment about final

提交回复
热议问题