1 / 17

The Properties Pattern

Learn about the Universal Properties Pattern, a new way to design object models that allows for flexibility, scalability, and easy inheritance. This pattern is particularly useful for NoSQL databases and relational databases that need to handle variable user content.

Télécharger la présentation

The Properties Pattern

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. The Properties Pattern Based on http://steve-yegge.blogspot.com/2008/10/universal-design-pattern.html

  2. Introduction • Many names • Prototype • Property List • Properties Object • Adaptive Object Model • Bottom line • Seems like a low-level hack • Actually, a new way to look at the world

  3. Map API • get(key) • put(key, value) • has(key) • remove(key) • Also: keys()

  4. Properties Pattern API • Based on the Map API • Enhancement: a parent() link • Points at another Properties object • Supplies additional properties • Map method need to be adjusted

  5. public class PropList { private PropList parent; private Map<String, Object> map = new HashMap<String, Object>(); public PropList(PropList parent) { this.parent = parent; } public Object get(String key) { if(map.containsKey(key)) return map.get(key); if(parent != null) return parent.get(key); return null; } public void put(String key, Object value) { map.put(key, value); }

  6. public boolean has(String key) { return map.containsKey(key) || parent != null && parent.has(key); } public void remove(String key) { map.remove(key); } public Collection<String> keys() { List<String> result = new ArrayList<String>(); result.addAll(map.keySet()); if(parent != null) result.addAll(parent.keys()); return result; } public PropList parent() { return parent; } }

  7. Motivation • NoSql Databases (BigTable, HBase, …) • Relational DB: change resistant, do not scale well • New storage facilities are based on triplets: key, attribute, value • Property objects are the ideal in-memory counterpart • Flexible list of properties • Variable user content • When the logic is not interested in specific properties • It is interested in the relationship between the properties • Examples: A movie list browser, protein-peptide browser

  8. org.eclipse.jdt.core.dom.ASTNode Each AST node is capable of carrying an open-ended collection of client-defined properties. Newly created nodes have none. getProperty and setProperty are used to access these properties.

  9. Implementation • Representation of keys • String (almost always) • Arbitrary objects • Instances of a Key class • String + Numbers • Representation of key-value pairs • Linked list of pairs • Hashtable

  10. Deletion • Three alternative • Remove from current instance • Remove also from its complete parent chain • Remove replaces the value with a special “not here” value

  11. public class PropList { private static final Object NOT_HERE = new Object(); public void remove(String key) { map.put(key, NOT_HERE); } public Object get(String key) { if(map.containsKey(key)) { Object o = map.get(key); if(o == NOT_HERE) o = null; return o; } if(parent != null) return parent.get(key); return null; } // Similar changes in has() method

  12. Safety & Invariants • A parent is notified of put() actions on any child • Can veto the change

  13. public class PropList { public interface Interceptor { public Object onPut(PropList p, String key, Object value); } private List<Interceptor> interceptors = new ArrayList<Interceptor>(); public void addInterceptor(Interceptor i) { interceptors.add(i); } public void put(String key, Object value) { for(PropList p = this; p != null; p = p.parent) for(Interceptor i : p.interceptors) value = i.onPut(p, key, value); map.put(key, value); }

  14. Persistence • Quite easy if all values are primitive • E.g.: One key/value pair per line (Otherwise) • Maintain a unique id property (primitive or string) • Saving • If value is another PropList save its id • Loading • Build an id -> PropList map • In each PropList replace properties that hold an id with the actual reference • Maps nicely to a ternary table on a relational DB: id, key, value

  15. Motivation: Object-level inheritance • Sometimes we want to extend an object! • Here’s an existing instance • I want some new instance to be essentially the same as the existing one • Except for some additions, changes • When the existing instance changes I want the new ones to change as well • “I want that one” • “Inheritance by example”

  16. Example: Disabling of Menus

  17. Example: Disabling of Menus (cont.) • No open file -> Nine menu items are disabled • Class-level inheritance • A superclass, S, with setEnabled(boolean) method • Each menu item is an instance of this superclass • When a file is closed call setEnabled(false) on all nine instances • Object-level inheriance • A PropList object, x, with an "enabled" property • Each menu items is a PropList object, with x being the parent • When a file is closed: x.put("enabled", false)

More Related