Yes!
Hi,
I like the "withBackLink:" one more because the other solution exposes how books are implemented on Library by passing the collection through. Better to let library manage books than to add it directly.
Library>>addBook: aBook aBook addToLibrary: self.
Book>>addToLibrary: aLibrary aLibrary addBook: self withBackLink: [ :backlinkValue | library := backlinkValue ].
Library>>addBook: aBook withBackLink: setBacklinkBlock books ifNil: [ books := OrderedCollection new ]. books add: aBook. setBacklinkBlock value: self.
However, I'm not sure that you are adding *that* much value by using the "withBackLink:" because this reads a bit easier:
Book>>addToLibrary: aLibrary aLibrary protectedAddBook: self. library := aLibrary
Library>>protectedAddBook: aBook books add: aBook
We build in a bit of an integrity framework that helps:
Book>>checkIntegrity self assert: (library hasBook: self)
Library>>checkIntegrity books do: [ :book | self assert: book library == self ]
After each test, in the tearDown, we call this on all objects created in the test. Also, we run this daily on production databases and fix failures (not often enough though!).
Cheers Otto