Architectural Guidelines

Introduction

We are now in the process of consolidating what Agilo can do and make it available through new interfaces (via XML-RPC or JSON probably) as well as extend the core with some additional modules, that can be "sold" as separated. These Modules will be for now put in a separate repository, and called Enterprise and Pro versions. These projects are hosted in https://enterprise.hosted.agile42.com/ and developed in Partnership with some selected customers. Focus and informations on the Enterprise or the Pro version are available in that project wiki.

Needs

We have the need to define an architecture guidelines, may be our own API on top of Trac Component Model, cause we are starting to get lost in multitude of little and big modules that do not have a clear responsibility boundary. For example, in many places the web_ui modules, instead of being used only to manage specific Web Interface things and interact with some model objects, they actually end up doing a lot of things on models which do not belong to that specific web module at all.

Beside making the code harder to maintain, due to not very clear dependencies, it makes it also much more error prone, and it is a big impediment in terms of performance and optimization, cause we cant control from where a Model instance (or a Persistent Object) will be loaded. This affects of course the possibility of make some caching optimization for recurrently loaded objects.

We need to expose the core API as JSON or XML-RPC (not preferred, given envelope overhead) so that the Enterprise and Pro version can use the technology easily and decoupled as much as possible.

Ticket Business Value Summary Status Reporter
#654 2000 Define JSON distributed interfaces closed andreat
#655 2000 Define Object Identity caching closed andreat
#653 3000 Define Architecture Layers closed andreat

Ideas

We would have to think about separating the Controller portion of the Web Interface into a specific level, where can be used to interface also other media, via XML-RPC or other specific UI related formats. To achieve this we could build our own Agilo API, using the Trac Component Model approach, but implementing a set of Extension Points that can guarantee us that the architecture will stay clean and client independent as much as possible.

One idea could be to refactor in the following direction:

  • Model: An object representing a model, than can be persisted to the database as Persistent Object, and will only contains methods which have to do with the Model consistency, the Database integrity and access and may be some Business Rules.
  • Model Manager: A Component that will take care of manipulating a specific type of Model, that will eventually also implement Object Identity with the Database and Caching Policies.
  • Controller: A Component that will take care of manipulating the model instances through the Model Managers, and implement specific actions, which should be directly related to the 'Domain' (Scrum in case of Agilo).
  • View: A Component that takes care of displaying the UI or providing a specific interface for the final users. It should take care of handling the input data, validating them, and calling the proper actions on the Controllers level. The view should not access the Model Managers level.

We could enforce the Architecture defining some specific Extension Points according to Trac Component Model.

UPDATE: There is now a definition of the Agilo Model API, the Agilo Controller API and Agilo View API

Examples:

class Model(Interface)
    """Set of methods needed to be a Model"""    

class ModelManager(Component):
    """Specific for a Model, so there should be a connection between this and the model"""
    model = ExtensionPoint(Model) # A specific instance of Model

class Controller(Interface):
    """Define some generic methods"""
    model_managers = ExtensionPoint(ModelManager) # or only specific?!

class View(Interface):
    """Define some generic view methods"""
    controllers = ExtensionPoint(Controller)

Than the actual implementation could look like:

class Sprint(Model, PersistentObject): # Or we can make PersistentObject a Model instance too
    """Represent a Scrum Sprint"""

class SprintManager(ModelManager):
    """Manages Sprint Data"""
    sprints = ExtensionPoint(Sprint) # This would bound every sprint to the Sprint Manager

class SprintController(Component):
    """Manages Scrum Sprints"""
    implements(Controller)

class SprintEditView(Component):
    """Implements the page for editing a sprint"""
    implements(HtmlView)

class SprintDisplayView(Component):
    """Implements the page to display a sprint"""
    implements(HtmlView)

class SprintConfirmView(Component):
    """Implements a page to display confirmation for delete or close"""
    implements(HtmlView)

May be I am missing a point here, that an Interface can only be implemented by a Component, Therefore the Model can't be an interface, but we could implement a mechanism where a Model register to its Model Manager or the other way round like with Persistent Object and Persistent Object Manager.

Last modified 8 years ago Last modified on 02/25/2011 10:51:42 AM

1.3.15 © 2008-2016 Agilo Software all rights reserved (this page was served in: 0.16713 sec.)