To be a lazy developer or not to be a lazy developer? [closed] - visual-studio

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
Am I a lazy developer?
Is it being lazy to use automated tools, such as code generators and such?
Now, I could, if I had to, create all the data layers and entities I needed, but I choose to use CodeSmith to generate my datalayers and entities.
I also use Resharper and I would say it fights with MSDeploy as to which gets installed first after Visual Studio.
Again if I had to, I could code without it, but prefer not to.
Both these tools from my point of view are no brainers as they improve output massively.
But is this lazy?
I'm sure there are purists out there that would say everything should be wirtten by you so you know what everything is doing, but if you can read through the code and see what is happening is that ok?
So am I being lazy or am I just using all the cards in my hand?

In programmers, laziness is a virtue, so don't worry.

It's only lazy if you use a tool to produce code and use it as-is without verifying that the code meets your needs and abides by your standards.

You don'nt need to reinvent the wheel n times, this is done often enough. Briefly I'd state that using tools like the ones you mentioned (within reason) is absolutely no problem...

For you? No, you're not being lazy.
For the guy that doesn't understand what code generators are doing and how they do it? Yes, it's being lazy.
That's the important distinction: You have to know what you gain and know what you're missing by using a code generator. If you don't, it's only a matter of time before you come across a case where you have to be able to produce those classes and not know how.

Both these tools from my point of view are no brainers as they improve output massively.
This means you're not being lazy, you are using the appropriate tools to enable you to concentrate on the important aspects of the job.

It's not being lazy - it's being smart. There's nothing wrong with using every tool at your disposal...as long as it makes you more productive. Using tools for the sake of using tools is a bad idea.
However, if you don't know what your tool is doing under the hood, you should learn about it so if you don't have the tool available for some reason, you can get the job done.

I think that's the wrong question. Laziness is a virtue. I've seen too many programmers who do things the hard way rather than sitting back and thinking for a few minutes to come up with an easier way. I've had so many times that I've said to a junior programmer something to the effect of, "Yes, I respect your diligence in working through lunch and staying late to write the code to do X, but if you'd taken a few minutes to check the documentation you might have seen that there is already a function in the library that does that". Or similar stories.
I'm not familiar with the specific tools you describe, but to me, the question always is, Does this tool actually save me any work? I've tried plenty of "code generators" that basically just create code stubs. So gee, thanks, you wrote the "function x(int, float)", now all I have to to is fill in the actual parameter names and write the code. What did that save me? I've also seen plenty of code generators that write really awful code. So now I have to try to add the "custom" code to this jumbled mess. Wouldn't it have been easier to just write the whole thing cleanly the first time? I've seen plenty of productivity tools where I found it takes me more time to set up the parameters to run the tool than I actually saved by using it. (Like the old joke that it's been proven that jogging regularly really does make you live longer: for every 60 minutes you spend jogging, it adds 30 minutes to your life.) Some tools may produce code or data structures or whatever that is difficult to maintain, so you save an hour today but it costs you ten hours in maintenance over the life of the project. Etc.
My conclusion isn't that you shouldn't use productivity tools, but rather that you should make sure they really are increasing your productivity, and not just giving an illusion of doing so. If in your case you find these tools really do help you, then using them is not "cheating", it's simply smart.

As everyone else already pointed out there's nothing wrong in your use of code generators.
Still I can see downsides and reasons to avoid it in certain particular sitations.
choice of language. Sometimes the very same fact you need a code generator to get your coding started could imply you're using the wrong language for the task. Most times language cannot really be chosen, so code generators remain the best way to go.
code redundancy. Depending on the actual generators used, generated code could be redundant, if this happens and generation happens once, isn't automated, and generated code goes into the main repository maintenance problems could arise in the long run. Not really a problem with code generation itself, but with the way it should and should not be used.
adding development platforms requirements. We have to concede many programmmers out there work on bread-toasters doubling as PCs. It's really a bad, (and sad) reality of cheap business practices meeting sharp minds. (sharp minds go to waste in the process) It could become a concern if our project (which could have a port in store for the future, and in an external facility either) needs an hefty, ram hogging, not enough cross platform, IDE handy to compile every little modification.
So, no definitive answer on code generating lazyness and programmming: it depends. Then again, using the wrong tools for the job is bad for your health, (and business) so... don't.

You're using all the cards in your hand. Why reinvent the wheel when there are tools available to make your job easier. Bear in mind these tools DON'T do your job, they only assist.
What you create is down to you, so using the tools is not lazy... it's just intelligent.

I'd say you're more efficient rather than lazy.

Programming is primarily a thinking exercise not a typing one. So long as you understand what the tools are doing you're shifting the balance away from typing to thinking. Doing more of what your job is about? Doesn't sound like lazy to me!

I'm sure there are purists out there that would say everything should be wirtten by you so you know what everything is doing
This might have been a viable point of view during the early days of programming. But nowadays, this is simply not feasible (or even preferable). After all, you've already obscured a certain level of understanding just by using a high-level language.
That said, I've found it to be a great learning exercise to write some of these things by hand occasionally. Not only do you get to learn more, but they teach you how helpful these tools really are (or aren't). Note that I'd only do this on a personal project though. I wouldn't do this for any project someone was paying me for (unless I were working for a masochist or something).

Ask yourself why there are so many ORM and other code-generation tools around. I'd say go for it with the proviso that you leave it maintainable for the next guy/gal.

Programming is about being lazy, about automating repetitive tasks. If you can't do that inside your language, using code generators and similar things is a useful workaround.

It depends on what you're writing, of course. I am suprised nobody's brought this up. If you're writing device drivers, operating systems, protocols, or server software (web servers, tcp driven servers, etc), you should probably do it by hand.
But with what I do and probably what a lot of us do is implement business processes in code for web pages or web services. And in those areas, if you can improve on your code with code generators, go for it.

Yes you are being a lazy developer, be honest to yourself, if you take the time to do it the hard way you can call yourself less lazy than you are now.
The point is, being lazy isn't inefficient at all.
Lazy people take time to look at the problems from different direction before acting upon it, this avoids unnecessary errors which saves you valuable time.
So you're being lazy, but that's ok. People don't hire hyperactive coders that make 10 applications each day but leave a trail of bugs on their path. bug-fixing costs time, time is money.
conclusion:
Laziness = profit
Go for it.

