From: Walker, D. <dw...@ca...> - 2011-10-19 18:55:13
|
Hey Damian, Chiming in very late on this, sorry. I must say , it's a very clever solution. In fact, my worry is that, if anything, it might be a bit too clever. I wonder if this will make it more difficult to debug the code. But that's just a gut feeling, I'd have to see it in action. More concretely: Beyond the concerns you raised in the article, I would also add (1) this solutions would defeat things like autocomplete when using an IDE, since the "concrete" class names are dynamically generated, and (2) Zend Framework 2 has introduced significant changes to the auto-loading, so something to think about. A more "traditional" way in which you could achieve this -- or something like it anyway -- might be to use a Dependency Injection Container. This is all the rage now with Symfony 2 and Zend Framework 2 -- mostly for making unit testing easier, I think. Symfony has a good write-up on it: http://components.symfony-project.org/dependency-injection/trunk/book/02-Dependency-Injection-Containers The (simplified) idea here is that you move your object creation code to container objects. So instead of having this in your code: $z = new Sample(); You'd have a container like this: class Container { public static function getSample() { return new Sample(); } } And then back in your code you would call it like $z = Container:: getSample(); So now, if you want to override a function in the Sample Object, you could create a Local_Sample class that extends Sample, make the change you need, and then change the Container::getSample() method like this: class Container { public static function getSample() { return new Local_Sample(); } } The rest of your code is none the wiser. Now, at this point, you still need to change the Container class, which means editing that core file instead of the core Sample class file. But one option here might be to make the Container class itself abstract, and then have a concrete class that does nothing but extend the abstract one: class ContainerForRealz extends Container { } And then in your code, you'd always reference the concrete class: $z = ContainerForRealz:: getSample(); So, now to create our Local_Sample class, we'd simply need to create it in our local path. We'd also create a local ContainerForRealz class in our local path, and have it override the getSample() method like this: class ContainerForRealz extends Container { public static function getSample() { return new Local_Sample(); } } VUFind would use this local ContainerForRealz class in place of the core one, and in so doing, we now know to use the Local_Sample in place of Sample. So, to localize a class, you'd have to create the local class file and also the local container file -- you might think of that latter step as something akin to "registering" the new local class with the system. It's a bit of extra work, I'll admit . It does have the advantage, though, of making everything explicit (and therefore perhaps more clear) than relying on magic sauce. There are other advantages to using Dependency Injection Containers, as the Symfony site discusses ad nauseum. So you might go this route for other reasons, and just throw this localizing code feature in as kind of a bonus. Anyway, just my thoughts. --Dave ----------------- David Walker Library Web Services Manager California State University From: Demian Katz [mailto:dem...@vi...] Sent: Wednesday, October 05, 2011 10:56 AM To: vuf...@li... Tech Subject: [VuFind-Tech] New blog post: Separating Local Code Customizations in PHP During the course of VuFind 2 development, I have been thinking about ways we can more effectively separate local customizations from the core VuFind codebase in order to make upgrading simpler (among other benefits). I think I've come up with a potential solution, but it's somewhat complex. I have written about it here: http://blog.library.villanova.edu/libtech/2011/10/05/separating-local-code-customizations-in-php/ I would be very interested to hear what people think about this idea, and I'll be happy to answer questions if anything I have written is unclear! thanks, Demian |