2009-02-11 2 views
1

В PHP, как лучше всего отслеживать состояние объектов, определить, было ли оно изменено? У меня есть объект репозитория, который создает новые сущности, затем они считываются/изменяются другими компонентами и в конечном итоге возвращаются в репозиторий. Если объект изменился, я хочу, чтобы репозиторий сохранил данные обратно в постоянное хранилище (БД).Отслеживание состояния объектов

я могу думать о четырех вариантах:

  1. Используйте внутреннее логическое свойство, называемое $ _modified, которые каждый сеттер обновления, когда сделаны изменения (утомительным, если есть много сеттеров).
  2. Некоторые ужасно некрасиво хак с помощью Serialize() и сравнения строк (я уверен, что это очень плохая идея, но я думал, я бы добавить для полноты картины)
  3. Что-то, как выше, но с хэш свойств объектов (не уверен, что он будет работать с объектами, которые содержат другие объекты)
  4. Взятие клонов объектов по мере их выхода из репо и сравнение того, что входит (более сложное, чем это звучит, поскольку вы знаете, клон для сравнения объекта?)

    или ...

  5. Некоторые другие умные трюки, о которых я не знаю?

Спасибо,
Джек

+0

После написания этого я начинаю думать, что № 1 является единственным жизнеспособным вариантом, если нет №5? –

ответ

3

Вариант 1 - с помощью булева флаг - это лучший способ. С точки зрения производительности, а также общего удобства и мобильности.

Все другие варианты несут чрезмерные накладные расходы, которые просто не нужны в этом случае.

+0

Да, вы абсолютно правы, спасибо. –

+0

fyi: флаг часто называют «грязным флагом». Если объект «грязный», он изменился с «последнего раза». –

+0

Не могу договориться подробнее. – Syntax

0

Я думаю, что первый вариант является лучшим для более читаемого кода и более быстрого выполнения. Я также рассмотрел бы сериализацию объектов сначала (скажем в файл), а затем хеширование содержимого.

То же самое содержимое должно содержать одно и то же значение хэш-функции.

1

Возможно, вы захотите заглянуть в шаблон Unit of Work, так как это большая проблема, с которой он предназначен. По мере изменения объектов они регистрируются или пассивно регистрируются с помощью UoW, который отвечает за отслеживание того, какие объекты были изменены, и для выяснения того, что нужно сохранить обратно в базу данных в конце игры.

1

Во-первых, я обычно считаю, что это исправленное или $ грязное свойство.

Но причина, я пишу твой комментарий, что было бы

утомительным, если есть много сеттеров

Я интересно, если вы не используете PHP5?

Если это так, это идеальное использование метода магии __set(). Вы даже можете использовать его как есть, вызывая существующие сеттеры из метода __set().

Например:

class some_concept 
{ 

    private $x = 1; 
    private $y = 2; 
    private $dirty = false; 

    // This represents your existing setter methods 
    function set_y($i) 
    { 
     $this->y = $i; 
    } 

    function __set($name, $value) 
    { 
     if ($value != $this->{$name}) $this->dirty = true; 

     return $this->{'set_' . $name}($value); 
    } 

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

Однако, есть некоторая заслуга вашей идее сравнения сериализованные строк. Сериализация может быть дорогостоящей. Это правда.

Но это наиболее точное решение в вашем списке. Представьте, что вы загрузили объект выше, установив $ y в 0, затем вернув его в 2, а затем сохраните. Это грязно? Он скажет так, но на самом деле он находится в том же состоянии, когда он был загружен.

Тестирование, которое я бы использовал здесь, насколько дорогим является ваше сохранение(). Если сохранение - очень дорогостоящий вызов API, транзакция DB и т. Д., То вы можете обнаружить, что стоит сериализовать объект на нагрузке и сохранить хеш-файл md5.

Если этот op, который займет долю секунды, может сохранить многосекундную транзакцию, тогда это действительно может стоить того.

Наконец, я хочу указать противоположное мнение по этому вопросу от Дэмиена Каца. Katz - талантливый разработчик, создавший CouchDb, и в настоящее время работает для MySQL.

Его сообщение Error Codes v Exceptions длинное, но очень хорошее читать на эту тему.

В то время как он начинает говорить о достоинствах возврата кода ошибки бросания Исключения, он действительно заканчивает разговор о том, как писать надежное программное обеспечение.

В первую очередь, он говорит о том, как создавать классы, которые являются атомарными так же, как и транзакции SQL. Общая идея заключается в том, что вы создаете копию объекта, изменяете его состояние и, только на последнем шаге, если это удастся, замените эту копию на основной объект. Это позволяет осмысленные функции отмены. Подобный шаблон, хотя и трудно подделать в существующее приложение, также обеспечивает решение этой проблемы is_modified.

Смежные вопросы