Factory factories, or dependency injection, is a lot more like Futamura Projections than a factory factory factory factory because you want a hammer.
On Futamura Projections: http://blog.sigfpe.com/2009/05/three-projections-of-doctor-f...
(And that's fu-ta-mu-ra, a Japanese name; not fu-tu-ra-ma, the TV show. I read it wrong the first time, and so did everyone I've admitted that to :)
But I stand by the tongue-in-cheek suggestion that FactoryFactories are high altitude if not low earth orbit. And obviously, you can use factories and still switch between production and development with a single flag. So please don't interpret my remarks as critical of code I've never actually seen.
I don't see interfaces and plugins as being orthogonal at all, you can't very well have plugins without interfaces (it wouldn't be much of a plugin if the client depended on the "plugin" itself). Besides, orthogonal vectors don't get you to the same place. ;-)
In my opinion, the defining feature of a plugin is that it can be loaded and used with no modification of the code that uses it. On architectures with dynamic loading, this means you can drop a DSO somewhere and use it without code modification or relinking. "Factories", as usually described, would require some modification of the factory to support this new implementation (perhaps just a single line). A "factory" with a runtime-extensible list of implementations that it knows about, is a plugin architecture, but a plugin architecture need not look anything like a factory.
That being said, you clearly can implement indirection without plugins. I think of a plugin architecture as being composition at a coarse level. In the case of a factory with a runtime list of implementations, I think of that as a factory and a plugin architecture, possibly that the plugin architecture is implemented with a factory.
This may give you millions of combinations, but since the various parts that don't need to interact can't interact, this isn't really a problem. OOP is nice when used by people that know OOP.
An advantage of keeping an old code in its own branch is that it's less likely to become incompatible through random changes. In particular, I'm thinking of bug compatibility: there may be bugs you wish to fix in the new code, but you don't want to fix in the older code because of third-party dependencies.
a nice upside is that you can merge changes to each feature up into the "combined" branch as they get stable, to test side by side. when you finally finish, you can leave feature a behind by merging b into your release, or vice versa. or maybe even merge both into mainline.
sorry, the point I was trying to make is that cheap branching and merging is still an easier way to manage this situation than just ignoring branches altogether.
A: Create separate branches, manage merging/updating unrelated changesets.
B: Create 2 implementations of something in code, and manage nothing.
I guess it depends on how easy it is to isolate the part you want to create 2 implementations of, so it may depend on what language you're using as well as how you architected things.
Branching+Merging just seems like something extra I have to do, manage, and remember. Like filing. And I still can't see what benefit it gives for many cases.
But that's fine I think... I just don't get it. Maybe I'm too old ;)