Defining a complexity threshold cannot be done in a general discussion, but rather on a per project basis.
The regular issues to be considered:
- Do I have any deadlines? When is it supposed to ship?
- Is it production code that needs to scale well, or is it a prototype?
- Do I have performance/resource constraints?
- How much time will I have to optimize (at the end of the cycle, not from the beginning!!)?
Here's a quote by famous hacker Paul Graham:
Everyone by now presumably knows about the danger of premature optimization. I think we should be just as worried about premature design - designing too early what a program should do.
The issue here is and remains:
There is no general rule, it depends on the project.
Why should I pay for optimal?
The optimal threshold is called 'optimal' for a reason. It implements best practices based on previous experience (good/bad judgement), but what are the real gain? Why should certain tasks be coded in low-level rigid assembly, and others should be written in some meta-macro or pseudo-code?
A solid (complex) design, mainly gives two things:
* Large code base: How will programmers interact with one another? How can I make changes to one class that won't break everybody's code? Are parts of my code redundant and can be united?
* Stability: Will my code handle heavy load? concurrent access? Exotic input? Hacking attempts?
These benefits are consequent and very important, yet they only come into play when scalability is in play. And quite frankly, in 99.99% of the projects, (the web projects anyway) this won't be a priority.
The cost you put in dev time will handicap you, and when you start a project, you want to be reactive and flexible. Be able to make changes at any moment.
A highly publicized case study could be
Twitter's move from Ruby to Scala/Java.
Twitter rose to fame arguably because of the simplicity and the beauty of the RoR framework. With this flexible framework, they were able to move fast, react to bugs and add new features faster than ever before. Today, it is one of the biggest websites in the world, and as such, they are migrating their framework to Java, a more complex one, in order to handle the new load.
Is the migration from Ruby to Java expensive? very.
Should they have started with Java from the start? Hmmm.... I think that the fact that they went with RoR made sense in the beginning.
My point is: quick and dirty will often save your ass.
Another example I witnessed in a
talk given by Sir Tony Hoare, the inventor of the NULL value. In his talk, he explained how NULL was theoretically impure, and gave room for the programmer to be lazy and therefore filled the industry with poor designed code everywhere.
In the Q&A section, a programmer said that he is part of the team of inventors of Erlang, a functional language. That they managed to solve the problems induced by the NULL issue, yet NULL was a good idea, because without it no progress would've been made in the past 40 years.
My point is: quick and dirty will sometimes allow you to move on to greater things, even if it means you'll have to come back and fix it later.
I was recently asked in an interview what are my favorite aspects of Python. I answered the lack of encapsulation. By freeing developers from these constraints, the productivity boost is consistently bigger and will allow you to be considerably more productive. Yet it comes at a price, where collaboration amongst multiple developers can be tricky. I would never adopt this quick and dirty approach for a large project.
Finally, a blog post I want to share.
The Mature Programmer. In this rant, the author talks about the "Mature Programmer". MP is someone who will deliver, get results and be highly productive. He won't lose time in futile stuff and "sexy coding". We's a go to the point guy.
Yet does he have fun? We all got into programming because it was fun. So yeah, I say
go ahead, write your 6 classes instead of 1. If you believe that is better and optimal. Programming should be fun, and should be done the way you believe is right.