The consequences of living with a legacy PHP framework
blog.yannickmahe.com
blog.yannickmahe.com
Just look at all the pain Ruby devs have felt moving from various rails versions. https://railslts.com shouldn't have to exist if we were doing our job as software developers.
Using a framework is a HUGE tradeoff. You are trading ease of development for a kind of vendor lock-in where the cost to move goes up with every line of code you write.
Using an architecture that lets you write framework-independant code is a huge win and would keep you out of this kind of trouble. I wrote Obvious Architecture http://obvious.retromocha.com for this reason, but there are plenty of clean architecture examples here: http://blog.8thlight.com/uncle-bob/2012/08/13/the-clean-arch...
As far as I'm concerned, you're digging a hole either way, it's just the shape of the hole that changes.
The bottom line is that there is too much code to maintain (or migrate, or rewrite, depending on the shape of your hole) and never enough resources/people/budget/time to do it.
Everything is a huge tradeoff.
The truly useful code of the application will quickly become overwhelmed by the code that tries to abstract away the high-level abstractions offered by the frameworks being used. The boundary or interfacing code you mention ends up becoming a custom framework in and of itself, but usually far more limited than the underlying frameworks.
It's pointless to use a framework in the first place in order to reduce the time and effort needed to build a software system, only to immediately try to abstract it away with a bunch of custom code.
As an industry, we've seen these kinds of systems in the Java world for many years now, and they never turn out well. The performance is awful due to the layers upon layers of abstraction. It becomes extremely difficult to partially, never mind fully, comprehend such a system. This in turn makes even simple changes risky and awkward. And in virtually all cases, the abstractions end up being useless, because the underlying framework is never actually changed at any time. And in the rare cases that it is, a huge amount of work is needed anyway because the code abstracting away the framework never does this perfectly.
The cost of implementing and maintaining the type of abstraction that you propose can easily exceed the cost of rebuilding from scratch software systems that are highly tied to one or more frameworks.
Everyone says this, but then finds time for FB/Twitter/HN during the day. Something doesn't line up. This is a question of priorities, and people not feeling the effects of hard coupling to a framework.
Not to mention extravagant lunch breaks spent chewing food instead of inhaling Soylent, trips to the bathroom and time wasted milling around the proverbial water cooler.
More to the point, the technical debt being discussed here isn't solved by increasing office productivity by 5%.
So, yes. It's OK if you don't, but I think it's worthwhile foregoing social media sometimes to work on studying and upping your game.
Besides, you don't always have to be in "OMG not enough time to do this nicely!" mode. Such a mindset is reactionary and generally not conducive to writing robust code. I'd rather go a little slower and not have to return to parts of the codebase later.
I do believe that thinking more and working less on work will solve more problems though.
I wrote against Symfony 1.0 and the upgrade to 1.4 needed a partial rewrite (look, new form library!).
I wrote against Symfony 1.4 and the upgrade to 2.X ..well hasn't happened, a recession got in the way and clients want to spend money on something that'll have results.
I don't mind legacy code - heck I make a good living from it. But I wish framework developers (and everyone online) would agree that slower, more evolutionary progress is OK.
-- A cynical developer, who's seen fads come and go too many times
the thing about frameworks is that you don't get the goodies unless if you upgrade, but you wouldn't get the goodies anyhow unless if you wrote it yourself.
It's a tradeoff, but usually a worthy one.
It's entirely possible to decouple yourself from a framework and move quickly. It's just that most devs are incredibly lazy, and most frameworks are specifically engineered to make this difficult.
I think you mean frameworks are specifically engineered to allow devs to be lazy.
Doctor, it hurts when I couple my code to a framework in an attempt to save time and effort writing boring things I don't care about.
Then stop doing it, silly.
Portability requires effort. It pretty much requires you to not use all-encompassing frameworks. But I'd be shocked if the average JS code slinger today has even heard that word before.
Frameworks mean you get to skip the design step, at the risk of having you by the balls later on.
I use Yii, for example, and pretty much only utilize permissions filtering, routing, view management, and AR. The form, theme, and other niche tools are all unused.
This way, when upgrades come along I only really need to be aware of controller files, model files, and view files (all php template and raw html, no helpers). Models are auto generated off the schema, so those are a one click fix on a new base.
This almost makes it sound like an attempt at intentional lock-in which I find fairly unlikely.
Can you elaborate?
It's the tradeoff of simplicity: framework authors want to make things easy (and this is commendable).
Probably a better way to put it: developing legacy code is like living in the past with the benefit of knowing the future. You miss all of the modern tech and constantly remind yourself how much easier it would be if only you had XYZ. But it's unfair to criticize those past decisions with the benefit of hindsight. When writing my expressive scala code, I sure wish the computer would just know what I mean and auto-complete my code... it would be obvious to one ten years from now :)
Using fear to choose the 'Obvious' framework over choosing Rails or rolling your own seems silly to me given you can find tons more people who know Rails (your boutique shop hopes to grow, right?) and tons more products designed to work with Rails. That ecosystem bonus seems to more than offset any tie-down to an open source framework. Will there ever be Obvious LTS?
You're right that there is a tradeoff in picking a framework, but I think we disagree on the costs behind that tradeoff.
Rails all of a sudden is terrible? Switch the routing/views/controllers to Sinatra. Want to move over to something Java based, you can still use a bunch of your core app code via JRuby and maybe slice out bits into Java/Scala over time. Want to switch from Mongo to Postgres, swap out the database module.
My point is, the switching cost doesn't have to be an entire codebase rewrite to move from one thing to another. It only exists that way because the default framework path is tightly coupled by default.
As to if people should use Obvious? Well it's just a pattern of how you put code together. It's not a framework and it's not the only way for people to get the same benefits. I don't care if people use it or not. Use Hexagonal Architecture or Onion Architecture or DCI or whatever the flavor of the week is. It doesn't matter.
The point is, your code doesn't have to be tightly coupled to any framework. There are good options and patterns out there and just defaulting to any particular framework's defaults will lead you down the same path as the OP.
My professional career has worked with codebases that have a median age of 5 years and millions of lines of code. Most projects have 50 or so developers across timezones. Say we wanted to switch out rails for sinatra, it simply would never have been possible, even if we perfectly isolated rails from our business logic using an adapter like Obvious. The concrete details most often leak through the adapters -- remember, people are sometimes hurried or sleep deprived or forgetful. We would have had to stage the work, do it in phases just to test properly, and most likely leave the legacy stuff alone -- "If it aint broken, don't fix it."
Shame about WSGI (despite it's benfits) being so inflexible though. It'd be good if there was some sort of "socket gateway interface" for pythonn spec that allowed Python apps to do stuff like websockets. IIRC WSGI cannot do that as it's all about single request/responses.
Might look into what can be done with async stuff (gevent) and uWSGI 1.9.
In other words, you don't want to live on the bleeding edge necessarily, but it's a bad idea to let yourself get too far behind it too.
1. Need to update to support newer PHP versions. Check.
2. Lack of community support. Check.
3. Can't draw on 3rd party plugins. Check.
etc.
Plus he would have had the burden of writing his own in the first place - or the overhead of coding without a framework.
So - how does this lead to the conclusion that he would have been better off not using Symfony?
The lesson I drew was "choose your framework wisely and don't accrue technical debt".
Most plugins for 1.2 offer versions for both Prototype and jQuery.
In general, Symfony 1.* was easier to work with than 2.0. Symfony 2.0 feels very much like a Java project in that they prefer mounds of configuration files, reflection, annotations, etc, all to do something very simple - routing and view management.
Even after a couple projects I still didn't "get it." Most of my time was spent in the docs and stack overflow trying to learn the "symfony way" of doing things rather than just getting it done.
- Too much nesting, both in file layout and yaml configurations - Too many different ways to do things (YAML, PHP, .ini, file annotations) - Too verbose when coding (namespaces, long class and method names) - And don't get me started with Twig
I took those hard knocks and tried to write my own mini-framework, which only taught me why you don't write frameworks. It is really hard to do well.
Then I found laravel [1] and have been impressed. It is more opinionated than Symfony and feels more cormfortable to develop on. Less configuration, less verbosity. I combed through the docs and had a project up and running in two days.
But here is the real nugget, kids. Using a framework on a long-term project is like marriage. It takes commitment. You will be in it for a while, so you had better make sure you can live with it. You have to invest your time and effort into it to understand it as much as possible -- warts and all.
[And yes, I know large stuff can be built with the others, like it can with Drupal. But does the framework make it as/more easy than Symfony, that's the question?]
A free rant :): I hate the Doctrine ORM for it's hideously bad documentation (either missing information or written by core devs for core devs -- I can't contribute to improving it as I don't understand it well enough!) yet I appreciate a 'real' ORM vs an ActiveRecord+QueryBuilder system. Gah.
Nothing I've made has required a lot of input form complexity, which seems to be Symfony's strong suit.
I think you might be right about the project sweet-spots. Symfony certainly seems equipped to handle workloads you describe -- I've not seen form input validation as complex as Symfony.
TL;DR: I think Silex has changed a lot since I looked at it. I can't give you a good answer.
I am interested in people's experiences with using a third-party system and trying to keep it updated versus using an in-house system that gradually becomes more difficult to update/maintain.
Sometimes a state of permanent updates can be just as limiting.
I do not know if it is feasible in all cases. Having many frameworks allows to anticipate the problems, cost and benefits of a migration. I think it is interesting for developers who will have more interesting work. The cost of many framework may be compensate by the fact that it is easier to associate a migration cost to a client.
But when you start to create larger systems, you will have to think about maintaining the code, adding new features and fixing bugs. Then it is not so fun if your code depends too much on a framework and you don’t update it when new versions are released. It is not fun googling for something and in the one result you get someone is pointing out that you are using an obsolete framework, and noticing that the post is 10 years old. (Did happen with some software I used to be developer on)
Might be called that now. When I was working on big systems it was called Service Oriented Architecture.
When I'm writing a new feature, I always try and code it as if I'm going to release it as a standalone library that could easily work for other people regardless of what framework they're using.
Stuart Herbert wrote a lot about this: http://blog.stuartherbert.com/php/php-components/
The solutions was in fact simple: we told our customers we wouldn't add any features or changes other than bugfixes. When you are telling the software is outdated and the support is gone they all understand it's time to move on [1].
Most of the time the customer also wants to get rid of the outdated website/webapp. So it's also a good reason to start something new.
[1] Ofcourse this doesn't work for all customers.
Or did you have a new version ready and at (near) feature parity with the old version? As the article describes, that investment can become very large when you put it off for too long. And the reasons they had to put it off were, at least initially, quite valid.
Anecdotal, there's a company that built their core product on Symfony 0.9x, and never upgraded. That was started around 6 years ago. The company is now worth 1+ billion on nasdaq, and still relies on Symfony 0.9x for the core functionality.
From a development point of view it sucks. Ask any developers.
From the business point of view, staying away from the kind of 6 month no feature s-bugs-only period you're talking about, is probably the reason it could beat its main competitor, and succeed the way it did.
Because the latter fixes itself with time as the community tests version 1.2 and patches come out, but not having tests for your own code that don't rely on the framework prevents you from being able to move fast on anything but the smallest of refactorings.
I think that's how you can get yourself out. Ruthlessly write end-user acceptance tests (something that drives a browser, headless or not, Selenium, PhantomJS/CasperJs, etc etc) that verify all your functionality. Only once you can quickly and automatically verify correct operation can you then do something like a framework migration (even if to latest Symfony 1.x).
About your case, I agree with you that the best way for you is to add component by component, extracting and encapsulating functionality so you can use Symfony2, Zend or whatever framework you want in the future. Go for a service oriented architecture. And let's hope you have everything tested!
Right now I maintain about 70/30 old code to new code. Most of the old code is because previous developers didn't care at all and were more interested in job stability than code stability. You make a conscious effort to not follow the trends with the framework and thus can only blame yourself for the outcome.
It is a problem -- I have apps that i only barely got upgraded from rails 2 to 3 before 4 came out. Hopefully upgrading to 4 won't be as much of a nightmare... but I'm still procrastinating it, even though I know if I wait too long to do it it will just get worse.