Ted Husted wrote:

Craig R. McClanahan wrote:

Far better would be to divide the procedural flow into small steps that are externally configurable. And, let each step have its own arbitrarily complex internal structure (by virtue of the fact that it can be a Command or a Chain of its own). Oh, by the way, the procedural steps become small enough and narrowly focused enough to write high quality unit tests for. And, because commands interact with each other *solely* through a Context, you can easily create mock objects (like a ServletContext or an HttpSession, in a chain destined for a web applicaton) that let you thoroughly test things in a standalone environment (in case it's not obvious, I'm a *huge* fan of JUnit :-).


Me too. =:) Right now, I've got my DAO layer (which also uses a XML config) running under the JUnit applet or as an Ant task. I can't seem to get Chain running that way. It's fine as an Ant task, but when I try to run it under the applet, my Commands table comes up empty =:(

Obviously, I need to define this better, provide a demnstration environment, but I thought I'd bring this up in case anyone had a clue for a quick fix. [That green bar is soooo addictive :)]

Doesn't sound familiar, but use the Ant task variant myself. Perhaps a class loader problem; perhaps related to the XML parsing?



Though, my unit tests for the Commands don't utilize mocks. They just populate the Context directly and pass it up. Of course, there's the part where the Context is created from the request paramenters, but that's a separate test suite that isn't coupled to the Commands.

That's the approach I take as well.



For end-to-end integration, Cannoo Webtest pulls it all together nicely. Need to run the container running for that one, but it doesn't involve loading Cactus or anything like that, so those run very quickly.

For web stuff in particular, I've also found HtmlUnit to be quite helpful -- it lets you treat the response page as a DOM and look for various things, without the fragility of comparisons to a static golden file that is sensitive to changes in whitespace that are not usually important.




Indeed, the only reason that Catalog exists is to allow chains to refer to other chains in an organized way. One could argue that even this is out of scope; however, it's very useful to be able to write a Command that uses complex processing logic to decide which other commands (or chains, since you can't tell in the catalog what something is) should be used to actually perform a task.


IMHO, the Catalog construct places a key role in decoupling the sender from receiver, as specified by the CoR pattern. Right now, I have a command-name coming up from the web tier. The presentation framework requesting the command has no idea how it will be handled. It just knows how to create a given Context for a given Command, according to a high-level API contract. All it really knows is the logical name and parameters required. The Catalog takes care of selecting the Command/Chain to process, in much the same way a framework like Struts takes care of selecting the Action class to execute.

If an implementation exposes the Catalog to the Command/Chains, then another usage is to allow Commands to call one another through the Catalog. As mentioned, this allows any number of clever strategies for creating "framework" chains that can be reused in different ways under different circumstances. This usage can also make the Catalogs more testable, since a test could substitute a "mock" Command, if such a thing were desired.

Do you think we should make a Catalog an optional property of a Context? A lot of use cases would like to have a default spot to go find one, and you can always have private conventions about what other attribute keys might also point at other Catalogs.



But, I would argue that these benefits are still secondary to the core need to cleanly decouple sender from the receiver.


-Ted.



Craig



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Reply via email to