Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: Fwd: Re: Re[2]: [higgins-dev] IdAS Update Proposals

Another analogy that fits proposal 3 is comparing an IProperty to a Polygon, and an ISingleValuedProperty to a Triangle (or a Henagon f you like).  In Polygon, I might have a method called addLineSegment.  This is still valid for a Henagon or Triangle, but can only be called a specific number of times for each (one or three times respectively).  The same relationship exists between IProperty and ISingleValuedProperty and the use of addValue.
 
Jim

>>> "Jim Sermersheim" <jimse@xxxxxxxxxx> 4/28/07 9:01 AM >>>
I like the motorcycle analogy, but I don't see it that way at all.
 
In proposal 3, what we've done is defined a WheeledVehicle, and subclassed that with a Unicycle.   I'm not sure what functionality exists in IProperty that is inappropriate for ISingleValuedProperty.  The one which was mentioned was addValue.  This is valid to be called once-only on a ISingleValuedProperty, just as it is valid to be called 5 times-only on an IProperty which has maxCardinality = 5.  Remember that ISingleValuedProperty is nothing more than an IProperty with maxCardinality = 1.
In proposal 5 below, ISingleValuedProperty needs an addValue(URI type) (which yes, could be called setValue I suppose), and IMultiValuedProperty needs an addValue(IPropertyValue newValue) to be consistent with other interfaces. 
 
I may be missing something, but I think proposal 5 is like proposal 3 other than it doesn't use inheritance and uses a different name for the setter (set instead of add).
 
Jim

>>> Valery Kokhan <vkokhan@xxxxxxxxxxxxxx> 4/28/07 7:21 AM >>>
Actually I dislike proposal #3 because to my mind it is even more
confusing then #2. It looks like in #3 we're going to do something
like this:

We need to define an interface to represent a motorcycle with the
methods to fuel up, start the engine and drive and we define it as our
base interface (just because our model allow this). Then, because
there are use cases when we don't need an engine at all, we "extend"
our base interface by defining an interface to represent a cycle (just
for a user convenience). We are saying that cycle is actually a
motorcycle but... without an engine.

I hate to think that when I have an instance of the cycle I still have
a methods to fuel it up and to start an engine but with unknown
semantic however.

It looks like nobody like proposal #2 because of the way how
objects are extended there. Ok, I could live with that but as for me
#2 is less confusing then #3.

As alternative take a look at #5 below which to my mind could help us
to avoid ambiguity like we have in both #2 and #3.

Proposal 5:

Definitions:

interface IProperty {
        public URI getType() throws IdASException;
        public boolean isSingleValued();
}

interface ISingleValuedProperty extends IProperty {
        IPropertyValue getValue();
        IPropertyValue setValue(IPropertyValue newValue);
}

interface IMultiValuedProperty extends IProperty {
        Iterator getValues();
        IPropertyValue addValue(URI type);
}

Some sample code:

IProperty prop;
...
               
IPropertyValue val;
IPropertyValue newVal;
               
if (prop.isSingleValued()) {
  ISingleValuedProperty sProp = (ISingleValuedProperty) prop;
  val = sProp.getValue();
  //do thimething with the value
                       
  //set new value
  sProp.setValue(newVal);
} else {
  IMultiValuedProperty mProp = (IMultiValuedProperty) prop;
  Iterator iter = mProp.getValues();
  while (iter.hasNext()) {
    val = (IPropertyValue)iter.next();
    // do something with the value
  }
                       
  //add new value
  mProp.addValue(URI.create("someType"));
}

In order, I'd prefer #5, #4, #2, #3, #1

Valery


Friday, April 27, 2007, 11:34:49 PM, you wrote:



> So, here's my opinion:

> Proposal #1; I agree seems a bit wishy washy, but it's very simple
> (check for single-valuedness, and proceed with no casting)



> Proposal #2; I like that there's no casting when it's a single-valued attribute.

> I dislike because it presents a model where:

> * A property has a value

> * A value is either a value or a list of values

> * A list of values is both a value and a list of values



> It's the last point that I worry about.  A list of values is itself
> a value?  It means that my list has methods like isList(), and
> getType().  It also has isSimple() and isComplex().  I view the two
> latter as things that should be declared at the attribute level, not
> the value level.  Also, I don't want to present APIs that make it
> appear that we allow an attribute to contain different typed
> values.  It also presents the view that a value may be a list of
> values, each of which itself could be a list of values and so on.
> Meaning, it presents an API view inconsistent with the data model.



> Proposal #3; If we really think it's necessary to provide a
> convenience for users to call "getValue()" IFF an attribute is
> single-valued, then I slightly prefer this method over #1.  Valery
> dislikes that it's possible to call ISingleValuedProperty.setValue
> repeatedly (would fail on subsequent calls).  I think this is fine
> -- it's simply one of many places where an API will fail due to the
> constraints of a specific Context's model.



> Proposal #4; This has the advantage of presenting exactly the
> intent of the data model.  Adding a convenience like getValue() is
> effectively trying to reflect the reality of a specific Context's
> model through the general-use IdAS APIs -- I believe this is why
> we're getting into trouble in the first place.  None of the other
> methods provide instructions that the consumer can't perform
> himself.  Further, the consumer can build his own convenience method however he wishes.



> In order, I prefer #4, #3, #1, #2



> Jim

>>>> "Jim Sermersheim" <jimse@xxxxxxxxxx> 4/27/07 12:14 PM >>>

