Hi Alex,
I have very little experience programming in Java (from a long
time ago), but it looks like the Java 8 features you're using have
made for nicer syntax.
It sounds like you've already been reading up on DCI and the pitfalls of wrapper implementations, but just to be clear, it's not actually DCI if object identity isn't preserved. A wrapper implementation can still be useful if it's the only option though, which I always thought was the case for Java...but now that I looked up Java interfaces with default methods I'm not so sure.
It looks like Java interfaces with default method work similarly to traits (e.g. Scala traits). There's an old thread about them here in this group:
https://groups.google.com/g/object-composition/c/gPXGKOtgMgU/m/lKZi6lTIwmYJ
As you can see from that thread, there are challenges with making them work well for DCI.
I wonder if a "reverse wrapper" technique would be possible in Java 8 (which does preserve object identity). This is where the data object wraps the role instead of the other way around. But that's only helpful if you have a way of intercepting method calls, as I did in my PHP implementation where I used PHP's "magic method" __call() in this part of my implementation. As I said I don't really know Java, but maybe aspect-oriented programming using a tool like AspectJ would be worth looking into in case that's possible?
In general, there are two approaches to making traits or abstract base classes work for "true" DCI (without macros or source code transformation):
1. The reverse wrapper technique mentioned above (uncommon; the only DCI implementations I know are using this are in PHP)
2. Somehow using the language's type system to ensure that only the appropriate roles can be called within a Context
In both cases, the traits have to be added statically somewhere,
you're just doing some trickery to ensure they're only available
where they should be. And you either have to accept the
possibility of name conflicts of methods from different roles that
could potentially be added to the same object (forcing you to
rename one of them), or using a naming convention that includes
the role name, e.g. `source.source_transfer()`, which is a bit
verbose and annoying.
I'm not sure if any of this will help improve your Java
implementation given the constraints of the language, but those
are some things to think about.
--
You received this message because you are subscribed to the Google Groups "object-composition" group.
To unsubscribe from this group and stop receiving emails from it, send an email to object-composit...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/object-composition/a3138fa4-d2cc-4a40-a31f-f07b9d27a330n%40googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/object-composition/9a480eb2-a8d8-465c-9c08-608e38b725c6%40gmail.com.
Hi Alex,
I'll try to think about if/how it could be implemented; one concern I have off the top of my head would be the fact that objects should have some role wrapping mechanism build into them and this might not be feasible in projects that have a certain maturity but did not start out with DCI in mind
Yes, that is one disadvantage of the approach...the other example
would be classes from third-party libraries that you would have to
subclass first if you wanted to be able to use their objects as
role players. I didn't find it to be an issue in practice but your
mileage may vary.
Preserving object identity, in the sense of being able to compare object references is indeed challenging when trying to do DCI in Java, however I'm wondering just how important this really is
I imagine you're aware that there are a number of operations
involving lists, hash maps, etc, that depend on consistent object
identity to work correctly (in OO systems in general). The
canonical DCI example that showcases the need to maintain object
identity is an implementation of Dijkstra
algorithm (
Having said that, DCI is really more about how you think about
the system than it is about the implementation details. Even with
a very imperfect implementation, I think you can still get a lot
out of thinking in terms of DCI and approaching your code from
that perspective. So from a practical standpoint and the
limitations of the language, I think what you said makes sense and
I would probably think similarly. I would still definitely explore
all your options for solving the identity problem, and even if you
decide to stick with your original solution, you'll learn more
about DCI and its implementation patterns along the way.
Cheers,
Matt
To view this discussion on the web visit https://groups.google.com/d/msgid/object-composition/1a20b368-4828-40ca-b1f2-a133024263b3n%40googlegroups.com.