implementing-the-notify-changetracking-policy.rst 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. Implementing the Notify ChangeTracking Policy
  2. =============================================
  3. .. sectionauthor:: Roman Borschel (roman@code-factory.org)
  4. The NOTIFY change-tracking policy is the most effective
  5. change-tracking policy provided by Doctrine but it requires some
  6. boilerplate code. This recipe will show you how this boilerplate
  7. code should look like. We will implement it on a
  8. `Layer Supertype <http://martinfowler.com/eaaCatalog/layerSupertype.html>`_
  9. for all our domain objects.
  10. Implementing NotifyPropertyChanged
  11. ----------------------------------
  12. The NOTIFY policy is based on the assumption that the entities
  13. notify interested listeners of changes to their properties. For
  14. that purpose, a class that wants to use this policy needs to
  15. implement the ``NotifyPropertyChanged`` interface from the
  16. ``Doctrine\Common`` namespace.
  17. .. code-block:: php
  18. <?php
  19. use Doctrine\Common\NotifyPropertyChanged;
  20. use Doctrine\Common\PropertyChangedListener;
  21. abstract class DomainObject implements NotifyPropertyChanged
  22. {
  23. private $listeners = array();
  24. public function addPropertyChangedListener(PropertyChangedListener $listener) {
  25. $this->listeners[] = $listener;
  26. }
  27. /** Notifies listeners of a change. */
  28. protected function onPropertyChanged($propName, $oldValue, $newValue) {
  29. if ($this->listeners) {
  30. foreach ($this->listeners as $listener) {
  31. $listener->propertyChanged($this, $propName, $oldValue, $newValue);
  32. }
  33. }
  34. }
  35. }
  36. Then, in each property setter of concrete, derived domain classes,
  37. you need to invoke onPropertyChanged as follows to notify
  38. listeners:
  39. .. code-block:: php
  40. <?php
  41. // Mapping not shown, either in annotations, xml or yaml as usual
  42. class MyEntity extends DomainObject
  43. {
  44. private $data;
  45. // ... other fields as usual
  46. public function setData($data) {
  47. if ($data != $this->data) { // check: is it actually modified?
  48. $this->onPropertyChanged('data', $this->data, $data);
  49. $this->data = $data;
  50. }
  51. }
  52. }
  53. The check whether the new value is different from the old one is
  54. not mandatory but recommended. That way you can avoid unnecessary
  55. updates and also have full control over when you consider a
  56. property changed.