I'd like to add a sort of listener to an object, but I need to be able to do this at runtime. My plan is to have a 'dummy' object set whereever it needs to be, and as soon as any of its methods are called, something goes out and sets all the internal values up (anything accessing the object waits until this is finished).
So, I need a way to hijack the object. I can do this by changing the actual object, or by creating a subclass of the object. Either way, I need to put a call to Something at the start of each method, so that that Something can go about setting up the object, and holding off anything that's trying to get at the object while it's doing this.
This sounds like a job for a Decorator. Here is the Decorator chapter from "Head First Design Patterns".
What I'm suggesting: - Make a MyClassDecorator class that is a subclass of your existing MyClass. - MyClassDecorator should have a field of type of type MyClass that gets set with a reference to an ordinary MyClass object in a constructor. - MyClassDecorator should override each method to call something() and then the method with the same name in the wrapped object.
That way you can add or not add the "something" functionality based on some value available at runtime:
After that snippet, the rest of the code doesn't need to care whether it's dealing with a basic MyClass object or a basic MyClass object wrapped in a MyClassDecorator. They both implement the same basic MyClass interface.
This is a simplification the standard Decorator pattern in that...
The pattern is usually used when there is more than one type of additional functionality that might be added.
There is usually a separate MyClassDecorator class between MyClass and the various decorators.
Since there was only one decorator in this case, I decided to not bother with the extra overhead of the additional intermediate Decorator class.
I hope this helps.
posted 15 years ago
It does help, but I still need to be able to create this decorator at runtime - I can't code this into the classes I'll be setting up, since I don't know what those classes will be. I need to be able to take any class at all, as is, let my factory create it according to whatever, and spit it out - except I won't set it as I create it, I'll just spit out the generated dummy (sub)class (that may or may not be accessed at all, I can't tell) and set it up (via reflection, probably) as soon as anything touches it. So I need to attach a bit of code at the start of all methods that leads into that one method, something like:
A good question is never answered. It is not a bolt to be tightened into place but a seed to be planted and to bear more seed toward the hope of greening the landscape of the idea. John Ciardi
posted 15 years ago
That certainly seems to be on the right track, but it looks like that solution is limited to interfaces. I'd still need to deal with classes that don't have an interface.
I only need to create the class once, so I was considering reading in the classes, creating source code to extend the class, compiling it, and then loading and using that compiled class. That seems really messy though...
Well, I'm pretty sure you could use AspectJ for something like this. Or BCEL if you want to get your hands dirty. Both allow you to essentially rewrite class definitions at runtime. BCEL essentially lets you edit the bytecode directly; AspectJ lets you work at a higher level. You can't make completely arbitrary changes to code with AspectJ, but you can do things like inserting a log statement before all method calls in package X, or insert some new custom method calls before and after calls to method Y() in class Z. I'd look into AspectJ first.
"I'm not back." - Bill Harding, Twister
posted 15 years ago
those two seem like a lot to take in! I think I have quite a bit of reading to do.
AspectJ looks like it needs to compile everything with a specific compiler... if this is the case, I'd rather not use it. Is this the case?
It sure would be nice if I could just write
and be done with it. But I guess that that's not gonna happen