I think the best developers are also the laziest. Basically, all you're doing should be focused on getting the end result with the least amount of work. This often provides the best result and also avoids developers from being distracted by fun things to include in a project. A lazy developer would e.g. never add an easter egg to his code, simply because this would be more code, which could introduce more bugs that need to be fixed later on. Adding code is bad, since you'd also add more bugs that you need to resolve later. Still, you will need to add code, else you won't get paid. So, as a lazy developer you would of course choose for the most optimized code, the best-tested code which would almost never fail and you'd work in a way that the chance of errors is reduced to a minimum.
Do keep in mind that lazy developers should focus on avoiding work in the future, not on avoiding work right now! So stop reading here and get back to work! ;-)

Laziness is a trait that most good programmers have. Unless they work for Adobe, in which case they are often lazy in a bad way.

Related

Do you think VS and Intellisense make us dumber? [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
Improve this question
I read this article, the parts of "Intellisense" and "Generated Code":
http://www.charlespetzold.com/etc/DoesVisualStudioRotTheMind.html
Do you think the Author's is right?
I don't agree that Intellisense is soooo bad for programmers. VS for C# uses to "hide" the controls' events in another file, but you can find them if you know enough about the language and you can modify them by hand. And with VS I don't need to memorize all the .Net classes I use.
I think it doesn't matter if you use an IDE or notepad but, if thsese RAD tools exist and are free... Why not to use them?
No I very much disagree with this point.
Yes, I do agree that intellisense allows me to keep less of an objects growing number of members in my head. I am dumber in the sense that I often know less about the intricate details of projects where I use intellisense heavily.
For instance, I can probably rattle off all of the members of the C++ types I use with great accuracy. I tend to be a VIM only guy for my C++ projects and hence don't really use intellisnsee. In C# and VB.Net projects though I couldn't rattle off the members with the same accuracy as I rely on intellisense more often.
But there is a trade off. Keeping all of the members in my head comes with a cost. When writing code, instead of focusing on the algorithm, I focus on the members. I have to constantly think about the naming convention of a particular type, or the parameter list, what's byref or by val, when writing out an algorithm in C++. In C#/VB.Net I'm more free to think about the algorithm as the IDE takes care of finding the members for me.
Does this mean I'm dumber? No it simply means I'm able to focus on the problem I'm actually trying to solve. I feel this makes me more productive and hence smarter not dumber.
It doesn't make smart people dumber, but it makes dumb people look smarter
No, modern programming tools and languages help the programmer focus less on the little things and more on the big picture.
The main goal is to design solid software. If a programmer doesn't have to worry about memorizing every method of a class, they can spend more time on engineering the product.
Our physics prof always said why memorize something you can look up. He always listed the required formulas on the board during exams. Seems to be intellisense is the same idea. Rather than remembering if the object uses a Count or a Length property, let VS tell me.
No, it enables us to code faster I think. Anything to make the coding process faster, easier and simpler is a step in the right direction in my opinion.
Not dumber, it makes us faster :)
I use intellisense and generated code to speed up development, not because I don't know what I'm doing. Therefore, I can't agree that using them makes you dumber.
I am the kind of person that will try to learn as much about a language as possible before attempting to use the tools that facilitate development in that language. In that regard, I have to agree with Matthew Jones' comment that "tools do not make people dumber...laziness and lack of drive do."
Programming is just moving forward to make life easier for the programmer and making him more productive.
It would be like complaining that we don't write assembly code anymore... it's important to know the big concepts and ideas behind it, but working with it would be weird (in most cases).
I don't think so.
Intellisense makes things like case sensitive spelling easier.
Is it MyArray.Count() or MyArray.Size() or Length(MyArray) ... ? Which return type is a particular method, again? Intellisense saves me a few minutes every day on Google for things like this.
Detail memmorization is not the most important skill in software development. It is better to have problem solving skills and the ability to find the information you need. If you invest more time in the details you will be lost when the next greatest language is born, but algorithms and patterns will still be relevant.
The question is of course....does Intellisense make programming less of a skilled profession?
Yes, I agree with the author. Intellisense (and many other Visual Studio features) is indeed "making us dumber" for the reasons mentioned in the article.
That's not always a bad thing. Sometimes it's more desirable to be productive than it is to get smarter. The challenge is striking the right balance. :)
The only qualm with IntelliSense that the author seems to have is the autocomplete when you press the space bar, which apparently he doesn't realize you can turn off in the Options menu.
Although, he claims that coding "has become a constant dialog with IntelliSense"... which makes no sense because you still have to pick the correct methods from the list! Without it, you'd simply have to search online for the name of the method instead of an instantaneous search.
It's interesting how the author ignores that IntelliSense can't tell you whether to use a StringBuilder or a String, etc.
Not at all. When the intellisense list pops up, does a programmer search through the whole list every time to find the function they were looking for? Maybe at first, but normally you keep typing until intellisense narrows down the list to the point where it's faster to use the up/down arrows and tab to complete.
Without intellisense, it would take a little longer to code given that you are experienced with the classes that you're using and a lot longer given that you aren't. It only serves as a speed tool and quick documentation of everything that's available.
It doesn't make us dumber; it is a necessity.
Back in the day (MS BASIC for me), there was no need for intellisense. The scope of the language was limited enough for a programmer to remember all keywords and functions.
Jump to today, intellisense is an absolute requirement. Take .Net for example. There is simply no way to remember or discover the many thousands of types, properties and methods. Oh sure, for a very small project you may know a bunch (100s?) of items. But let's be honest - there is no way a modern working programmer could exist without it.
Adding my two cents here.
From my own experience and as mentioned in the TFA I would say that the only drawback I've encountered so far is when you learn the language you might pick up bad habits. Using ArrayLists instead of List only because you're not aware of changing use clauses enables might give you some other datatype.
The author complains over that he gets the wrong datatypes when entering certain datatypes. While some of you will probably get a license, a weapon and start the man hunt, I've found that using naming conventions is an excellent way of forcing the intellisense to be working my way, especially when working in GUI-Control intensive forms & stuff.
No more so than calculators made for poorer mathematicians and physicists. Sure, using a slide rule forces you to keep a mental model of the order of magnitude of things, but it is really just a tool ... and better tools let you do better work.
This can be abstracted into the traditional question:
Does knowing more about the details help or hurt?
As a rule, experienced engineers and craftsman say, help. But knowing the details also lets you know when the details don't matter, which is what Visual Studio/Intellisense provides. (I'm sure there's a pithy proverb that could be said here, but I don't feel up to thinking up a quip).
Dumb & Lazy.
Interesting question. Sure I find Intellisense in some sense makes the job easier, but it's kind of like money. The more you have, the more you spend, not necessarily on things you need. I learned to program around '62, and somehow I got along without Intellisense for a really long time. What Intellisense does for me now is help me remember lots of classes and members that as little as 4 years ago I never knew I needed.
There's one tendency I've seen in software that never fails. Nature abhors a vacuum. Machines get bigger, so guess what, software gets bigger (but not always better). Machines get faster, so software gets slower. Now people can get help typing long names, so the code gets really verbose. Now people get help remembering lots of classes, so guess what, there are lots more classes to remember. This goes a long way to helping the software get bigger and slower.
I do a lot of performance tuning, and what is the dominant cause of slowdown? It is galloping generality caused by overdesign with too much data structure, too many classes, and too many layers of abstraction. In a word, "bloat". Here is just a small example.
I find Visual Studio's tools conducive towards more experimentation. When you're dealing with the Win32 API in C (for example) you can't really poke around too easily. When you're working with C#, it's a snap to have a little explore around a library and learn what it does without breaking out MSDN or a disassembler for the entire evening.
If you're a naturally curious programmer, Intellisense won't change that. If you're not, Intellisense won't change that either. To paraphrase one of my colleagues "I think it's a waste of time looking through huge books when you can just take an implementation from the web and move on to the next thing".
It's an old argument anyway, pre-Intellisense. Does BASIC rot the mind where writing in x86 doesn't? Is knowing an algorithm inside out relevant when every single programming language you're going to use in your role has a tried and tested library?
I find that those who consider programming a hobby or a skill are inclined to comprehend and investigate. Those who consider it the day job don't. Regardless of any frippery around it, it's more about a programmer's mindset than what is made available.

