Prototyping vs Maintenance

Last two weeks I was thinking a lot about whole process where I have a client on one side and a working application on the other. Fist big thing is in the title of this post. Too often we prototyping instead of thinking what happens next.

Of course it’s human factor but when I’m thinking about reason why it’s happening I say modern frameworks. Rails, Symfony, Cake. Whole “MVC way of development” which is not bad but it’s also not everything. Anyway when you check tutorials for them it looks like that. It’s also an issue with dynamic languages. They are used for fast projects and it’s quite hard to force management to think about trivial things like architecture of the new application. Fast language doesn’t mean that we should code without proper preparation.

Sooner or later we have huge codebase and we are no longer prototyping. We maintain current code and create new features in current system. And we are doomed, because we have a lot of procedures in controllers, procedures in model and some in views. Even if there are some tests they are useless when everything is done in one place and cannot be pulled outside. One common thing which I noticed lately is creating pagination objects. OK, pagination is a service in Symfony 2 but most of the time we have pagination in application and in control panel. Why the hell we are copy/paste this code when we can outsource it and put different HTML on result? When we take a look on time most of it we spent on maintenance. So why we are not investing on the beginning in good and clear code?

Because it’s hard on the beginning and it takes time to create good object graph. Design patterns are moderate easy but they need, like everything else, practice to work smooth. It’s also more code. Simple triple if can take interface, chaining class and three implementations. Instead of few lines we have few files. Is it easier way? Not yet. It pays off in few days when another if is needed and all whets needed is one class with specific responsibility and this single responsibility rule is one of factors of maintainable code.

It’s also very important when new person join the project. Simple change in method which is returning bool after 5 lines of code is easy and safe for rest of code. It’s also very testable. By the way these day I realized why I didn’t liked TDD. Testing big procedure on framework level is a waste of time. What is the idea after testing controller with 20+ lines of code? Everything inside should be tested on lower level. Controller only takes what is needed for user in view and forwards data to template. Nothing interesting. Failed test is also worthless. There is plenty of things which could failed. Let’s think about failed test of dashboard. It gathers data from all around the system and renders some graphs and tables. If test failed it can be anything from malformed HTML markup to data inconsistency id database. Good luck with finding it in less than 10 minutes.

And time is the most precious thing in our job. We get payed for getting work done in time. So please stop wasting it. Think before, not after. It’s common knowledge so use it with your job.

You are no longer application developer

Lately I watched few presentations about DDD and software architecture. What hits me after that is that we are no longer developing applications. We’re developing systems. Ask yourself when was last time when you created app which worked alone without other software?

It’s not obvious, because we are forced to use some kind of libraries for databases, AJAX request etc. Now we often have 3 applications – frontend based on some JavaScript MV* framework, JSON API in PHP, Ruby or something similar and some database MySQL, Mongo, whatever. My point is we don’t care about how this thing communicate with each other. We simply use it because it’s the convention for them and we don’t think about that they can fail or be replaced or moved. Same thing happens inside this PHP/Ruby layer. In JavaScript layer is a bit better when people are using LocalStorage, but it’s not my area of expertise.

When we are at home, in our application we don’t really care about how data are moved from one object to another. Most of the time we are type hinting for specific class, sometimes is a bit better, when we are targeting interface of specific class. Both ways it’s working fine inside application. What happens when we want to reuse component in other project or move it to different machine? Nothing scary, we create some DTOs, some serializations and we’re done. But why not use this generic date structures in first place? It’s slower? Like DTOs and serialization is fast. It’s additional work? Serialization don’t need code, right?

Another thing is possibility to reuse component in other application. That’s the idea behind Bundle system in Symfony 2. But when I see code it’s more about nicer look and feel than reusability. What I want to say that OOP in SOA is not always the best answer. When we come to border of application we can’t say to outside world that we we are using Symfony\Component\Security\User class. We are sending some raw data. Nobody cares about our internal naming.

Quick example from my current side project. I need some rating mechanism and you can say let’s create related table for “votes” and we can call this everywhere we use base entity. Nice? Easy? Yes. Reusable? Nope. I think better solution is when I have identity of object (for example class name and ID or simply some GUID) and I’m counting votes without thinking what for. It’s fast with proper indexes. It’s reusable for many types, not only for this one “related” so I can simply use this component as a vendor. Can I move it easy somewhere else? Yes. What I need are two values – object id and vote as number. No DTOs, no hacks to make it work with related table and foreign keys in main database.

So stop thinking that you are alone there. You are working on system, not only your piece of code. So be lazy, don’t be attached so much to objects and try to think more with data than how this data is named. You are (and were) System Developer.