Лучший способ справиться с грязным состоянием в модели ORM

Я не хочу, чтобы кто-то говорил"you should not reinvent the wheel, use an open source ORM"; У меня есть немедленное требование и я не могу переключиться.

Я делаю небольшой ORM, который поддерживает кеширование. Даже не поддерживая кэширование, мне все равно понадобилась бы эта функция, чтобы знать, когда записывать объект в хранилище или нет. Шаблон является DataMapper.

Вот мой подход:

I want to avoid runtime introspection (i.e. guessing attributes). I don't want to use a CLI code generator to generate getters and setters (really I use the NetBeans one, using ALT+INSERT). I want the model to be the closest to a POPO (plain old PHP object). I mean: private attributes, "hardcoded" getters and setters for each attribute.

У меня есть абстрактный класс под названиемAbstractModel что все модели наследуют. У него есть публичный методisDirty() с закрытым (при необходимости может быть защищен) атрибутом is_dirty. Он должен возвращать истину или ложь в зависимости от того, есть ли изменение в данных объекта или нет с момента их загрузки.

The issue is: есть ли способ поднять внутренний флаг"is_dirty" без кодирования в каждом сеттере$this->is_dirty = true? Я имею в виду: я хочу, чтобы сеттеры$this->attr = $value Большую часть времени, кроме изменения кода, необходимо для бизнес-логики.

Другое ограничение заключается в том, что я не могу полагаться на__set потому что в конкретном классе модели атрибуты уже существуют как частные, так__set никогда не вызывается на сеттеров.

Есть идеи? Примеры кода от других ORM принимаются.

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

Еще одна мысль, которая у меня была, - создание сеттеров, а затем изменение имени частного атрибута подчеркиванием или чем-то подобным. Таким образом, сеттер будет вызывать__set и есть некоторый код, чтобы иметь дело с"is_dirty" флаг, но это немного нарушает концепцию POPO, и это ужасно.

Ответы на вопрос(3)

Ваш ответ на вопрос