What are some good strategies to fix bugs as code becomes more complex?

I'm "just" a hobbyist programmer, but I find that as my programs get longer and longer the bugs get more annoying--and harder to track. Just when everything seems to be running smoothly, some new problem will appear, seemingly spontaneously. It may take me a long time to figure out what caused the problem. Other times I'll add a line of code, and it'll break something in another unit. This can get kind of frustrating if I thought everything was working well.
Is this common to everyone, or is it more of a newbie kind of thing? I hear about "unit testing," "design frameworks," and various other concepts that sound like they would decrease bugginess, make my apps "robust," and everything easy to understand at a glance :)
So, how big a deal are bugs to people with professional training?
Thanks -- Al C.
The problem of "make a fix, cause a problem elsewhere" is very well known, and is indeed one of the primary motivations behind unit testing.
The idea is that if you write exhaustive tests for each small part of your system independently, and run them on the entire system every time you make a change anywhere, you will see the problem immediately. The main benefit, however, is that in the process of building these tests you'll also be improving your code to have less dependencies.
The typical solution to these sort of problems is to reduce coupling; make different parts less dependent on one another. More experienced developers sometimes have habits or design skills to build systems in this manner. For example, we use interfaces and implementations rather than classes; we use model-view-controller for user interfaces, etc. In addition, we can use tools that help further reduce dependencies, like "Dependency injection" and aspect oriented programming.
All programmers make mistakes. Good and experienced programmers build their programs so that it is easier to find the mistakes and restrict their effects.
And it is a big deal for everyone. Most companies spend more time on maintenance than on writing new code.
Are you automating your tests? If you do not, you're signing up creating bugs without finding them.
Are you adding tests for bugs as you fix them? If you do not, you are signing up for creating the same bugs over and over.
Are you writing unit tests? If not, you are signing up for long debugging sessions when a test fails.
Are you writing your unit tests first? If not, your unit tests will be hard to write when your units are tightly coupled.
Are you refactoring mercilessly? If not, every edit will become more difficult and more likely to introduce bugs. (But make sure you have good tests, first.)
When you fix a bug, are you fixing the entire class? Don't just fix the bug; don't just fix similar bugs throughout your code; change the game so you can never create that kind of bug again.
Bugs are a big deal to everyone. I've always found that the more I program, the more I learn about programming in general. I cringe at the code I wrote a few years back!! I started out as a hobbyist and liked it so much that I went to engineering college to get a Computer Science Engineering major (I am in my final semester). These are the things that I have learned :
I take time to actually design what I am going to write and document the design. It really eliminates a lot of problems down the line. Whether the design is as simple as writing down a few points on what I am going to write or full blown UML modeling (:( ) doesn't matter. Its the clarity of thought and purpose and having material to look back at when I come back to the code after a while that matter the most.
No matter what language I write in, keeping my code simple and readable is important. I think that it is extremely important not to over complicate the code and at the same time not to over simplify it. (Hard learned lesson!!)
Efficiency optimizations and fancy tricks should be applied at the end, only when necessary and only if they are needed. Another thing is that I apply them only If I really know what I am doing and I always test my code!
Learning language dependant details helps me keep my code bug free. For instance I learned that scanf() is evil in C!
Others have already commented on the zen of writing tests. I would like to add that you should always do regression tests. (i.e. Write new code, test all parts of your code to see if it breaks)
Keeping a mental picture of code is hard at times, so I always document my code.
I use methods to make sure that there is a bare minimum dependence between different parts of my code. Interfaces, class hierarchies etc. (Decoupled design)
Thinking before I code and being disciplined in whatever I write is another crucial skill. I know people who don't format their code so its readable (Shudder!).
Reading other peoples source to learn best practices is good. Making my own list is better!. When working in a team, there must be a common set of them.
Don't be paralyzed by analysis. Write tests, then code, then execute and test. Rinse wash repeat!
Learning to read over my own code and combing it for mistakes is important. Improving my arsenal of debugging skills was a great investment. I keep them sharp by helping my classmates fix bugs regularly.
When there is a bug in my code, I assume its my mistake, not the computers and work from there. That is a state of mind that really helps me.
A fresh pair of eyes aids in debugging. Programmers tend to miss even the most obvious errors in their own code when exhausted. Having someone to show your code to is great.
having someone to throw ideas at and not be judged is important. I talk to my mom (who is not a programmer) , throw ideas at her and find solutions. She helps me bounce my ideas back and forth and refine them. If she is unavailable, I talk to my pet cat.
I am not so be discouraged by bugs anymore. I've learned to love removing bugs almost as much as programming.
Using version control has really helped me manage different ideas I get while coding. That helps reduce errors. I recommend using git or any other version control system you might like.
As Jay Bazzuzi said - Refactor code. I just added this point after reading his answer, to keep my list complete. All credit goes to him.
Try to write reusable code. Reuse code, both yours and from libraries. Using libraries which are bug free to do some common tasks really reduces bugs (sometimes).
I think the following quote says it best - "If debugging is the art of removing bugs, programming must be the art of putting them in."
No offense to anyone who disagrees. I hope this answer helps.
Note
As others Peter has pointed out, use Object Oriented Programming if you are writing a large amount of code. There is a limit to code length after which it becomes harder and harder to manage if written procedurally. I like procedural for smaller stuff, like playing with algorithms.
There are two ways to write error-free programs; only the third one works. ~Alan J. Perlis
The only way for errors to occur in a program is by being put there by the author. No other mechanisms are known. Programs can't acquire bugs by sitting around with other buggy programs. ~Harlan Mills
Obviously, bugs are a big deal to any programmer. Just look through the list of questions on Stack Overflow to see this illustrated.
The difference between a hobbyist and an experienced professional is that the pro will be able to use his experience to code in a more "defensive" way, avoiding many types of bugs in the first place.
All the other answers are great. I'll add two things.
Source control is mandatory. I'm assuming you're on windows here. VisualSVN Server is free and maybe 4 clicks to install. TortoiseSVN is also free and it integrates into Windows Explorer, getting around the VS Express limitations of no add-ins. If you create too many bugs, you can revert your code and start over. Without source control, this is next to impossible. Plus you can sync your code if you have a laptop and a desktop.
People are going to recommend many techniques like unit testing, mocking, Inversion of Control, Test Driven Development, etc. These are great practices, but don't try to cram it all into your head too quickly. You have to write code to get better at writing code, so work these techniques slowly into your code writing. You have to crawl before you walk and walk before you can run.
Best of luck in your coding adventures!
This is a common newbie thing. As you get more experience, of course, you'll still have bugs, but they'll be easier to find and fix because you'll learn how to make your code more modular (so that changing one thing doesn't have ripple effects everywhere else), how to test it, and how to structure it to fail fast, close to the source of the problem, rather than in some arbitrary place. One very basic but useful thing that doesn't require complex infrastructure to implement is to check the inputs to all functions that have non-trivial precondtions with asserts. This has saved me several times in cases where I would have otherwise gotten weird segfaults and arbitrary behavior that would have been near impossible to debug.
If bugs weren't a problem then I'd be able to write a 100,000 line program in 10 minutes!
Your question is like, "As an amateur doctor, I worry about my patients' health: sometimes when I'm not careful enough, they sicken. Is patients' health a problem for you professional doctors too?"
Yes: it's the central problem, even the only problem (for any sufficiently all-inclusive definition of 'bug').
Bugs are common to everyone -- professional or not.
The larger and more distributed the project, the more careful one must be. One look at any open source bug database (ex: https://bugzilla.mozilla.org/ ) will confirm this for you.
The software industry has evolved various programming styles and standards, which when used right, make wrong code easier to spot or limited in its impact.
Therefore, training has a very positive on code quality... But at the end of the day, bugs still sneak through.
If you're just a hobbyist programmer, learning full bore TDD and OOP may involve more time than you're willing to put in. So, going on the assumption that you don't want to put in the time on them, a few easily digestible suggestions to cut down on bugs are:
Keep each function doing one thing. Be suspect of a function more than, say, 10 lines long. If you think you can break it into two functions, you probably should. Something that will help you control this is naming your functions according to exactly what they are doing. If you find that your names are long and unwieldy then you function is probably doing too many things.
Turn magic strings into constants. That is, instead of using:
people["mom"]
use instead
var mom = "mom";
people[mom]
Design your functions to either do something (command) or get something (query), but not both.
An extremely short and digestible take on OOP is here http://www.holub.com/publications/notes_and_slides/Everything.You.Know.is.Wrong.pdf. If you get this, you've got the gist of OOP and are quite frankly ahead of a lot of professional programmers.
The prevailing wisdom seems to be that the average programmer creates 12 bugs per 1000 lines of code - depends on who you ask for the exact number, but it's always per lines of code - so, the bigger the program, the more the bugs.
Subpar programmers tend to create way more bugs.
Newbies are often trapped by idiosyncrasies of the language, and lacking experience tends towards more bugs too. As you go on, you will get better, but never will you create bug-free code... well I still have bugs, even after 30 years, but that could be just me.
Nasty bugs happen to everyone from pros to hobbyists. Really good programmers get asked to track down really nasty bugs. It's part of the job. You'll know you've made it as a software developer when you stare at a nasty bug for two days and in frustration you shout, "Who wrote this crap!?!?" ... only to realize it was you. :-)
Part of the skill of a software developer is the ability to keep a large set of interrelated items straight in his/her head. It sounds like you're discovering what happens when your mental model of the system breaks down. With practice you will learn to design software that doesn't feel so brittle. There are tons of books, blogs, etc. out there on the subject of software design. And Stack Overflow of course for specific questions.
All that said, here's a couple of things you can do:
A good debugger is invaluable. Often you have to step through your code line by line to figure out what went wrong.
Use a garbage-collected language such as Python or Java if it makes sense for your project. GC will help you focus on making things work instead of getting bogged down by maddening memory errors.
If you write C++, learn to love RAII.
Write LOTS of code. Software is somewhat of an art form. Lots of practice will make you better at it.
Welcome to Stack Overflow!
What really changed my odds against code complexity and bugs was using a coding standart - how to place brackets an so on. It may seem like just boring and useless thing but it really unifies all the code and makes it much easier to read and maintain. So do you use a coding standart?
If you're not well organized, your codebase will become your very own Zebra Puzzle. Adding more code is like adding more people/animals/houses to your puzzle, and soon you have 150 various animals, people, houses and cigarette brands in your puzzle and you realize that it just took you a week to add 3 lines of code because everything is so inter-related that it takes forever to make sure the code still executes how you want it to.
The most popular organizational paradigm seems to be Object Oriented Programming, if you can break your logic down into small units which can be constructed and used independently of each other, then you will find bugs far less painful when they occur.

The "Should be easy for a junior developer to understand" argument [closed]

Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 10 years ago.
Improve this question
Does anyone actually think this is a good reason to "Dumb down" your code?
When a manager asks you to make your code simple (in terms of technology skills required to understand it) at the cost of more verbose cluttered code what should you do?
I highly disagree. Junior developers will end up being Senior developers. How? By encountering advanced topics that aren't taught in school.
My code base now makes heavy use of Inversion of Control containers. I would never revert my code to the old way because a junior developer had issues groking IoC. Instead I would take them out for a beer after work and discuss it. The more the junior dev learns the less hand holding needs to be done.
Here's a blog post discussing this very topic.
If you're constantly dumbing down your code or designs, it's a pretty good way to make sure your junior developers stay dumb. Challenge them and use it as a mentoring opportunity. Of course, some will never learn, but you've got bigger problems at that point.
It's not just pointy-haired bosses either. As a senior dev, it's often difficult to resist the urge to mommy junior developers. "Oh I'll just do this part because it's way too hard for them", or it'll take them too long, or they'll get way off in the weeds.
And finally, make sure you strike a balance between idiomatic code that uses the full power of a language vs idiomatic code that abuses that power. There's no reason you need to override the || operator just to run its args in two separate threads. At least dumb the code down a little for your older, dumber, future self.
Well, I think it's reasonable to avoid using "clever" language constructs unless they really, really make the code better - at which point if a junior developer sees it, hopefully they'd ask rather than just being flumoxed.
Here's an alternative way of phrasing it though: "Write your code so that it's easy enough to understand that if you get called at 3am and asked to fix a bug in it, you can still understand it."
Seriously, make it as easy to understand as possible. That doesn't mean a comment every other line - it means a comment where the purpose of a piece of code isn't obvious, and only then where the preferred choice of "well make it obvious then" doesn't work.
There's a difference between puzzle code and complex code.
I've found that the single biggest issue is that there is a big difference between "easy to understand by reading" versus "well-factored", and that the two goals are often in direct tension with one another. In well-factored code, there is a lot more jumping around between classes and a lot of virtual dispatch, so the path through the code is very non-linear.
Yes readability and being able to easily understand code is a big part of maintainability in my opinion.
Well if you intend to maintain your code forever, never change jobs, never feel the urge to work on something new, and can assure everyone you will never be hit by a truck, then sure there is no need to dumb down that puzzle code.
No. In the past, I've learned a lot from seeing the tricks of more experienced developers. I'd much rather have had the opportunity to learn something new from them than have had them dumb things down for me.
Its a balancing act...
If any 3 people on your team can 'read' your code and know what its doing... no need to change. However if you're the only person who can understand your code (no matter how rad/clever you think it is).. maybe you should take it down a few notches.
Another guideline to help would be to 'Try the simplest thing that works.' All the latest buzz words are nice to know however what it is even more important is having the skill to spot where you could get by without using them. You don't need to spray paint your code with IOC or Frameworks or Design Patterns...
The manager's side of this argument is sorely missed in this thread :) (and for the record.. I'm not one). His/Her major concern being he doesn't want a dark area of code that no one else dares to venture into.. so if you can convince your boss that a few other people on the team can make an arbitrary fix (or better yet.. show an actual bug fixed by someone else) - the mgr should let you off the hook. Disagreeing with your boss is another art :).. but you can talk things out usually.
You dont have to go all the way backward to Lowest Common Denominator.. strike a balance.
Your goal should not be for your code to be easy to understand for a junior developer. Instead, it should be easy to understand for a maintainence programmer.
This means:
Local "complexity" is okay, when needed. If they see the complex code they'll know they need to dig deeper.
Hidden complexity is bad. If you can't see that changing a piece of code will have subtle side effects then maintaining the code will be a nightmare.
New technologies that are visible are also okay, when not taken to extremes.
This is because those that maintain code rarely have the same overall understanding of the system. Or the time to develop it.
I disagree with the manager: What needs to be simple is the code, not the technology used to write it.
I would, however, impose a closely related requirement:
The internal documentation states clearly what technologies are needed to understand this code, and it gives references to places where those technologies can be learned.
For example, even as a senior developer, I find all matrix codes baffling. But if somebody gives me a reference to the right part of Numerical Recipes, I can puzzle out the details.
Yes. It's a very valid reason to take it down a notch. The reality is that a very, very large number of developers (as in most) are at the junior level.
As far as what you should do... Say "Yes Sir" or "Yes Ma'am" and do it. There is only one boss in that relationship.
UPDATE:
As some people seem to think that having a jr dev learning advanced topics while wading through obfuscated code I want to throw one more thing in here.
When ANY developer (jr or otherwise) runs into code they don’t understand, their first approach is to refactor it into something that is understandable. This is called the “Wow that code is crap I must rewrite it!” syndrome. I’m willing to bet everyone on this board has experienced it. So, as a business owner, do I want to pay for code to be developed each time a new person comes by or do I want to pay for new features to be added?
Guess which person I’m going to keep around longer.
If you dumb down your code, you're going to be stuck working with dummy junior programmers who will never be familiar with advanced coding techniques. If there's any verbose code that's trying to express an inherently complex procedure that you wrote, the aforementioned junior developer probably wouldn't be able to see the forest for the trees anyways. And they'd probably screw up if they had to express a complex concept if all they knew were basic primitive constructs whereas if they knew how to express what they meant tersely and elegantly, the code has a better chance of being correct.
Scott Muc said:
"I've found that the single biggest issue is that there is a big difference between "easy to understand by reading" versus "well-factored", and that the two goals are often in direct tension with one another. In well-factored code, there is a lot more jumping around between classes and a lot of virtual dispatch, so the path through the code is very non-linear."
Quoted for truth, and I think this is one of the biggest problems with C++ code in general. If you're the one that wrote the code, it's pretty easy to come up with a very complicated set of stuff that is well factored, makes lots of sense if you already know it, works well, and generally resembles a diamond crystal, etc. but which, from the perspective of someone who's trying to figure out how you got there and why things are the way they are and how things work, and how one might make changes that fit into the existing system and satisfy new requirements, is almost completely opaque and impenetrable.
How does this kind of situation help maintainability? That situation is one of my main beefs with C++ programmers. Far better to have a mess of plain C code which can be hacked upon than a diamond crystal of inpenetrably super-factored code which nearly nobody can figure out how to sensibly modify without smashing the crystalline structure.
One way to "dumb down" code that I actually think is an excellent practice is to use longer variable names and longer function names. Naming variables and functions to make their purpose easily understandable is a significant engineering task, IMHO, and takes extra effort on the part of the original author of the code. Damian Conway has some excellent examples in "Perl Best Practices". Some examples include: Prefer "final_total" to "sum"; prefer "previous_appointment" to "previous_elem", prefer "next_client" to "next_elem". Prefer "sales_records" to "data". Etc. He also pushes for using grammatical templates (Noun-adjective) and staying consistent. Don't use max_displacement one place and then use VelocityMax in another. Index variables need real names too:
sales_record[i] vs sales_record[cancelled_transaction_number]
I frequently "refactor" my code at the end of a development cycle by finding new names for all my functions and variables. In a modern editor it's trivial to change them all, and it's only at the end that I really figure out what I used them for. "Dumbing down" code this way isn't classic C, but it's easier for me when I come back months later asking WTF did I do?
It depends on the code. Is this something being shipped in your flagship product that requires use of the features your manager wants you to remove for performance reasons? If the answer is yes I would try to have your manager let you keep the code and just write up a document explaining in detail the section of code that is hard to understand. If it's an internal app that needs to be maintained by lots of different people and the complex features can be removed with out negatively affecting the program remove them and pick more important battles to fight.
You should just remind your boss that you can build rocket ships or chicken coops, and he will have to pay you the same for either one. Do what they say but generally an environment like that lends itself to people looking for a new environment.
The old quote is appropriate here:
Make everything as simple as possible,
but not simpler.
I've known developers who wrote highly obfuscated code that they felt was advanced but which the rest of the team felt was unreadable and unmaintainable. Part of this involved overuse of advanced language features (in C, the ternary operator and the comma operator) and writing in an obscure personal idiom (for example, replacing ptr->item with (*ptr).item everywhere) that no-one else would ever be able to maintain. The author was trying to outsmart the optimizer (which to be fair, was far from good).
Note: I'm not suggesting that "x = (p == NULL) ? "default" : p->value;" is complicated, but when someone uses ternary operators that span many lines, are nested, and make heavy use of the comma operator, code quickly becomes unreadable.
In this sort of case, "dumbing down" the code would have been a good idea. The problem was not advanced algorithms nor advanced language features, but overuse and inappropriate use of advanced language features, and an obscure personal idiom.
However, in the case you are asking about, where the manager's changes make the code more difficult to read and maintain, I agree with you and the others who have responded. I just wanted to point out the alternative that no-one else has mentioned.
I suggest keeping the code in a "Geeky-level" and comment it well so that the juniors can understand the intention behind the code and simultaneously learn a better way (or a right way) to code, so we have the best of both he worlds.
I think it is the manager's way of politely telling you that your code is too obfuscated/complex/jumbled/puzzle code...whatever you want to call it. Sometimes we get so involved writing our codes that we forget that someone else will have to come along and read it later.
I learned it the hard way and, in retrospect, find that it was the better way. Let the cycle repeat itself.
I agree 100% with the argument. With one major addition: Train your junior developers until they understand your code ;-)
I'm talking about using "unusual" technologies. In this case it's JQuery.
This issue came up when I was writing a wizard control for user registration.
The navigation menu needed to be customised and the current step in the wizard had to have a different css class in the menu. This meant I needed to get access to the currently selected step when generating the menu. My solution was to output the current step index in a hidden html field which could then be read by JQuery in order to customise the css.
I thought that this was much nicer and cleaner than using the databinding syntax in ASP.NET which doesn't have compile-time checking and messes up the layout of the html.
The databinding solutions is "standard" while the JQuery one is "unusual" which means that it's less likely to be understood by a junior.
I'm trying more and more these days to provide the required data for the UI rather than hack it into the UI with databinding which is why I added the hidden field with the current step index.
It is simply impossible to make progress or to innovate in any industry without doing things that others don't understand. Innovation is necessarily blasphemous. Why? Because if you're doing things that make sense to everyone else around you, the odds are you're not the first one doing it. ;)
That being said, there is a significant difference between doing something that is difficult to understand simply because it's a new or complicated problem versus doing something that's difficult to understand because you're trying to show off or you think confusing people will somehow gain you job security (which I've never seen work, but I've heard of people trying).
Should you make things easy to understand? Yes absolutely, as much as humanly possible. However a program that works and does its job well is the higher priority.
The manager's complaint should never be "don't do this because our junior guys don't understand it" -- it should only ever be "do x instead of y whenever feasible because x is easier to read / understand". This also assumes that x and y are equivalent (accept the same input and produce the same result).
I can't stand when managers do that... I've had three different managers bawl me out for using perfectly normal code the way it was designed to work, not because I was doing anything complicated, but rather only because they felt like it was too much effort for the other guys on our team to go RTFM on the language we were using. As a management strategy, that's totally backwards. It's like being the Holy Roman Catholic church and insisting that the laymen are too dumb to be trusted with literacy.
If you want to know really how ridiculous some of these managers get, try this: I had one manager bawl me out for declaring a variable as a type of "boolean" because he didn't feel the other programmers could handle it. Actually when I asked why, his answer was "because we don't do that here", which is a non-answer, but I interpreted it to mean "dumb it down". They were also berating me for that and similar practices as though it should be obvious that good programming habits were actually "bad" and that I should already know why even though they had never expressed a preferred programming style (either formally or informally). Needless to say, it was a bad job.
Make sure you can understand what it does 6 months down the road.
When in doubt, COMMENT your code. That's what comments are for.

