[Subversion] / ObjectRoles / README.txt  

Diff of /ObjectRoles/README.txt

Parent Directory | Revision Log

version 2347, Thu Jul 12 23:07:45 2007 UTC version 2395, Fri Oct 26 14:16:23 2007 UTC
Line 2 
Line 2 
 Separating Concerns Using Object Roles  Separating Concerns Using Object Roles
 ======================================  ======================================
   
 (New in version 0.6: ``ClassRole.for_frame()``, ``Registry``)  This project has been superseded by the ``AddOns`` package; as it turns out,
   the term "add-on" is a much better way to describe what the package does.
   This final release is just a stub that wraps the ``AddOns`` package to provide
   a backward-compatible API.
   
   Please use the `AddOns`_ package in future, by performing the following renames
   in your code::
   
       Old Name            New Name
       ---------------     ----------------
       peak.util.roles     peak.util.addons
       Role                AddOn
       ClassRole           ClassAddOn
       roledict_for        addons_for
       role_key            addon_key
   
 In any sufficiently-sized application or framework, it's common to end up  And of course, you should change your ``install_requires`` to depend on
 lumping a lot of different concerns into the same class.  For example, you  ``AddOns`` instead of ``ObjectRoles``.
 may have business logic, persistence code, and UI all jammed into a single  
 class.  Attribute and method names for all sorts of different operations get  .. _AddOns: http://pypi.python.org/pypi/AddOns/
 shoved into a single namespace -- even when using mixin classes.  
   .. contents:: **Table of Contents**
 Separating concerns into different objects, however, makes it easier to write  
 reusable and separately-testable components.  The ObjectRoles package  NOTE: The remainder of this document is here to keep testing in place for the
 (``peak.util.roles``) lets you manage concerns using ``Role`` classes.  old API.
   
 ``Role`` classes are like dynamic mixins, but with their own private attribute  
 and method namespaces.  A concern implemented using roles can be added at  
 runtime to any object that either has a writable ``__dict__`` attribute, or  
 is weak-referenceable.  
   
 ``Role`` classes are also like adapters, but rather than creating a new  
 instance each time you ask for one, an existing instance is returned if  
 possible.  In this way, roles can keep track of ongoing state.  For example,  
 a ``Persistence`` role might keep track of whether its subject has been saved  
 to disk yet::  
   
     >>> from peak.util.roles import Role      >>> from peak.util.roles import Role
   
Line 48 
Line 51 
     saving      saving
     >>> Persistence(aThing).save_if_needed() # no action taken      >>> Persistence(aThing).save_if_needed() # no action taken
   
 This makes it easy for us to, for example, write a loop that saves a bunch of  
 objects, because we don't need to concern ourselves with initializing the  
 state of the persistence role.  A class doesn't need to inherit from a special  
 base in order to be able to have this state tracked, and it doesn't need to  
 know *how* to initialize it, either.  
   
 Of course, in the case of persistence, a class does need to know *when* to call  
 the persistence methods, to indicate changedness and to request saving.  
 However, a library providing such a role can also provide decorators and other  
 tools to make this easier, while still remaining largely independent of the  
 objects involved.  
   
 Indeed, the ObjectRoles library was actually created to make it easier to  
 implement functionality using function or method decorators.  For example, one  
 can create a ``@synchronized`` decorator that safely locks an object -- see  
 the example below under `Threading Concerns`_.  
   
 In summary, the ObjectRoles library provides you with a basic form of AOP,  
 that lets you attach (or "introduce", in AspectJ terminology) additional  
 attributes and methods to an object, using a private namespace.  (If you also  
 want to do AspectJ-style "advice", the PEAK-Rules package can be used to do  
 "before", "after", and "around" advice in combination with ObjectRoles.)  
   
   
 .. contents:: **Table of Contents**  
   
   
 Basic API  Basic API
Line 118 
Line 96 
 one (or is a new-style class with a read-only ``__dict__``), they are stored in  one (or is a new-style class with a read-only ``__dict__``), they are stored in
 a special dictionary linked to the subject via a weak reference.  a special dictionary linked to the subject via a weak reference.
   
 By default, the dictionary key is a one-element tuple containing the role  By default, the dictionary key is the role class, so there is exactly one role
 class, so that there is exactly one role instance per subject::  instance per subject::
   
     >>> aThing.__dict__      >>> aThing.__dict__
     {<class 'Persistence'>: <Persistence object at...>}      {<class 'Persistence'>: <Persistence object at...>}
Line 220 
Line 198 
       ...        ...
     AttributeError: 'NoDict' object has no attribute '__leech__'      AttributeError: 'NoDict' object has no attribute '__leech__'
   
 Of course, if an object doesn't have a dictionary *and* isn't weak-  Of course, if an object doesn't have a dictionary *and* isn't
 referenceable, there's simply no way to store a role for it::  weak-referenceable, there's simply no way to store a role for it::
   
     >>> ob = object()      >>> ob = object()
     >>> Leech(ob)      >>> Leech(ob)
Line 514 
Line 492 
 Alternately, you can pass a specific Python frame object via the ``frame``  Alternately, you can pass a specific Python frame object via the ``frame``
 keyword argument to ``for_enclosing_class()``, or use the ``for_frame()``  keyword argument to ``for_enclosing_class()``, or use the ``for_frame()``
 classmethod instead.  ``for_frame()`` takes a Python stack frame, followed by  classmethod instead.  ``for_frame()`` takes a Python stack frame, followed by
 any additional arguments needed to create the key.  any extra positional arguments needed to create the key.
   
   
 Class Registries  Class Registries (NEW in version 0.6)
 ~~~~~~~~~~~~~~~~  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   
 For many of common class role use cases, you just want a dictionary-like object  For many of common class role use cases, you just want a dictionary-like object
 with "inheritance" for the values in base classes.  The ``Registry`` base class  with "inheritance" for the values in base classes.  The ``Registry`` base class


Generate output suitable for use with a patch program
Legend:
Removed from v.2347  
changed lines
  Added in v.2395

cvs-admin@eby-sarna.com

Powered by ViewCVS 1.0-dev

ViewCVS and CVS Help