[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Геттеры и сеттеры
Страницы: 1, 2
AlmazDelDiablo
chee, нет, сам этот объект ни о каком кэше знать не будет. Его getValue() просто обратится к некоему модулю, на который мы перевязываем логику. А уже тот, в свою очередь, обратится к кэшу или хранилищу/сервису с исходными данными. Плюс, прослоек кэша может быть несколько — сначала грузим по API данные от сервиса, кладём в БД (долгосрочный кэш), затем в какой-нибудь memcache (ненадёжный, но быстрый кэш).

А ручное сбрасывание кэша — это признак не очень хорошей архитектуры и в нашем случае добавляет лишнюю ответственность нашему $anyObject.

_____________
Блог | VK | GitHub | Twitch
chee
Цитата (AlmazDelDiablo @ 7.11.2014 - 10:11)
getValue()

что в ваших примерах должен возвращать этот метод, какие то сложные данные или просто атрибут модели?

_____________
Люди, имеющие низкий уровень квалификации, делают ошибочные выводы, принимают неудачные решения и при этом неспособны осознавать свои ошибки в силу низкого уровня своей квалификации
sergeiss
Дайте тоже поразглагольствую/позанудствую о пользе геттеров и особенно сеттеров smile.gif

Особенно хорошо знаком с ними по опыту работы с С++ (C++Builder, если уж совсем точным быть). Сеттер - очень удобная хрень. Потому что внутри этой функции можно:
1. Проверить корректность устанавливаемой величины и, в случае необходимости, скорректировать её.
Например, некая величина разрешена в диапазоне от 1 до 10. При попытке установить величину, большую 10, он будет все равно только 10.
2. Вызвать событие, связанное с изменением величины. Это может быть некое пользовательское событии, либо метод самого объекта.
Например, при установке свойства Active можно вызвать методы Open() или Close(), а также события BeforeOpen, AfterOpen, BeforeClose, AfterClose (когда какие, я думаю, понятно и без каментов smile.gif). Естественно, события будут вызваны (соответствующие им функции), если мы определим эти самые функции.

Геттер тоже может быть полезен, если мы хотим получать значение не некой "почти константы", а величину типа статуса, который может быстро меняться в зависимости от внешних условий и еще чего-нибудь. Тогда, фактически, не будет внутренней переменной, а будет определение этих внешних или других условий, получения статуса и его возврат вызывающему.
Опять же, если у нас есть сеттер для свойства, контролирующий и ограничивающий ввод данных (п.1 для сеттеров, что я написал чуть ранее), то мы тогда просто обязаны сделать геттер для этого свойства. Иначе просто не получится реализовать.

_____________
* Хэлп по PHP
* Описалово по JavaScript
* Хэлп и СУБД для PostgreSQL

* Обучаю PHP, JS, вёрстке. Интерактивно и качественно. За разумные деньги.

* "накапливаю умение телепатии" (С) и "гуглю за ваш счет" (С)

user posted image
Michael
AlmazDelDiablo, что ты предлагаешь в Yii для AR модели для каждого столбца еще и свой геттер создавать? cool.gif
Та ситуация с которой ты столкнулся и без переопределения __get() решаема, а во вне будет также использоваться $obj->value.

_____________
There never was a struggle in the soul of a good man that was not hard
bestxp
Цитата (Michael @ 7.11.2014 - 17:07)
AlmazDelDiablo, что ты предлагаешь в Yii для AR модели для каждого столбца еще и свой геттер создавать? cool.gif
Та ситуация с которой ты столкнулся и без переопределения __get() решаема, а во вне будет также использоваться $obj->value.

в yii не надо) там магия такая что есть либо validate() для проверки

либо если надо какую-то особую проверку реалтайм так сказать, то пишешь
setProperty($value) где Property название свойства и при

$obj->property оно будет вызвано автоматически, только там стоит учесть что надо будет где-то правильно его сохранить wink.gif
AlmazDelDiablo
Цитата (Michael @ 7.11.2014 - 18:07)
AlmazDelDiablo, что ты предлагаешь в Yii для AR модели для каждого столбца еще и свой геттер создавать?  cool.gif
При необходимости — да — каждому полю по геттеру/сеттеру.

Цитата (Michael @ 7.11.2014 - 18:07)
Та ситуация с которой ты столкнулся и без переопределения __get() решаема, а во вне будет также использоваться $obj->value.
Я тоже так думал. Только вот если посмотреть код CActiveRecord::__get(), то там можно заметить, что сначала проверяется, нет ли $this->attributes[$name] (и устанавливается напрямую, если есть), а только потом идёт вызов CComponent::__get(), в котором уже проверяется геттер/сеттер. А посему, полю AR нельзя сделать геттер/сеттер без перегрузки __get().

