← Back to team overview

launchpad-dev team mailing list archive

Re: Performance tuesday: faster development

 

>>
>> If there is a traversal service, it would map URLs to ... what?  Do
>> things that are model objects today all have some kind of unique name in
>> the new world (it could be as simple as bug-$id)?  I guess it could
>> return just a (view-name, model-object-name) pair.
> 
> I think there is a need for site wide unique ids for objects; possibly
> as simple as (class, id) - but there are folk with more experience
> than I that will surely inform this discussion (/me looks at
> wallyworld).
> 

/me looks back at lifeless

As an aside, before I produce some drivel on the above topic, there's
been quite a mix of different concepts explored in the discussion so
far, touching on service definition, object modelling, deployment
architecture, application layers etc etc. Given the scope of what's
being discussed, It may be worth considering using ideas from something
like the 4+1 Architectural View Model to describe the New World Order.
I'm not sure if people have used this in the past of already know about
it and like/dislike it, but in summary it's a technique used to describe
the architecture of software systems based on multiple views:

Logical: the functionality that the system provides to end-users (class
diagrams, sequence diagrams etc)

Development: the system from a programmer's perspective (system
components, packages etc)

Process: dynamic aspects of the system - runtime behaviour including
system processes and how they communicate; concurrency, distribution,
integrators, performance, and scalability, etc

Physical (aka Deployment): topology of software components on the app
servers and the physical connections between them.

Scenarios (the +1): uses cases etc. The starting point for tests, draws
on input from the other views.

NB: I'm not advocating we adopt the above approach but merely consider
using the concepts therein to help frame how we define and document and
describe the new architecture moving forward. Breaking it down like that
I think helps reduce the complexity of what is a significant engineering
problem.

Anyway, back to the main topic (and a bit more - I talk about
application layers to frame what I want to say about domain objects). My
view on this is that there could be, at a high level, 5 distinct layers.
Bear in mind my background is from the JEE world but I think the
concepts translate fairly well to other technology stacks. Again these
are just ideas for how we might want to think about the system.

Presentation: user interface. Widgets, reporting etc.

Application: provides glue to bind user interface elements to back end
services. Performs syntactic validation, delegates to services layer for
business logic. Provides use case UI workflow.

Services: provides access to business logic, initiates workflow, invokes
methods on domain objects. Can be called by multiple systems such as web
apps, external clients etc.

Domain: where the domain model is implemented. The services layer
delegates many of its requests to the domain layer.

Persistence: the plumbing (ORM solution) required to persist the domain
model to the database as well as other database access functions

In terms of defining our system as a set of services, a slightly
different view could be:

Data Services: provide consolidated access to data

Business Services: contain logic for specific, well defined tasks and
perform business transactions using data services

Business Processes: coordinate multiple business services within the
context of a workflow

So, given the above, and based on my past ramblings on this topic, I
think that we need to model separately:
- the persistent objects as handed by the orm (persistence) layer
- the business objects used by the services layer
- the data objects passed to the view rendering (presentation) layer*

* the last one is usually just something like simple json for a
javascript rendering layer for example or may be attributes on the view
object like we use with out current template based approach etc

IMHO the business objects used by the services layer should be a POPO
based component model. Actually, the services themselves should also be
POPOs IMHO. This leads to a simplified programming model and better
testability since both business objects and service business logic can
be instantiated outside the container. This makes more sense if one
tends to prefer a middle out design approach and considers the database
as just a persistence abstraction :-) Again, this thinking is also borne
out of my experience in the JEE world where it took the industry a long
time to realise the benefits of decoupling your actual application code
from the infrastructure/container.

Thinking out loud, would it be feasible to still use the zope component
model (eg interfaces) to define the services' APIs - they could be
easily run up outside the container for unit testing but when run inside
zope, we would still get the declarative security etc that zope offers.
Or am I totally off base there?

My view is that zope data objects should not be seen above the
persistence layer but I don't have enough zope knowledge to know if
that's viable or desirable. Because we are looking at splitting our
system into multiple collaborating services, that has implications
anyway for how objects are passed around. One option is that passing an
in memory reference would become verboten, even if the services were to
be co-located in the same application container. Typically objects would
be represented by their business key - this is not (or rather should not
be) the database pk but many implementations including ours tend to be
lax about the use of surrogate keys. It is up to the callee (the
receiving end) to turn an object id back into an object in whatever way
makes sense for the use case. For operations like delete, no
transformation may even be required. This approach helps reinforce that
the inter-service interfaces need to be coarse grained. And of course,
inter-service calls do not have to be via RPC; the service operation
being invoked could be at the other end of a message queue.

So what should the id generation strategy be? (class, id) as suggested
at the start I have found to work well. It maps nicely to a restful
namespace too. id itself does not have to be globally unique (sometimes
people make it that way but it's not what we want) and as stated above,
should be a surrogate key but often defaults to the database pk.

Anyway, enough rambling for now. If you've read this far, get a life :-)




Follow ups

References