From: Brian Candler Date: 2010-02-16T07:03:59+09:00 Subject: Re: "Code must be Chunkable" Caleb Clausen wrote: > Those roles in turn simply forward the #transfer message to some > other method(s) > (increaseBalance and decreaseBalance in this case) > > Please let me know what you think of this. I think it's more limiting that what DCI is supposed to offer; I think you are supposed to inject *new* methods into the underlying objects to help them fulfil their roles, rather than just mapping existing ones. That is, the role contains extra logic which in normal OOP might pollute the model, and DCI helps separate it out. I've been going through Trygve's Gantt planner example documented in http://heim.ifi.uio.no/~trygver/2009/bb4plan.pdf Whilst the code appears incomplete (it relies on a base class defined earlier in the book), and given also that I don't grok Smalltalk, I've still picked up a few things. Here is one example: Frontloader>>frontloadFrom: startWeek AllActivities do: [:act | act earlyStart: nil]. [ Context reselectObjectsForRoles. Activity notNil ] whileTrue: [ Activity earlyStart: startWeek. Predecessors do: [ :pred | (pred earlyFinish > Activity earlyStart) In the PDF, you'll see that "AllActivities", "Context", "Activity" and "Predecessors" are roles, and are underlined to highlight them - a bit of a weakness IMO that they are not clear in the syntax. Anyway, the Frontloader is a separate class which is (as far as I can see) somehow 'mixed in' to the FrontloaderCtx context object using roleStructure magic. But if it were a single object I think it might look roughly like this: class FrontloaderCtx attr_reader :all_activities, :activity, :predecessors def initialize(model) @model = model end def reselect_objects_for_roles @all_activities = @model.all_activities @activity = @all_activities.find { |act| act.early_start.nil? && !@model.predecessors_of(act).find { |pred| pred.early_start.nil? } } @predecessors = @model.predecessors_for(@activity) end def frontload(start_week) while (reselect_objects_for_roles, activity) ... end end end which is probably not too much different to how you'd write a front-loader "controller", except I'd be inclined to use local variables for the 'roles' rather than instance variables. However it's clear from this that the assignment of objects to roles is something which it intended to change during execution of a single method, since the whole algorithm relies on "reselect_objects_for_roles". I still haven't achieved enlightenment as to what is new or different about "DCI". The view contexts might provide meatier examples. I did actually start to translate the whole lot virtually line-by-line into Ruby, but got a bit stuck on the UI side because I've not done any Ruby UI programming. It's probably possible to hook Tk in, but I don't fully understand what's going on in the Smalltalk yet. Regards, Brian. -- Posted via http://www.ruby-forum.com/.