3

I have a design and am wondering what the appropriate way to access variables is. I'll demonstrate with this example since I can't seem to describe it better than the title.

  • Term is an object representing a bunch of time data (a repeating duration of time defined by a bunch of attributes)
  • Term has some print functionality but does not implement the print functions itself, rather they are passed in as anonymous functions by the parent. This would be similar to how shaders can be passed to a renderer rather than defined by the renderer.
  • A container (let's call it Box) has a Schedule object that can understand and use Term objects.
  • Box creates Term objects and passes them to Schedule as required. Box also defines the print functions stored in Term.
  • A print function usually takes an argument and uses it to return a string based on that argument and Term's internal data. Sometime the print function could also use data stored in Schedule, though. I'm calling this data shared.

So, the question is, what is the best way to access this shared data. I have a lot of options since JS has closures and I'm not familiar enough to know if I should be using them or avoiding them in this case.

Options:

  1. Create a local "reference" (term used lightly) to the shared data (data is not a primitive) when defining the print function by accessing the shared data through Schedule from Box. Example:

    var schedule = function(){
        var sched = Schedule();
        var t1 = Term( function(x){   // Term.print()
                           return  (x + sched.data).format();
                     });
    };
    
  2. Bind it to Term explicitly. (Pass it in Term's constructor or something). Or bind it in Sched after Box passes it. And then access it as an attribute of Term.

  3. Pass it in at the same time x is passed to the print function, (from sched). This is the most familiar way for my but it doesn't feel right given JS's closure ability.
  4. Do something weird like bind some context and arguments to print.

I'm hoping the correct answer isn't purely subjective. If it is, then I guess the answer is just "do whatever works". But I feel like there are some significant differences between the approaches that could have a large impact when stretched beyond my small example.

Edit

I'll post the solution I'm using but I'd still welcome criticism:

All print functions take, as arguments, anything term doesn't own. This way, term is not coupled to schedule in any way (obviously schedule is still dependent on term, though). This allows term to be initialized/constructed anywhere without needing knowledge of schedule.

So, if term had an init() function it might take an object that looks something like this:

{
    inc: moment.duration(1,"d"),
    periods: 3,
    class: "long",
    text:"Weekly",
    pRange: moment.duration(7,'d'),
    //*...other attr*//
    printInc: function(increments,period){
        return moment(this.start).add(this.inc.product(increments)
              .add(this.startGap))
              .add(this.pRange.product(period))
              .format(DATEDISPLAYFORMAT);
    },
    printLabel: function(datetime){
        return (datetime).format(DATEDISPLAYFORMAT);
    }
}

Where increment, period, datetime would all be passed from whatever is using term's print methods (schedule in this case).

3
  • Could you be more specific on the relations between box, schedule and term? Is the relationship between schedule and term one to many? Is the box the owner of the schedule? Or is box just a factory? Aug 22, 2014 at 12:00
  • @MarcodeJongh Box owns schedule and passes terms to it.Term is essentially a data structure with minor functionality and is used elsewhere in the app. The print functions are specific to schedule though. I'll update the question with the solution I'm using atm.
    – DanielST
    Aug 22, 2014 at 13:48
  • 1
    The solution you're using looks reasonable, although if the printing is specific to Schedule, why isn't it in the Schedule class rather than Term? Aug 23, 2014 at 21:38

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.