Friday, December 28, 2012

Re: Design by composition and persistance

On 29/12/2012 4:44pm, Taras_96 wrote:
> Hi,
>
> I'm stuck on the best way of implementing design by composition in
> Django, and was wondering if anyone had any suggestions/pointers/past
> experiences.

Design by compositon is what you do before thinking about Django. The
outcome would be, well, a design!

Only then do you convert the entities and relationships into Django
models. A model defines the object complete with data and methods.

Relationships between models are defined via SQL-style foreign keys and
constraints.

Have a look at the model layer here ...

https://docs.djangoproject.com/en/1.5/

and

https://docs.djangoproject.com/en/1.5/ref/models/fields/#module-django.db.models.fields.related


Cheers

Mike

>
> Say you're designing an event management program. Each event has a name,
> occurs in a suburb, and has a start time and end time. Say you want to
> model an event as follows.
>
> class Event:
> string eventName
> string description
> Suburb suburb
> TimeWindow eventTimeWindow
>
> class Suburb:
> string suburbName
> string state
> string postcode
>
> class TimeWindow:
> datetime startTime
> datetime endTime
> def getDuration(self) # in seconds
>
>
> The system contains a definitive list of Suburbs that can be chosen;
> that is a Suburb object has reference semantics. Consequently it makes
> sense for Suburb to have its own table, and thus the Event has a foreign
> key to a Suburb object.
>
> However, a 'TimeWindow' object has value semantics. Two TimeWindow
> objects with the same attributes are not the same object (arguable, but
> for illustration let's assume this). Thus although TimeWindow could have
> it's own table, it seems like overkill - you have the cost of a join,
> and a TimeWindow object will only ever have a reference to exactly one
> Event (thus there's no benefit in normalising this part of the design).
>
> This is analagous, in the extreme case, to the 'eventName' attribute.
> 'eventName' has value semantics, that is two 'eventName's that have the
> same sequence of characters will still be two separate objects. So you
> wouldn't create a separate 'EventName' table and reference this from the
> 'Event' class.
>
> So from the OO software design angle, the Event's TimeWindow object is
> it's own object (with it's own state & behaviour), but at the
> persistance layer, TimeWindow's attributes are lumped in with eventName
> (and description) into the same 'Event' table. Having a separate
> TimeWindow object is desirable as it follows the general rule that
> design by composition is desirable. We should have small, coherent,
> abstracted models that are well defined.
>
> My question is, is it possible to acheive this in Django? One possible
> solution is to declare TimeWindow as abstract and have Event inherit it.
> But this doesn't accurately model the 'has a' relationship (and seems
> like an abuse of Abstract inheritance) - Event would inherit the
> 'getDuration' method as well as TimeWindow's attributes, which more or
> less makes sense in this case but not in the general case.
>
> So in your business logic you would want to use the object as:
> event.eventTimeWindow.getDuration() (and by using abstract inheritance
> this wouldn't be possible)
>
> Another drawback is that you could only have one 'TimeWindow' object per
> Event. Let's say that we change the model slightly so that eventName and
> description are both EnglishString types:
>
> class EnglishString:
> def isEnglish(self)
> def spellCheck(self)
> def titleCase(self) # capitalise the string as if for a header
> string contents
>
> EnglishString is an object with value semantics - two instances with the
> same contents are not the same object. Thus you probably wouldn't want
> to store instances in their own table (to avoid join costs and overall
> complexity in how the objet is persisted). However, you can't use
> abstract inheritance (ignoring the previous concerns raised), as there
> are two instances contained with an Event instance.
>
> Another option is to separate how the data is persisted from how it is
> used in the business logic.
>
> class Event:
> EnglishString eventName
> EnglishString description
> Suburb suburb
> TimeWindow eventTimeWindow
>
> class PersistedEvent:
> string eventName
> string description
> Suburb suburb
> datetime startTime
> datetime endTime
>
> persistedEvent = PersistedEvent.objects.get(eventName = "John's Birthday")
> event = Event(persistedEvent)
> print event.suburb
> print event.eventTimeWindow.getDuration()
>
> But this feels:
> - difficult to get right
> - a large piece of work, that I'm sure someone has tried to solve before
>
> And also any Django functionality that is bound to a Django model (eg:
> Forms, QuerySets) would need a separate conversion step.
>
> - as above, you'd query against the 'persisted' model and then use
> that to construct the domain model
> - also, you'd construct a form from the 'persisted' model
> - verification logic would have to sit on the 'persisted' model, as
> that's what extends Django's Model class
> - however, you'd probably want verification in the 'domain' model,
> leading to possible duplication
> - also verification for both models would probably have to be done
> slightly differently, as the 'persisted' model can 'see' all of the
> attributes from composed objects, whereas this isn't necessarily the
> case for the 'domain' model.
>
> Is it even worth the effort?
>
> Thanks
>
> Taras
>
> --
> You received this message because you are subscribed to the Google
> Groups "Django users" group.
> To view this discussion on the web visit
> https://groups.google.com/d/msg/django-users/-/OwPJZWYqfTwJ.
> To post to this group, send email to django-users@googlegroups.com.
> To unsubscribe from this group, send email to
> django-users+unsubscribe@googlegroups.com.
> For more options, visit this group at
> http://groups.google.com/group/django-users?hl=en.

--
You received this message because you are subscribed to the Google Groups "Django users" group.
To post to this group, send email to django-users@googlegroups.com.
To unsubscribe from this group, send email to django-users+unsubscribe@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/django-users?hl=en.

No comments:

Post a Comment