I just had this conversation with Rickard about the above which bothered me for 
quite a while now:

WDYT ?

Michael

this pattern:
        List<ContactRoleValue> contacts = state.contacts().get();
        contacts.add(contact);
        state.contacts().set(contacts);

why not use state.contacts()._().add(contact)
is otherwise the UoW EntityListener not notfied about changes?

ContactRoleValue is a Value, so needs to be explicitly set
Michael: 03 :51
its a list, isn't it?
Rickard: yes, but like you said, UoW doesn't get any callback if you just 
update the list
Michael: ok
Rickard: I even think the List should be immutable actually
Michael: then I'd propose to get rid of the list/set/collection interfaces on 
our assocs
Rickard: why???

assocs are mutable!
Michael: because you introduce a lot of accidental complexity with all those 
methods you inherit from there

all we need is an : add, get, remove and interate
  03:53

iterate
Rickard: but then you can't use them with libraries that takes collections!
Michael: and perhaps an toList/Collection

because if you expose all the collection interface methods you must also guarantee that no one uses them behind your back to change the content of the list

and imho you cant guarantee that

we had a start of this discussion some time ago in qi4j
Rickard: ???

now I don't understand at all. The methods from ListAssociation are all ok to 
use
Michael: but's exposing internal state and keeping all the contracts is quite 
nasty
Rickard: sorry, not following...

what do you mean by "exposing internal state"?
Michael: ok, you have a bunch of objects in an assoc

the basic operations on that stuff that are really needed are the some i 
mentioned above
Rickard: true
Michael: all the rest is syntactic sugar or compatibility

the problem is - is our assoc really a jdk collecition ? isn't it rather a 
association between entities/values ?
Rickard: see your point. but are there any methods in List (for example) that 
don't really make sense?

for assocs I Mean
Michael: and by exposing all the mutable methods to the outside you have to care for all the accesses that may mutate your assoc even if you don't want that

what about immutable assocs ?

if you have an toList() you can just return an unmodifiableList(association())

but if you are a list yourself and want to be mutable you cant protect yourself
Rickard: but, note that ListAssociation<> at least as used in StreamFlow is 
only available internally

I never expose ListAssociations directly in Entity interfaces

if you want to expose the ListAssociation, then do it as an Iterable<MyEntity> 
and that should be fine
Michael: yes that was my first point about that
Rickard: or, as a Query

as Queries are immutable

if you define ListAssoc in your internal state, with access to all the collection methods, but only expose either domain methods or Iterable<>/Query<> views of that assoc, what is the problem?

the argument that I might agree with is that there are methods in List that 
don't make any sense on Associations
Michael: nice example (i hope)

remove(int i) in ListAssocInstance
Rickard: toArray, lastIndexOf, subList are a bit weird

for example
Michael: where does the notification/vetoing happen

as it only happens in remove(Object) of ManyAssocInstance

or iterator().remove() is (imho) also not reported to the listeners
Rickard: for remove(i) that's a bug

I forgot to add the vetoing in ListAssociationInstance
Michael: see what I mean ?
Rickard: same thing

not really. you found a bug

which is good!
Michael: it's quite hard to get it right if you expose all the nasty methods of 
the collection classes
Rickard: but it's not inherent

hard, yes, but not inherent
Michael: but why do we normally encapsulate and delegate (prefer delegation to 
inheritance) ?
Rickard: I'm looking for inherently bad reasons, not difficulty of 
implementation
Michael: because if we inherit we inherit all the contracts of the superclass if we delegate we chose which methods/contracts we expose to the outside world Rickard: I agree, and so, again, what I am interested in is if there are methods in List which are bad from an association point of view, not if they are hard to implement

if all the methods make sense, but are hard to implement, that's fine!
Michael: what about retainAll in ManyAssocInstance ?

is also not going along the votes
Rickard: so then the problem is: is that a bug that can be fixed, or is it 
nonfixable?
Michael: sure they can be fixed but are they necessary in the first place

lets ask me the other way round
Rickard: you are using the wrong arguments my friend
Michael: whats the necessity of inheriting from the jdk collection classes ?
Rickard: finding bugs doesn't help

ok, good question
Michael: sure it helps  one can fix them
Rickard: so, the main idea is to be able to use the manyassocs with libraries 
that can use JDK collections, which are a lot

if we do our own, we are on our own also
Michael: but which you could also do if you expose an toCollection() method in 
the manyassoc

which should then be immutable (imho)
Rickard: ok, can you explain the difference between these two approaches?
Michael: yes sure
Rickard: there doesn't seem to be a whole lot?
Michael: it is
Rickard: if you can, then I'm interested!!!
Michael: if I expose myself as an jdk collection class and am mutable

i have to deal with all the issues around mutability

if i expose my internal list as an unmodifiablecollection to the outside world I don't have to deal with mutability issues from the jdk classes at all

and as I  provide some (2) mutating methods on myself (add, remove) i have full 
control there

so i define the interface that clients are able to use againts me rather than 
having it dictated by some obscure josh bloch

it also makes testing much easier as there are only 2 contracts you have to 
test for

and it also allows you to give stronger guarantees about your correctness
Rickard: ok

now you're making sense!

much better arguments

and if we add the toList/toSet etc. then I get my thing as well
Michael: I just looked at ListAssocInstance, with that an retainAll you will have much fun fixing those I did this some time ago for some of my own stuff and I just dropped the collection exposure after that

yes

I didn't mean to cut us off the collection

but to control the access

especially if we care about notifications, voting, state handling etc

another interesting aspect

if I expose the jdk stuff in my classes how would I add an concern regarding 
e.g. mutability or auditing ?
Rickard: good point again
Michael: if i want to have an audit log for all changes and don't want to specify all the necessary listeners (which can be easily forgot) i just want to add one sideffect and be done

but if i have a plenthora of methods that mutate state and even some that are 
not accessible

(or how would you write an sideffect for list.listIterator.set(object))
Rickard: very good point

alright. You have convinced me

with the toList/toSet as immutable variants I'm fine
Michael: retainAll is especially messy (have a look at the javadoc) - you have to perform the actual operation before knowing whats in and whats out

I would volunteer to make those changes in qi4j
Rickard: write an email to the list with the suggestions, with arguments as 
above

I'll +1 it
Michael: as I am guilty of convincing you  and have done this already in other 
projects

ok

may I just copy this communication?
Rickard: yup
Michael: and sorry for not starting with better arguments, its 4:30 am here
Rickard:
04: 28
no worries

_______________________________________________
qi4j-dev mailing list
[email protected]
http://lists.ops4j.org/mailman/listinfo/qi4j-dev

Reply via email to