From: Demian K. <dem...@vi...> - 2011-10-20 14:53:43
|
Thanks for the detailed and thoughtful reply! Good point regarding IDE issues -- I tend to prefer minimalistic editing environments, so that hadn't occurred to me, but I can see how it could be a significant annoyance for some people. There are always trade-offs in these things! I'm not too concerned about Zend Framework 2 -- I suspect that some variation on the solution will still work no matter how they move things around. I wish they'd get on with it and put out a release, though -- it's going to be frustrating to finish VuFind 2.0 on Zend Framework 1 and then have to refactor everything yet again. I don't see a way around it at the moment, though -- ZF1 is working out quite well so far for implementing VuFind 2.0; I can see how ZF2 is going to be even better, but I don't want to make that jump until there's a production-level release of the new framework. Thanks for bringing up Dependency Injection Containers -- I'll definitely have to read up on the subject, as I hadn't heard of them before. However, based on your brief description, it doesn't sound like a good match for the problem I was trying to solve for two reasons: 1.) It solves the problems of instantiating custom classes, but it doesn't address inheritance issues. One of the important features of my solution is that it allows you to override a base class with local code and have child classes in the core code seamlessly inherit from your locally overridden class. VuFind has several areas (search objects, record drivers) where you would realistically want to add functionality to a base class without having to also override all of its children to point to a different parent. 2.) Part of my goal here is to have "drop-in upgrades" where you overwrite the core code with a new version and everything just continues to work since your local customizations are in separate files that don't get overwritten; creating a registration requirement might create an obstacle there (though I suspect this problem is not insurmountable... it just might add some burdensome configuration). Anyway, the key phrase is "a good match for the problem I was trying to solve." I don't think there's another way to achieve the effect I was aiming for, but the real question may be whether I'm aiming for the correct effect. My solution appeals to me because it allows for totally self-contained customizations that are easy to share and which don't impede the upgrade process in any way. I think it's fairly easy to understand once you know the convention to follow, though as you say, there's a certain "magic sauce" element involved. Ultimately, I'm not the best person to judge the solution, since I'm not the person who will be using it -- I suspect that I'll continue to manage my own customizations through frequent merging, which I think is the most reliable means of localizing software if you have the time to keep up with it. I'm trying to provide a reasonably clean and simple alternative for people who can't watch diffs frequently enough for that approach -- and I'd definitely be interested to hear more from somebody who actually falls into that demographic. - Demian > -----Original Message----- > From: Walker, David [mailto:dw...@ca...] > Sent: Wednesday, October 19, 2011 2:55 PM > To: Demian Katz; vuf...@li... Tech > Subject: RE: [VuFind-Tech] New blog post: Separating Local Code > Customizations in PHP > > 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 |