Leo Simmons posted a nice little essay that should be referenced^^ Simons
prominently, although maybe tempered a little?
KISS. Say one thing and say it well. Going a little over the top is more thought-provoking and more fun to read (IMHO). There is always a balance to be found in Real Life(tm) :D
1) Are we going too far down the rabit hole, as it were? If so, where and how do we fix it?
I know I've repeatedly crusaded against all the complexity in merlin. What you need to realise is that different use cases demand different complexity. Now, Merlin is being developed according to a set of complex requirements for a complex solution to a complex problem.
The catch: many of us don't have those complex requirements. My apps are an order of magnitude (or two) simpler than the things Steve works on. Thus, for me, merlin is too much magic, while for him, its the only thing that will allow him to get his stuff in place before the 22nd century.
2) How does a project that *is* a framework embrace such an outlook--> carefully balancing what the framework is supposed to do and increase
maintainability and debuggability (new word...) of applications built> on it.
I think it can only be done with lots of discipline and slow addition of features. Only add support for something once you have arrived at a point in your framework-using application that cannot be solved otherwise.
That, however, is often a much more difficult (at least for me) way of designing. It takes longer.
For instance, I like attributes, as it solves some very real problems with component management--although their use does provide some serious issues that need to be addressed.
Along with the introduction of attributes, and special config files, etc., making an application built with these tools work with a storebought IDE is difficult. I have really learned how to work with a debugger in the past few years, and creating a plugin just to make the application run is not really that cool.
indeed! The thing to realize is that, everytime you add some kind of magic, you're introducing some kind of language extension. And the problem with language extensions is that they are extensions, hence *not standard*.
Remember the flamewars about making metadata a part of the 'core framework' vs. it being an extension? If it is not part of the generally accepted core, its use is problematic. If it is, other things are hampered (like the ability to use your stuff in a "pure" java environment).
We need to compile the attributes at compile time, and be able to work with the IDE's supplied classloader--which means scanning JARs is not really a good option in this environment. This is sort of a catch 22. Attributes not only solve a number of management issues, they introduce a host of new issues. Does this mean I consider them a failed experiment? No. I don't.
It is not just attributes. It is everything that is not "pure", "standard" java code that is compiled into classfiles. XML configuration files. Manifest files. Property files.
What should we do? The answer to that is actually a simple one, Berin!
Just make sure that your code only references, and works with, other java code. Make sure all your 'language extensions', all your magic, should be able to map to and from (and be replaced by) java code, directly, intuitively.
In the attribute example, create an object model for attributes, and use that in your components. Make sure your runtime support layer is flexible enough that you can use manual method calls on it to build the attributes. In fact, make your fancy attribute parser into something that does nothing but do these method calls for you.
Consider (just making something up here)
/** @@ComponentClass( "SomeComponentImplementation" ) */
class ComponentFactory
{
Object newInstance()
{
String className = AttributeUtil.getAttributes( this.class )
.getAttribute( ComponentClass.class ).getClassName() return Class.forName( className ).newInstance();
}
}The only thing you need to make sure is that you can add in the attribute by hand as well. Like this (again, just a stupid example):
AttributeUtil.addAttribute(
ComponentFactory.class,
new ComponentClass( "SomeComponentImplementation" ) );what you have here is 'optional' magic. You can remove your attribute compiler and your attribute metadata by replacing it with pure java code. When you write unit tests, when you debug your code, when you deploy to a constrained environment, you replace your fancy stuff with the pure java.
I don't feel much like continuously referring to PicoContainer, but this is a pattern consistently followed there. You normally want to use some kind of xml declaration of your components (or a script, or an automatic classpath browser, or ...), but those are *optional*. PicoContainer is built around being able to replace the xml, the scripts, all that, with plain and simple java code.
How do we make Merlin easier to understand?
I spent an hour or two looking at the code today, and I must say I haven't got a clue.
Lies, damn, lies, and some statistics:
Files Lines ------------------------------------- Pico | 164 8495 Fortress | 433 26115 Phoenix | 924 69230 Merlin | 2130 88623
that includes all non-code files as well, all comments, all unit tests, all license headers (see below for how I got these figures). Merlin is roughly 10 times the size of Pico. Based on that, I will assert that it is at least sqrt(10)=~3.16 times as difficult to understand (yes, that is a complete bogus figure which has no basis in science).
cheers!
- LSD
Statistics gathering ----------------------------------------------------------------------- [EMAIL PROTECTED] merlin]$ pwd /home/lsimons/cvs/avalon/merlin [EMAIL PROTECTED] merlin]$ find . -type f | grep -c '.*' 2130 [EMAIL PROTECTED] merlin]$ find . -type f -exec cat \{\} \; | grep -c '.*' 88623
[EMAIL PROTECTED] avalon-phoenix]$ pwd
/home/lsimons/cvs/avalon-phoenix
[EMAIL PROTECTED] avalon-phoenix]$ find . -type f | grep -c '.*'
924
[EMAIL PROTECTED] avalon-phoenix]$ find . -type f -exec cat \{\} \; | grep -c '.*'
69230
[EMAIL PROTECTED] fortress]$ pwd
/home/lsimons/cvs/avalon/fortress
[EMAIL PROTECTED] fortress]$ find . -type f | grep -c '.*'
433
[EMAIL PROTECTED] fortress]$ find . -type f -exec cat \{\} \; | grep -c '.*'
26115[EMAIL PROTECTED] pico]$ pwd
/home/lsimons/cvs/pico
[EMAIL PROTECTED] pico]$ find . -type f | grep -c '.*'
164
[EMAIL PROTECTED] pico]$ find . -type f -exec cat \{\} \; | grep -c '.*'
8495--------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]
