Common Sense Driven Development

Nowadays every day or week we’ll getting new framework or tool everyone is hyped about. https://dayssincelastjavascriptframework.com/ is a great example of trolling JS people about that. Development is a lot about this new and exciting technologies but day to day life is not as simple as using the cutting edge, shiny things.

The double edged sword of Cargo Cults

For the definition I’ll fall back to good old Wikipedia:

(…) attempt to emulate more successful development houses, either by slavishly following a software development process without understanding the reasoning behind it, or by attempting to emulate a commitment-oriented development approach (in which software developers devote large amounts of time and energy toward seeing their projects succeed) by mandating the long hours and unpaid overtime, when in successful companies these are side-effects of high motivation and not requirements.

As managements issues are important, I’d like to focus more on first part of the definition.

There are from time to time new tools and practices released and world is getting crazy. I’d say React.js is one of them. Other may be Netflix Cloud tooling or good old Docker and Kubernetes on the Dev/Ops side.

And don’t get me wrong, I like them all. The difference between what you can use and what to use to make your project successful. It’s context of making decision being more important than decision itself.

Having technology solving your problem is great but you may fail because of very steep learning curve. Tool may be not supported in few months or new version will be released and you’ll have nice and shiny legacy code even before release.

What to look for

  1. Make sure you’re not trying to use the same hammer for every nail – there Is a lot of technologies and some are better in some tasks than other. Like PHP and multithreading or long running processes. You don’t want to do this to yourself. Maybe better solution will be to get people to learn a bit of Java of node.js to make this subsystem?
  2. Support – is the library you want to use “mainstream” enough for you to use it and be sure it will still exist in few years. From other hand ask yourself if you really need to use library for some very simple functionality you can write in about 20 seconds.
  3. Learning curve – Check with your team new solution can be understood and implemented correct way. As an example I can take CQRS and Event Sourcing, which are quite complicated topics and used mostly in enterprise environments. Anyway people often think it’s silver bullet for their problems and going through with it. Often they are right but as it needs time for people to learn about it’s problems it’s better to take middle ground and tart with just emitting events before switching to ultimate solution.
  4. Look at yourself first – There is a lot of companies and a lot of ideas. None of them is a silver bullet. There are also old, “bad” ideas. Like monolith. And those bad ideas are good in some cases. Like when you have quite big application to write in small team.
  5. Take authorities with grain of salt – aka Cargo Cult of the person. It happens when opinion of one person becomes opinion of the community. You know examples of that from global politics. And I’m not saying those people are wrong. They are just preaching one solution which they like. And it doesn’t really matter if it’s correct solution of programatically correct. Their acolytes will quote them in every meeting. Argument of need and correctness of the solution will be pushed back because of argument of well known person having opinion.

There is only one correct answer – it depends

I’d assume there is as many styles of coding and tools as developers in the industry. Some are better than others. Some are evolving and getting better and better. Some are legacy at the idea level but still generating revenue for the company.

Bottom line is that there is no single answer to a problem. Context of the problem changes everything and I think it’s the most important thing to look at when making technical and process decisions. And then choose which hyped tech use in the next project.

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.