[Ns-developers] Different Approaches to Default Values (was Re: Default Values)
Mathieu Lacage
mathieu.lacage at sophia.inria.fr
Mon Jan 21 00:45:08 PST 2008
hi craig,
On Sat, 2008-01-19 at 12:29 -0800, craigdo at ee.washington.edu wrote:
> It is relatively easy to consider a global space that is available when the
> object has not yet been instantiated; and a local space that is available
> with the object fully instantiated. These are the two Set() examples I've
> been using worded to make the distinction clearer (I hope). The first is
> the global case, the second is the local case:
>
> Set ("/global/SomeClass/configuration/item")
> Set ("/nodes/1/SomeClassObject/configuration/item")
ok
>
> The hard case we are really talking about lives in-between these two
> boundary cases. What happens when you want to use some configuration item
> that is not in the global space while the object has not yet been
> constructed. There must be a "third way" to allow the user to specify which
> class to create and which parameters to use. There are a number of ways to
> do this. Pretty much all ways will get more and more complicated as the
> structure you want to create gets more complicated.
>
> I think the easiest to visualize the general problem is try and create a
> general hierarchy of various types of some ClassObject. Consider a node
> onto which you have an abstract need to hang a hierarchy of different
> objects you want to be user configurable.
>
> [ASCII art warning ...]
>
>
> +-> SomeClass2Object -> SomeClass4Object
> |
> node -> SomeClass1Object -> + +-> SomeClass5Object
> | |
> +-> SomeClass3Object -> +
> |
> +-> SomeClass6Object
>
> Just to be cruel, assume that each of the SomeClass{*} constructors can take
> a different set of constructors. I think Mathieu is asking, "how the #~(&
> do you configure a situation like this generically.
>
> One way is to just enter the whole structure into the global configuration
> space since it's available and waiting for such a situation:
>
> Set ("/global/TheConfig/class", "SomeClass1");
> Set ("/global/TheConfig/class/nChildren", "2");
>
> Set ("/global/TheConfig/childType/0/class", "SomeClass2");
> Set ("/global/TheConfig/Object/childType/0/nChildren", "1");
>
> Set ("/global/TheConfig/childType/0/0/class", "SomeClass4");
> Set ("/global/TheConfig/Object/childType/0/0/nChildren", "0");
>
> Set ("/global/TheConfig/childType/1/class", "SomeClass3");
> Set ("/global/TheConfig/Object/childType/1/nChildren", "2");
>
> Set ("/global/TheConfig/childType/1/0/class", "SomeClass5");
> Set ("/global/TheConfig/Object/childType/1/0/nChildren", "0");
>
> Set ("/global/TheConfig/childType/1/0/class", "SomeClass6");
> Set ("/global/TheConfig/Object/childType/1/0/nChildren", "0");
>
> You can imagine inserting various construction parameters into this
> structure. The contructors of all the objects need to know what level they
> live on and parse and use this stuff. Welcome to the Windows Registry. I
> won't comment on how wonderful this looks.
ok.
One thing I wanted to point out before this idea of a 'global' config
space goes much further is that it is most likely quite incompatible
with the idea that our objects are _dynamically_ aggregated and that
they don't know each other. i.e. /nodes/*/tcp/ is a namespace which is
created by the user when he aggregates a tcp stack to a set of nodes.
So, unless you decide to hardcode somewhere knowledge about the way
objects are expected to be aggregated, you won't be able to build the
'global' config namespace or, if you can build it, you won't be able to
read from it because objects won't know where they are within this
global namespace so they won't be able to read their values from there.
>
> Another way to do this is to package this information up into blobs
> (Parameters) and pass them down into the system. You will still have to
> pass the same amount of information, it'll just be in a different form:
>
> Parameter p1;
> p1.Set("class", "SomeClass1");
> p1.Set("nChildren", "2");
>
> Now I instantly see the need for a vector of Parameter in a Parameter, so
> I'll just assume one exists and work backward (making them all vector
> parameters for generality):
>
> Ptr<VectorParameter> p4 = Create<VectorParameter>
> p4->Set("class", "SomeClass4");
> p4->Set("nChildren", "0");
>
> Ptr<VectorParameter> p5 = Create<VectorParameter>
> p4->Set("class", "SomeClass5");
> p4->Set("nChildren", "0");
>
> Ptr<VectorParameter> p6 = Create<VectorParameter>
> p4->Set("class", "SomeClass6");
> p4->Set("nChildren", "0");
>
> Ptr<VectorParameter> p2 = Create<VectorParameter>
> p2->Set("class", "SomeClass4");
> p2->Set("nChildren", "1");
> p2->SetVector(0, p4)
>
> Ptr<VectorParameter> p3 = Create<VectorParameter>
> p2->Set("class", "SomeClass3");
> p2->Set("nChildren", "2");
> p2->SetVector(0, p5)
> p2->SetVector(0, p6)
>
> Ptr<VectorParameter> p1 = Create<VectorParameter>
> p2->Set("class", "SomeClass1");
> p2->Set("nChildren", "2");
> p2->SetVector(0, p2)
> p2->SetVector(0, p3)
>
> So this puts together a blob of parameters that can be passed down to the
> node doing the construction and disassembled by each SomeClass to discover
> construction parameters. At each level, the constructor strips off the
> lower level parameters and passes them on down the system. The parameters
> still need to be "parsed" somehow.
ok. I think that this 'vector of parameters' can be made to look vastly
nicer from a syntactical perspective. But, this is a disgression.
>
> Another way is to use a framework approach. In this case, the Build method
> of the highest level SomeClass would be refined by the user into MySomeClass
> that would create the hierarchy explicitly. If parameters were required,
> they could be provided here directly.
>
> Build ()
> {
> Ptr<SomeClassObject4> p4 = Create<SomeClassObject4> (0); // no child
> Ptr<SomeClassObject5> p5 = Create<SomeClassObject5> (0); // no child
> Ptr<SomeClassObject5> p6 = Create<SomeClassObject6> (0); // no child
>
> Ptr<SomeClassObject2> p2 = Create<SomeClassObject2> (1); // one child
> p2->SetChild(0, p4);
>
> Ptr<SomeClassObject3> p3 = Create<SomeClassObject3> (2); // two child
> p2->SetChild(0, p5);
> p2->SetChild(1, p6);
>
> Ptr<SomeClassObject1> p1 = Create<SomeClassObject1> (2); // two child
> p2->SetChild(0, p2);
> p2->SetChild(1, p3);
> }
>
> I think this is quite nice, myself.
Ok. So, in the specific case I outlined, you are suggesting that we ask
the user to subclass the HierarchicalMobilityModelFramework to provide a
CreateParent and a CreateChild method and that he should pass this class
to the topology helper classes ? I am perfectly fine with this: I
suspect that this Framework class could be trivially renamed to Factory,
hence making its purpose clearer. What is interesting is that, once you
are there, the difference between the Parameter stuff and this explicit
base factory class is that the Parameter stuff gives you a data-flow
approach to build the factory while what you are proposing is a
code-flow approach to build the factory.
> > So far, it sort of works in simple cases but
> > as soon as you get into arranging more complex object structures, you
> > will get in cases like this where multiple objects are created by a
> > single call to a single function from the point of view of
> > the user. You
> > can try to add what craig has been championing to solve this problem,
> > that is, an inversion of control flow but I doubt very much that the
> > result is going to be much easier to deal with.
>
> Unless I am missing something, it is much easier to deal with. But I am
> perfectly willing to hear that I have missed something completely.
I don't think that the two are fundamentally incompatible: the
inversion-of-control is clearly necessary to handle the use-case I
described. What I am trying to do with the Parameter proposal is to
allow the user a way to easily implement a 'factory' with a data-flow
approach. So, the latter approach can be quite naturally built on top of
the basic inversion-of-control framework/factory thing.
I sense the start of a convergence here. (fingers crossed)
regards,
Mathieu
More information about the Ns-developers
mailing list