> I happened to catch Valery on #higgins and asked if there were
> issues with these before committing them.  There were no issues with
> the new add* methods, but in terms of getting a single valued
> attribute, our proposals differ, and he had issues with what I was proposing to add.

> Please take some time to review the problem and the two proposed
> solutions and express your view on which direction we should move
> (or propose an alternate if you wish)



> Problem:

> We say that an attribute may have multiple values, and we reflect
> this in the APIs with the method Iterator IProperty::getValues().
> This is fine except for one thing; in a large number of cases,
> attribute will have only a single value -- causing consumers to have to do something this:

> // assumes the user already knows this is a single-valued attr

> Iterator iter = myAttribute.getValues();

> IPropertyValue val = null;

> if (iter.hasNext()) {

>  val = ((IPropertyValue)iter).next();

> }



> //this could have been used to determine whether the attribute was a single-valued attr

> boolean bIsSingleValued =
> myAttribute.getProperty().getMaxCardinality() == 1 ? true : false;



> From a purist standpoint, this is fine -- we've provided an access
> method which is perfectly aligned with the model being presented.
> >From a practical standpoint however, people might prefer a simpler
> method to access single-valued attributes.  Note that we're talking
> here about single-valued attribute in terms of the Context's model.
> Not whether or not there happens to be a single value in a multi-valued attribute.



> Assuming that we're correct in our belief that the half-dozen lines
> above are cumbersome, A number of proposals have been presented:



> Proposal 1 (currently implemented)

> http://download.eclipse.org/technology/higgins/idas/lastNightlyBuild/javadoc/org/eclipse/higgins/idas/IProperty.html#getValue(boolean)

> Callers would probably want to precede this by first determining
> whether or not it's single-valued (see above)

> Sample code:

> IPropertyValue val;

> if (myAttribute.getProperty().getMaxCardinality() == 1) {


>   // handle single-val case
>   val = myAttribute.getValue(true); // boolean doesn't really
> matter here since we've already determined

>   // do something with val

> } else {

>   // handle multi-val case


>   Iterator iter = myAttribute.getValues();

>   while (iter.hasNext()) {

>     val = ((IPropertyValue)iter).next();


>     // do something with val

>   }

> }



> Proposal 2

> http://wiki.eclipse.org/index.php?title=IdAS_Update_Proposals_2 (Stuff in the first grey box)

> Sample code:

> IPropertyValue val = MyAttribute.getValue();

> if (!val.isList()) {


>   // handle single-val case

>   // do something with val

> } else {


>   // handle multi-val case

>   IValueList list = (IValueList) val;


>   Iterator iter = list.getValues();

>   while (iter.hasNext()) {

>     val = ((IPropertyValue)iter).next();


>     // do something with val

>   } 
> }



> Proposal 3

> http://wiki.eclipse.org/index.php?title=IdAS_Update_Proposals_2 (Stuff in the second grey box)

> Sample code:


> IPropertyValue val;

> if (myAttribute.isSingleValued()) {

>   // handle single-val case

>   ISingleValuedProperty prop = (ISingleValuedProperty) myAttribute;

>   val = prop.getValue();

>   // do something with val

> } else {

>   // handle multi-val case


>   Iterator iter = myAttribute.getValues();

>   while (iter.hasNext()) {

>     val = ((IPropertyValue)iter).next();


>     // do something with val

>   }

> }



> Proposal 4

> Remove IProperty.getValue() and make people always iterate.



> Please respond with your preference or alternate proposal.



> Jim




>>>> "Jim Sermersheim" <jimse@xxxxxxxxxx> 4/26/07 8:07 PM >>>
> Javadoc for these changes is reflected here
> http://www.eclipse.org/higgins/org.eclipse.higgins.docs/idas/

>>>> "Jim Sermersheim" <jimse@xxxxxxxxxx> 4/26/07 7:29 PM >>>

> Here's the diff (which also includes the changes talked about in
> http://dev.eclipse.org/mhonarc/lists/higgins-dev/msg02312.html) of
> the addition of add*(<Instance of * interface>) methods.



> I don't think there was any contention on either change, so I plan
> to check these both in tomorrow a.m. unless I hear otherwise.



> Jim

>>>> "Jim Sermersheim" <jimse@xxxxxxxxxx> 4/26/07 7:25 PM >>>
> <fwding: sorry, I'm used to pressing reply to sender for higgins
> messages, which works except in the case of messages that come from
> Valery for some reason. So I keep replying privately to him on accident>

>>>> Jim Sermersheim 4/26/07 9:18 AM >>>

> I agree.  I noted this at
> http://wiki.eclipse.org/index.php/IdAS_Update_Proposals_Distillation#Specifying_updates #2,
> but I didn't include it at this point as I viewed it as not
> absolutely necessary. In other words, the only way I could see
> getting the update refactoring done in a timely way was to remove anything potentially contentious.



> I'm happy to add this useful convenience method if no one has
> issues with it.  The only drawback I see is that it adds one more
> method to implement -- but I think it's worth it.



> Jim




>>>> Valery Kokhan <vkokhan@xxxxxxxxxxxxxx> 4/26/07 9:04 AM >>>
> Jim,

> I wonder why there is no methods like
> IAttribute IDigitalSubject.addAttribute(IAttribute attr);
> which you proposed earlier.

> To my mind, such methods are useful when we need to copy some
> attribute(s) from one digital subject to another.

_______________________________________________
higgins-dev mailing list
higgins-dev@xxxxxxxxxxx
https://dev.eclipse.org/mailman/listinfo/higgins-dev

Back to the top