diff --git a/src/index.ts b/src/index.ts
index 8d0ea14996d5a09e4f99b346a447901c6aeaa3a2..f904a4e2888d429cf7ea21fe4a2ed3d091308033 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -27,6 +27,7 @@ export * from "./util/result";
 export * from "./util/resultelement";
 export * from "./util/pair";
 export * from "./util/interval";
+export * from "./util/observer";
 export * from "./pab/pab_dimension";
 export * from "./pab/pab_puissance";
 export * from "./util/iterator";
diff --git a/src/nub_factory.ts b/src/nub_factory.ts
index 2301efbb517ff5b4c9398b2e37954370e238685d..56a6a1287fde232880e405d22be2e21d9bf32455 100644
--- a/src/nub_factory.ts
+++ b/src/nub_factory.ts
@@ -268,4 +268,8 @@ export class NubFactory {
                 throw new Error(`type de section ${ComputeNodeType[nt]} non pris en charge`);
         }
     }
+
+    // public get sessionNubIterator(): IterableIterator<SessionNub> {
+    //     return this._session[Symbol.iterator](); // crée un itérateur à partir d'un tableau
+    // }
 }
\ No newline at end of file
diff --git a/src/session_nub.ts b/src/session_nub.ts
index faf6c1226d92132ca8e86dece9df74e0b3860e01..d1f320d1505063d53fcfcd41ea0d9d2c8aaa32cf 100644
--- a/src/session_nub.ts
+++ b/src/session_nub.ts
@@ -1,10 +1,16 @@
 import { Nub } from "./nub";
+import { IObservable, Observer, Observable } from "./util/observer";
 
 /**
  * gestion d'un ensemble de propriétés (clé/valeur)
  */
-export class Props {
-    constructor(private _props: any = {}) { }
+export class Props implements IObservable {
+    // implémentation de IObservable par délégation
+    private _observable: Observable;
+
+    constructor(private _props: any = {}) {
+        this._observable = new Observable();
+    }
 
     public hasProperties(props: Props | {}): boolean {
         const keys = Object.keys(this._props);
@@ -24,8 +30,22 @@ export class Props {
         return this._props[key];
     }
 
-    public setPropValue(key: string, val: any): any {
-        this._props[key] = val;
+    private notifyPropChange(prop: string, val: any, sender: any) {
+        this.notifyObservers({
+            "action": "propertyChange",
+            "name": prop,
+            "value": val
+        }, sender)
+    }
+
+    public setPropValue(key: string, val: any, sender?: any): boolean {
+        const oldValue = this._props[key];
+        const changed = oldValue !== val;
+        if (changed) {
+            this._props[key] = val;
+            this.notifyPropChange(key, val, sender);
+        }
+        return changed;
     }
 
     public get props() {
@@ -38,6 +58,40 @@ export class Props {
             res._props[k] = this._props[k];
         return res;
     }
+
+    public toString(): string {
+        let res = "[";
+        for (const k in this._props) {
+            if (res != "[")
+                res += ", ";
+            res += `${k}:${this.props[k]}`;
+        }
+        res += "]"
+        return res;
+    }
+
+    // interface IObservable
+
+    /**
+     * ajoute un observateur à la liste
+     */
+    public addObserver(o: Observer) {
+        this._observable.addObserver(o);
+    }
+
+    /**
+     * supprime un observateur de la liste
+     */
+    public removeObserver(o: Observer) {
+        this._observable.removeObserver(o);
+    }
+
+    /**
+     * notifie un événement aux observateurs
+     */
+    public notifyObservers(data: any, sender?: any) {
+        this._observable.notifyObservers(data, sender);
+    }
 }
 
 /**
diff --git a/src/util/observer.ts b/src/util/observer.ts
new file mode 100644
index 0000000000000000000000000000000000000000..6a17beb902450e1e8f7da5c3d21023a49fd03fca
--- /dev/null
+++ b/src/util/observer.ts
@@ -0,0 +1,53 @@
+export interface Observer {
+    update(sender: any, data: any): void;
+}
+
+export interface IObservable {
+    /**
+     * ajoute un observateur à la liste
+     */
+    addObserver(o: Observer): void;
+
+    /**
+     * supprime un observateur de la liste
+     */
+    removeObserver(o: Observer): void;
+
+    /**
+     * notifie un événement aux observateurs
+     */
+    notifyObservers(data: any, sender?: any): void;
+}
+
+export class Observable implements IObservable {
+    private _observers: Observer[];
+
+    constructor() {
+        this._observers = [];
+    }
+
+    /**
+     * ajoute un observateur à la liste
+     */
+    public addObserver(o: Observer) {
+        if (this._observers.indexOf(o) == -1)
+            this._observers.push(o);
+    }
+
+    /**
+     * supprime un observateur de la liste
+     */
+    public removeObserver(o: Observer) {
+        this._observers = this._observers.filter(a => a !== o);
+    }
+
+    /**
+     * notifie un événement aux observateurs
+     */
+    public notifyObservers(data: any, sender?: any) {
+        if (sender == undefined)
+            sender = this;
+        for (let o of this._observers)
+            o.update(sender, data);
+    }
+}