Неизменяемый_объект(Immutable object):[Паттерн]

craz

Нестандартное звание
Примеры использования?
Я вообще не понимаю по сути данной конструкции в php. Так впринципе если мое приложение готово к продакшену то финализировать надо все методы всех классов. Это не даст возможность переопределять существующие методы, в тоже время если мы имеем к примеру:
PHP:
<?php
class BaseClass {
   public function test() {
       echo "Вызван метод BaseClass::test()\n";
   }
   
   final public function moreTesting() {
       echo "Вызван метод BaseClass::moreTesting()\n";
   }
}

class ChildClass extends BaseClass {
   public function moreTestingOther() {
       echo parent::moreTesting();
       //some code
   }
}
То мы просто обратимся к методу родителя и продолжим строить архитектуру дальше.
С финализированным классом более менее понятно, раз написал и уже все.

Так зачем может применяться этот паттерн, для понимания нужны практические примеры из рабочего кода.
P.s. решил я вплотную заняться самообразованием(ну то есть образованием себя с помощью вас)), так что это не первый вопрос, поэтому главное терпение))
 

Ragazzo

TDD interested
это нужно для того же value-object, основная цель которого просто служить data-container, а при любых операциях с ним должен порождаться новый value-object. У тебя пример не совсем корректный. В какой-то книжек по XP был пример с проектировкой системы денежного обмена.
P.S. самообразование это хорошо, да :)
 

craz

Нестандартное звание
это нужно для того же value-object, основная цель которого просто служить data-container, а при любых операциях с ним должен порождаться новый value-object. У тебя пример не совсем корректный. В какой-то книжек по XP был пример с проектировкой системы денежного обмена.
P.S. самообразование это хорошо, да :)
это пример чуть измененный из http://php.net/manual/ru/language.oop5.final.php, я его не исполнял к своему стыду
Как я уже давно понял... не все что написано в мане есть непреложная истина?)

Можешь чуток хотя бы псевдокодом объяснить, что ты написал, мне трудно представлять такие высокие абстракции пока/всегда - моск походу так устроен.
 

cDLEON

Онанист РНРСlub
Если бы в ПХП тип стринг был объектом, то он как раз был бы Immutable.
PHP:
$string = 'asdfgh';
$string2 = $string;
$string = 'new value'; 
echo $string, $string2;
// asdfghnew value
В тоже время, если захотеть, что бы string стал mutable, можно передать ссылку.
PHP:
$string = 'asdfghh';
$string2 = &$string;
$string = 'new value';
echo $string, $string2;
// new valuenew value
http://ru.wikipedia.org/wiki/Неизменяемый_объект
 

Ragazzo

TDD interested
craz
вон cDLEON верно тоже подметил. по сути единственная цель данных объектов просто служить для "переноски" данных, они в основном и появляются то после нескольких рефакторингов и замен массивов на объекты и т п. Но они так же могут быть "изменяемы", но должны возвращать новый объект того же типа, а не скрыто изменять свое состояние.
 

флоппик

promotor fidei
Команда форума
Партнер клуба
Всякие файналы пришли из явы, где с помощью них объявляют всякое ненаследуемое и неизменяемое (в том числе — константы, sic!). Это нужно, когда у тебя есть публичный интерфейс, без исходников и ты например, запрещаешь в нем перекрыть некоторые методы. В пхп польза от файнала сомнительна, ибо можно лазать ручками в код. // мистика бле, не надо держать кучу вкладок больше
 

craz

Нестандартное звание
Все таки я нашел пример https://github.com/zendframework/zf2/blob/master/library/Zend/Version/Version.php
Только вопрос все ж таки, получается исходя из этого ограничение накладывается по сути на создание класса Version в пространстве
PHP:
namespace Zend\Version
или его наследования в других частях приложения. Каков все таки профит от этого? Ведь ну предположим чУдное, мы еще один фреймворк подключили, а там нету ничего такого, то нам прям явно придется копипастить эту функцию так?
 

craz

Нестандартное звание
PHP:
class Foo{
    
    final public function setA($a){
        echo "Foo:A";
    }
    final public function setB(){
        echo "Foo:B";
    }
        
}
class Bar extends Foo{
    public function __call($name, $arguments) {
        echo $name;
        print_r($arguments);
    }        
    public function setB(){
        echo "Bar:B";
    }
}

$bar = new \Bar;
$bar->setA("SDASD");
ошибка
PHP:
class Foo{
    
    final public function setA($a){
        echo "Foo:A";
    }      
}
class Bar extends Foo{
    public function __call($name, $arguments) {
        echo $name;
        print_r($arguments);
    }        
    
}

$bar = new \Bar;
$bar->setA("SDASD");
нет ошибки

Это приводит меня к выводу, что когда добавляли то добавили только ради ООПешности, чтобы было как у всех. По сути бесполезная конструкция и паттерн в php.
 

craz

Нестандартное звание
PHP:
final class Str{
    private $_value;
    
    function __toString() {
        return $this->_value;
    }
    public function __get($name) {
        $this->_value = (string) $name;
    }
}
$stringVar = new Str();      
$stringVar->ff;
echo $stringVar;
иммутабле стринг-объект)
 

cDLEON

Онанист РНРСlub
craz
Неа. Если я изменю значение твоего объекта в одном месте, оно поменяется везде
 

craz

Нестандартное звание
craz
Неа. Если я изменю значение твоего объекта в одном месте, оно поменяется везде
в том и смысл - смысла в финализированных классах в php нет, в Java возможно, что при таком поведении она даже не скомпилируется, наверное...

Я кстати не правильно написал это иммутабл-класс, а не объект. Пойду поковыряю, чтобы стал и объект)
 

craz

Нестандартное звание
PHP:
final class Str{
    private $_value;
    
    function __toString() {
        return $this->_value;
    }
    public function __get($name) {
        if ($this->_value === null && $name != "null"){
            $this->_value = (string) $name;
        }elseif($name == "null"){
            throw new Exception("This object can not be NULL");
        }else{
            throw new Exception("This object alredy created");
        }
        
    }
}
Как то так.
 

Вурдалак

Продвинутый новичок
final можно использовать когда, например, интерфейс ещё полностью не устаканился и хочется запретить наследоваться с целью сохранения обратной совместимости для будущих версий, поскольку даже добавленный опциональный параметр сломает наследников. Открытый там код или нет разницы не имеет — изменяя код библиотеки в обход upstream'а, ты лишаешься возможности ругаться на отсутствие обратной совместимости.
 
  • Like
Реакции: craz

craz

Нестандартное звание
Вурдалак
Ну вот, наверное, это и есть единственное применение. Спасибо.
 
Сверху