When is the right time and the wrong time to do the quick and dirty solution? [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
When is it the right time and when is it the wrong time to take the quick and dirty approach versus the proper elegant solution?
This started from the comments on my question: Decode Base64 data in Java.
I wanted a way to do something using only internal Java or something I wrote. The only built in way is to use the sun.* package which is unsupported. So when is it the right time and when is it the wrong time to take that approach?
In my opinion the only "right time" to use a quick and dirty solution (aka hack) is when...
There is a mission-critical bug that needs immediate fixing and the proper solution is significantly complicated to implement.
It's an internal application and some higher ups need a quick feature implemented (hey, neither you nor your customers use it).
In any situation, you have to balance the time that will be spent on solving the problem, and then the time that will be spent in maintaining that solution. If the lifetime of whatever you do is expected to be lengthy, then the extra time spent up front to do things the right way will, presumably, be easier to maintain and will save you in the long run.
However, if there are time constraints, the penalties for going over may far outweigh the maintenance cost. For example, if you MUST get a product out the door, do a quick-and-dirty solution now, and then log it as a bug to get fixed later in a patch, or the next version. That will require you to re-do the work, but like I said, it is all a balancing act, and often driven by cost at it's root.
The right answer is that its never time to do the quick and dirty solution.
But sometimes (when having a big customerbase and lots of programs out there) its better to ship a fix with a Q&D that maybe breaks something, but FOR SURE fix more.
I dont know if I understand the question right but Ill leave it with this.
If there exists a simple but less elegant solution that closely matches the style and techniques used elsewhere in the code base (and consequently, is more easily understood by your colleagues), it may be safer to take that path -- compared to the solution that is perfect from an academic point of view, but difficult to understand if you never happened to read that specific paper.
Similarly, a small change may be considerably safer than a major refactoring effort that the elegant solution would basically require. This is especially relevant in any world that lacks unit tests.
If the project is a "proof of concept" work rather than a production implementation, it may be the right time for a quick and dirty solution that gets the job done of illustrating how easy or hard some particular part is of a system. I'm thinking of where one may want to test out a new ERP or CRM system and just want to see the mechanics of it without spending a ton of time and money to get a more realistic prototype working.
In most other cases, it is a question of trade offs. How many defects can something have that gets released into the wild? Are just no showstoppers bugs OK or does there have to be few only a few minor or cosmetic bugs left. If some project managers or business units want something quick but not necessarily fully working then it the quick and dirty solution may work if those asking understand the risks. In a way this is like the question of how many tests should a doctor give before making a diagnosis: Should you be examined head to toe through a variety of different waves of energy, e.g. X-ray, CT scan, MRI, etc. Or can the doctor just look at what you are doing and know what is wrong like Dr. House does from time to time.
It seems to me that quick and dirty solution is more often necessitated by a lack of planning somewhere moreso than it is because of a sudden change of business rules (not to say that doesn't happen though!). Either someone wasn't given appropriate tools to do their job, someone vastly underestimated the amount of time something will take, or someone got too attached to a feature that is overly complicated. In most of those cases, it's best to push back your release or scale back the features in the release.
In the case that it was necessitated by a business priority that you have no control over (like a legal issue), then you need to get it out the door as quickly as possible. But you should make the fix better for the next release!
It's the right time to use a quick and dirty solution when:
You need the solution to be quick (assuming no professional solution exists that is approximately as quick), and
You don't suffer consequences for it being dirty.
In some ways, that's a flippant answer, but it does cover it.
In your situation, you can't introduce a new library quickly. And you do have a process to mitigate the risk of using experimental code. As long as that process is reliable, and you are confident that production code won't include your quick & dirty solution, then go ahead.
Once my company was struggling to get some code working for a demo at a trade show. They were running out of time, the demo just one day away. I suggested they hard-code some options instead of making them configurable and dynamic.
It worked -- they got the demo running for the next day's show. Then when they got back to the office, they immediately removed the hard-coded part and finished their feature.
If you can rely on replacing the quick & dirty hack being top priority, then quick & dirty can be appropriate. It's just so seldom the case that it's top priority, that using this solution is usually a bad idea.
As noted by tj111 and others, there are times when the risk of an elegant solution are greater than that of the quick and dirty. I.e., you deliver something beautiful, but by that time the customers no longer want it, want something different, or are pissed off.
To be sure though, there is always a long-term cost with doing a quick and dirty solution and it is important to deliver a firm and forceful "by the way" caveat to management. Else the quick and dirty becomes like crack to management who often do not know or care of the difference between the elegant and dirty (especially when it is under the hood). That is until things start to go to hell, and even then the fixitnow stress is offloaded to the hapless (often new) technical team.
So yeah, sometimes you have to do it because of $$ and time considerations, but don't cloak it or forget it and strive and push to re-factor soon when the crisis wanes.
Remember a lot Application get built off of their prototypes.
We always want to think its throw away code. But it will grow!
In my case I work in a research and development position where we have a long process for getting approval when adding external libraries.
If code is marked as experimental it will be cleaned up before moving to production. I needed this for a quick experiment to see if something was even going to make sense for us to work on and needed to get the data processing quickly. So the quick and dirty approach was the right one to get things done asap. If we decide to work on the experiment I will have time to replace the functionality properly.
In the standard case where as kdgregory put it in the comments of one answer:
Bzzt. In a professional environment,
using an unsupported, undocumented
feature is never the correct decision.
And in a corporate environment,
"experiments" become "production code"
with no chance to fix the hacks.
I think he is correct that it is not the appropriate approach when you work in a position where you have even a doubt that it may go into production. The only exception with this is if you absolutely do not have the time for a proper fix but can mark it as being a high priority issue in some visible public place (bug tracker) and will definitely be able to fix it in a future release.
Sometimes a quick and dirty solution is synonymous with an unmaintainable solution. Other times it just means solving the (simple) problem you actually have, not the (more complex) generalization of that problem. I'm a grad student doing research in bioinformatics and I often need to write small programs that do simple things like reformat or summarize a few hundred megs of data. Occasionally I need to write several of these apps per day. If I wrote "proper" solutions to these I'd never get anything done.
Solving the general case (not quick and dirty) would mean making an app that handled errors robustly, was usable by people other than me, was configurable, etc. This would solve lots of problems that I don't have. I'm probably the only one that will ever use these programs. All the configurability I need is a few command line options and the ability to edit the source file as needed. All the error handling I need is displaying a decent error message and exiting if there's a problem.
Of course, sometimes these programs do grow into something more important and sometimes I do end up reusing code from them. Maintainability counts. Even in a quick and dirty solution, magic numbers should not be hard coded, variables should not be named "foo", "bar", and "stuff", and programs should not be written as one giant 400-line main() function. I learned these the hard way.
Sometimes you have to do things in Q&D way. What you need to do in that circumstance is to protect yourself by hiding the dirty implementation behind an interface or an adapter.
To use the cited example, the Sun.* package works for now, but may not sometime in the future. Fine. Then wrap it in an adapter that implements the desired interface. Then, when Sun changes the API (hopefully providing something permanent like Java.BASE64), you can quickly update your implementation to cope with the change.
I do a quick and dirty fix when three conditions are met:
There isn't enough time to do a proper solution
The fix and it's scope are clear and contained (it's easy to come back, know what the fix addressed, can be easily removed and replaced by a proper implementation)
The fix is atomic or has no dependencies
"Quick and Dirty", is often synonymous with "cheap yet actually works", which is generally all you need to get the job done. If anybody criticizes your code, pretty much the best defence is to say "yeah- it was just a quick and dirty solution". That way your coder colleagues can feel superior to you, whilst you pointy haired boss looks on, rubbing his chin in silent approval.

How do you justify Refactoring work to your penny-pinching boss? [closed]

As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 10 years ago.
You've just written a pile of code to deliver some important feature under pressure. You've cut a few corners, you've mashed some code into some over-bloated classes with names like SerialIndirectionShutoffManager..
You tell your boss you're going to need a week to clean this stuff up.
"Clean what up?"
"My code - its a pigsty!"
"You mean there's some more bug fixing?"
"Not really, its more like.."
"You're gonna make it run faster?"
"Perhaps, buts thats not.."
"Then you should have written it properly when you had the chance. Now I'm glad you're here, yeah, I'm gonna have to go ahead and ask you to come in this weekend.. "
I've read Matin Fowler's book, but I'm not sure I agree with his advice on this matter:
Encourage regular code reviews, so refactoring work is encouraged as a natural part of the development process.
Just don't tell, you're the developer and its part of your duty.
Both these methods squirm out of the need to communicate with your manager.
What do you tell your boss?
It's important to include refactoring time in your original estimates. Going to your boss after you've delivered the product and then telling him that you're not actually done is lying about being done. You didn't actually make the deliverable deadline. It's like a surgeon doing surgery and then not making sure he put everything back the way it was supposed to be.
It is important to include all the parts of development (e.g. refactoring, usability research, testing, QA, revisions) in your original schedules. Ultimately this isn't so much a management problem as a programmer problem.
If, however, you've inherited a mess then you will have to explain to the boss that the last set of programmers in a rush to get the project out the door cut corners and that it's been limping along. You can band-aid the problem for awhile (as they likely did), but each band-aid just delays the problem and ultimately makes the problem that much more expensive to fix.
Be honest with your boss and understand that a project isn't done until it's done.
Speak in a language he can understand.
Refactoring is paying design debt.
Ask your boss why he pays the company credit card bill every month vs not paying it until there is a collections notice. Tell him refactoring is like making your monthly payment.
Just do it and schedule it into your normal process. Estimate refactoring time into starting a new change or into finishing a change (ideal).
I always refactor while I'm initially exploring new code (extracting methods, etc).
Lie. Tell him it's research into a new technology. Then tell him you decided the cost didn't justify the benefits. He'll think you did a great job.
lol # people down modding / marking offensive.
Really, if it's a penny pinching boss, who doesn't understand good software from cheap software, what he doesn't know will ultimately make him happier. if it was me, i would leave the company and go someplace where they respect their developers ability to write good code. But then again, this is why I'm in a senior position.
Tell him 80% of the costs associated with a software project comes in the maintenance phase of the lifecycle. Any refactoring done now to alleviate future problems, and have some examples, will net substantial cost benefits later on when the need arises to maintaining that code.
This is assuming you are refactoring for a reason and not for programmer vanity.
Refactoring you should do all the time.... so you shouldn't have to justify it.
Cleaning up big messes / Redesign may include refactoring in order to get it under control, however its not "Refactoring"
Refactoring should be a matter of moments...or if you have no tool support, minutes.
In one of Robert Glass's recent books (I'll have to look up the reference) he mentioned a study on the cost of well maintained code. What they found is that well maintained code was edited more often than poorly maintained code. That sounds counter intuitive but when they dug deeper the discovered the reason:
Well maintained code has more features added to it in the same time frame than poorly maintained code.
Does your Boss like features? Sure, they all do. If more you improve the maintainability of the code, the more features you will be able to deliver with that limited budget.
I like the answer given in "Refactoring" by Martin Fowler. Tell your boss that you are going to develop software the fastest way that you know how. It happens that in most cases the fastest way to develop software is to refactor as you go.
The other thing to tell your boss is you are reducing the cost to make future improvements.
Less money now for me to refactor...
or more money later to fix whatever goes wrong and for me to refactor.
Sometimes, it's just time to get a new job. There are certian poeple who just want you to "get it done". If you are ever in one of those situations, and I've been there, then just leave.
But yeah, all that other stuff about future costs and such is good idea. I just think that most bosses lie to themselves because they want what they want when they want it, and they are just not able to see what's going to happen in the future.
So, good luck with your boss. Hpefully he or she is reasonable.
Dont.... just go get a new job in a place thats more in synch with you.
I think you should just start working on it without telling your boss. This is truly how I've done my best work. I just don't tell my boss what I'm doing and slowly replace bad/legacy code when I have time.
It has acutally saved my ass on more than one occasion.
If your boss doesn't understand the need to refactor or clean up code, then you have to wonder if he has enough engineering knowledge to be an engineering manager.
It's rare to find a boss who will give you time to refactor...just do it as you go along.
In my opinion, the simplest case to make for refactoring is fixing overly complex code. Measure the McCabe cyclomatic complexity of the source code in question (Source Monitor is an excellent tool for such a problem). Source code with high cyclomatic complexity has a strong correlation defects and bad fixes. What this means in simple terms is that complex code is harder to fix and more likely to have bad fixes. What this means to a manager is that the quality of the product will likely be worse, and the bugs harder to fix, and the schedule for the project ultimately worse. However, in refactoring out the complexity, you are improving the transparency of the code, reducing the likelihood of obscure / difficult bugs, and making it easier to maintain (e.g. a maintenance programmer can have a larger maintenance scope because of this).
Additionally, you can make the case (if it isn't a dead product in maintenance cycle) that decreasing complexity makes the application easier to extend when new requirements are added to the project.
The boss has to trust the dev to make correct technical decisions (including when to refactor).
Establish that trust or replace the boss or replace the dev.
Another good analogy is the maintenance of a tidy building site. The only catch here is that a programmer does not represent a construction worker, and a manager does not represent a foreman. If that were the case, his counter of "do it right first time" would still apply, since a competent and conscientious construction worker is responsible for maintaining good order on their workspace as they go.
Really the code itself represents the labourers, and the development process is the foreman. The mess is generated by various trades going about their business around one another (i.e. by different code features interacting, where each feature does its job well, but the seams between them are disorganised) and is cleaned up by the foreman taking a firm hand and keeping an eye on where disorder is setting in, and acting to get it cleaned up (i.e. the software process demanding refactoring).
What I just did recently is to explain to my business counterpart that the re-factory process helps to develop new features faster and decrease the probability of new bugs because the code has a better order and structure, and is even posible to make some speeds improvements because you can inspect the code easier than before.
When the business guys get that, if they are smart, they will encourage you to do a constant re-factory process.
You can explain that with a building metaphor. If you don't do refactory you will end with a crappy building with a bad core so you will have problems with the pipes, windows, doors.

Resources