Мне это нужно было для поиска по логам, в которой хотелось сделать возможность поиска по коду уровня лога и по его буквенному наименованию. Однако, без лишних плясок в контролере (что совсем уж грустно), либо перегрузки __get() это сделать невозможно.

_____________
Блог | VK | GitHub | Twitch
Michael
Цитата (AlmazDelDiablo)
Я тоже так думал. Только вот если посмотреть код CActiveRecord::__get(), то там можно заметить, что сначала проверяется, нет ли $this->attributes[$name] (и устанавливается напрямую, если есть)

Ну вот надо сделать чтобы $this->attributes[$name] не заполнялся.
В yii1 лень смотреть, но там скорее всего также, но вот в yii2:
Таблица с 2-мя полями
fid1 	name
7 micha

И сгенерированная для нее по умолчанию модель.
Смотрим:
        $fi = Fields1::findOne(7);
var_dump($fi->attributes()); // ['fid1', 'name'] - атрибуты по умолчанию из схемы БД
var_dump($fi->name); // 'micha'

Теперь в классе модели добавляю геттер для name и переопределяю attributes():
    public function attributes()
{
return ['fid1'];
}

public function getName()
{
return 'somevalue';
}

Теперь:
        $fi = Fields1::findOne(7);
var_dump($fi->attributes()); // ['fid1']
var_dump($fi->name); // 'somevalue'


_____________
There never was a struggle in the soul of a good man that was not hard
chee
все таки доводы с инкапсуляцией для меня убедительны. Но все таки в некоторых случаях я решил не использовать сеттеры и гетторы. А именно во-внедрении зависимостей. Покажу на примере

<?php

namespace ExampleCMS\Module\Base;

class View
{

protected $headerTpl = 'tpls/header.php';
protected $footerTpl = 'tpls/footer.php';
protected $bodyTpl = 'tpls/body.php';
protected $layoutTpl = 'tpls/layout.php';

/**
*
@var \ExampleCMS\Application
*/

public $app;

}

свойство $app публичное, потому что в него будет установлен(с помощью DI) инстанс класса \ExampleCMS\Application, о чем явно свидетельствуют комментарии. Плюсамы такого подхода: производительность, меньше кода, автокомплит. Минусы: можно туда пихнуть что угодно.

На счет обычных служебных свойств объектов, то тут я решил использовать геттеры, но создавать их когда они будут только нужны.

Но для меня остается открытым вопрос о атрибутах моделей, когда у меня есть сущность ORM и мне нужно читать её свойства, генерация геттеров и сеттеров не кажется мне очень хорошим решением в моем случает. Я думал уже, о методе set/get, но бенчмарки показали что такой способ работает ненамного быстрее магии.

_____________
Люди, имеющие низкий уровень квалификации, делают ошибочные выводы, принимают неудачные решения и при этом неспособны осознавать свои ошибки в силу низкого уровня своей квалификации
chee
Короче, для работы с атрибутами модели, решил использовать методы set/get, а также магию для доступа к ним.
В коде это примерно выглядит так

class Model
{

/**
*
@var string
*/

protected $module;

/**
*
@var array
*/

protected $attributes = array();

/**
*
@var array
*/

protected $attributeSetters = array();

/**
*
@var array
*/

protected $attributeGetters = array();

/**
*
@return string
*/

public function getModule()
{
return $this->module;
}

public function setModule($module)
{
$this->module = $module;
}

/**
*
@param string $name
*
@param mixed $value
*/

public function set($name, $value)
{
if (isset($this->attributeSetters[$name])) {
$this->{$this->attributeSetters[$name]}($value);
} else {
$this->attributes[$name] = $value;
}
}


/**
*
@param string $name
*
@return mixed
*/

public function get($name)
{
if (isset($this->attributeGetters[$name])) {
return $this->{$this->attributeGetters[$name]}();
}

if (!isset($this->attributes[$name])) {
return null;
}

return $this->attributes[$name];
}

public function hydrate(array $array)
{
foreach ($array as $name => $value) {
$this->set($name, $value);
}
}


public function __get($name)
{
return $this->get($name);
}

public function extract()
{
return $this->attributes;
}

}



что бы объявить кастомный getter/setter в соответствуйщий массив нужно затолкать ключ(название атрибута) = значение(название метода). Зделано это для того что бы сэкономить процессорное время, так как php очень много сил тратит на функции и не так много на работу с данными.

_____________
Люди, имеющие низкий уровень квалификации, делают ошибочные выводы, принимают неудачные решения и при этом неспособны осознавать свои ошибки в силу низкого уровня своей квалификации
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2025 Invision Power Services, Inc.