How do I know if I am overanalysing?
I've been chasing a problem the last 3 days. I've been through many designs and reached a complex solution using about 3 classes. Having discussed with a colleague, I realized that all I need is one method and a struct. How can I avoid being an architecture astronaut?
I find that if I can't come up with a good clean solution in 30 minutes, it's almost always best to discuss it with someone else.
Even if they have no idea how to resolve it, it often triggers a better design or solution.
So talk to someone about it.
Personally, I can't really complain about anyone who actually PLANS their software first! I do this, but I know LOTS of programmers who only know how to just jump right into the code... and I often have to fix such code...
That said, what your really asking is how to know when there is a better solution to the problem.
The advice I have for you is to ask yourself repeatedly: Am I thinking about the details of my solution, or about the real problem?
The best way to avoid become an architecture astronaut is to get into the habit of jumping right in. The best way to jump right in is to write a few tests that will pass when your implementation is complete and correct. That forces to you confront what "done" means from the outset, and it provides a sanity check on the code that will follow.
Then head for a solution.
You might now get there the first time, but the exercise of starting with an idea of what "done" means firmly in mind will help you to ask better questions as you go, and having some acceptance tests done ahead of time will help cull the design space down to something reasonable.
I used to suffer from this problem. Designing a solution which could handle a lot of growth in the future and what not. Ensured it had good abstraction resulting in the type of concern you had above.
I then dumped this approach and whacked it all into one big dirty class maybe two. After that I re factored it until it resembled something I'd want someone else to work on.
I like doing something quick & dirty first, and when it works, I refactor the code step by step until I'm satisfied with the design.
This is also the TDD approach.
I find myself following these three steps to find an 'ideal' solution:
If I had all the time and resources in the world, what would be the best solution in any way. (Technologically, Logically, Performance-wise, optionally solving a few related issues, re-writing modules you find could do better...) Do your (over-)analysis here, just to get to know about as mush as possible. Run tests, statistics and create proof-of-concept's.
How is it different from the current situation. What is the difference between the results of the two solutions. Is there a faster way to get to the same or similar result. Why would this or that change solve the problem at hand. Do some more tests, statistics, update your proofs-of-concept.
Find a way to implement the required changes, and only the required changes, drop anything not essential to this change. Check you're not modifying anything that was not having the problem. Test this, review changes to code, logic, structure; and minimize them if at all possible.
This sounds very restrictive (and a lot of work), but in fact I find myself I end up adding an entire table to the database in some cases. Part of the work (because it's a lot of work to get 100% sure of something) is checking all existing code keeps working exactly the same with this extra table to join in.
To top that, in most cases here at work we need to cater for 'transitional data' that remains in the system from before the update, that will have to get produced and shipped all the same after the update.
Related
So DRYing up code is supposed to be good thing right? There was a situation in one of the projects I was working on where there were certain models/entities that were more-or-less the same except the context in which they were being used. That is, Every such entity had a title, descriptions, tags, a user_id etc and some other attributes. Hence their CRUD actions in their respective controller looked pretty similar.
My manager argued that its repetition of code and needs to be DRYed up. Hence he came up with CRUD ruby module that when included took care of CRUD actions for the controllers of all these entities. But eventually, Simplicity was compromised. The code lost readability as every "thing" was named "object". Debugging became difficult and the whole point of DRYing up the code was lost.
This was just one case. There are several of them where DRYing up resulted in complex, hard-to-debug code. So the question is, when do we stop DRYing up the code? Because not every time you realize the code has lost simplicity (And often the code author never realizes the simplicity of code is lost). Also, if we have to choose between simplicity and DRYed code, what should choose, if at all there comes a situation where you could get only either of them.
From what I understand, if DRYing up code is causing loss of simplicity, we are doing something terribly wrong. I think, we should be DRYing up code that is repeated and has single responsibility. If the code responsibilities are different and/or the abstraction of entities cannot be named, we are not repeating code. The code pattern might be repeated but its a different code altogether with a responsibilty of its own. If DRYing is resulting into vague code, you are probably trying to DRY up code with different responsibilities that have a similar pattern which is not really a good practice. DRYing should enhance the simplicity, not suppress it.
If you are following REST, then yes, the controllers will be very similar and largely boilerplate. I agree with your manager that it's a problem.
It sounds though like he came up with a suboptimal solution. For a better one, check out Jose Valim's inherited_resources plugin that is being incorporated into Rails 3.
Readability and Maintainability are the two most important features of good code. Unfortunately, a compromise has to be made sometimes. It's a balance question and not everyone is going to agree.
Myself, I lean towards your point of view as well. I would rather have some apparent repetition if it means the code is easier to understand.
As for the 'debugging' problem, I am in the habit when I create such a 'base class' to include a supplementary field. This field is a simple string which identify the most derived class (and is thus passed from Constructor to Constructor). Then each message is going to print this field + the object id "realtype[id]" and everything is suddenly much easier to debug.
Now on to DRY.
There are two things to DRY:
building a hierarchy
using generic code
The first point should now be well understood. A hierarchy of class means a IS-A relationship. If two classes have similar behavior but are otherwise functionally unrelated, then they SHOULD NOT be part of the same hierarchy. It only confuses the poor maintainer and hurts readability.
The second point can be used much more often, especially with scripting languages. For the precedent example, I would argue that instead of having a hierarchy of classes, you could simply define generic methods that would take different classes (modeling different business) and treat them uniformly. This way you avoid repetition (DRY) yet you do not sacrifice readability (imho).
My 2 cts.
If someone every told me--with a straight face--that my code needed DRYing, I would probably take that as a sign that anything else they were going to do was going to be really far-fetched and for-the-sake-of-it.
That having been said, there is also a difference between simplicity in writing code (laziness) and simplicity in the code itself (elegance). I agree, though, that there is a balance. I had this situation myself one particular time (in PHP, but oh how it reminds me of your dilemma):
$checked = ($somevariable) ? "checked=\"checked\"" :"";
echo "<input type="radio" $disabled_checked />";
$checked = ($someothervariable) ? "checked=\"checked\"" :"";
echo "<input type="radio" $checked />";
This isn't even a very good example of what I was dealing with. Essentially, because it's a radio input, both inputs needed a some way of knowing which was to be bubbled in. I knew it had what your boss might call "wetness" issues, so I racked my head trying to come up with some solution that would be graceful and to the point. Finally I showed it to a senior developer and he said "No, it's all in order, it does what it needs to. It's only one extra line."
I felt a relief at being reminded that I was hurting my project more then helping by worrying over this, but at the same time, I'm still disappointed that he was so casual about a fundamental principle (as though it wasn't one of his, though I'm sure it is).
So while I agree, your manager probably was doing something just for the sake of doing it, it is only when we strive to come up with the better methods and approaches that we get better languages like Ruby and Python and cooler libraries like Jquery.
Basically, what if next week you suddenly had 70 things instead of 2? If your boss's objects make that a snap, he was right. If it's the same amount of trouble (in the code or in the execution), he was wrong. But that doesn't mean there isn't a better answer then keeping it simple because it's only a couple of things.
The aim of the DRY principle is to help increase the "quality" of the code.
If the changes aren't improving the quality of the code, it is time to stop.
The ability to judge this comes with experience. As requirements change, the most appropriate way to refactor the code also changes, so it's impossible to have everything ideal - at least you need to freeze the requirements first.
Minimising the size of the code should generally not be a consideration in the quality unless you are codegolfing, so don't DRY when the only purpose is to reduce the size of the code.
Complicated tricks can do more harm than good.
A key reason for applying DRY to improve maintainability is to ensure that when a code change is necessary, that change only needs to be made in one place, thus avoiding the risk that it doesn't get changed everywhere that needs it.
But I'm not telling the whole story:
This interview with Dave Thomas has DT saying:
DRY says that every piece of system
knowledge should have one
authoritative, unambiguous
representation.
The first time I saw "DRY" was in The Pragmatic Programmer so I'm inclined to go with Dave on this.
There's another article worth reading here
But DRY is a principle, not a rule: the better we understand the principle, the more able we should be to recognise situations where it should be applied.
(And finally, I think I'd want a little more than "more-or-less the same" before I started "DRY"ing that code: if I could see a clear way in which the two things might diverge in the future then I'd be inclined to leave them alone).
For me, duplicated code is a smell that can have multiple origins:
Missing variables (introduce variable).
Missing methods (push expression into a method).
Feature envy (push behaviour down into the envied class).
Over-generalization (break up generic class into specific concrete classes).
Insufficient abstraction (push attributes and behaviour down into new class).
This list is probably incomplete. Consider it a starting point.
When you find duplication, think about what problem it's symptomatic of. Then take a stab at addressing that problem. When you're done, consider the readability of the new code. If it has deteriorated, you may be in one of these positions:
You misidentified the problem at the root of the duplication (revert, rethink, try again).
The duplication is a necessary trade-off (revert your change and live with it).
Your software is necessarily complex (commit your change and live with it).
Consider posting example code along with questions like this, if possible. They provide something concrete to work around. And remember, a lot of this stuff is very subjective.
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 8 years ago.
Improve this question
I have joined a rails project as a contractor. The project has been going for more than a year. The code is written by about 10 different developers and most of them are contractors as well. They have different code style. Some of them came from Java. The code has horrible scores with metric_fu. Many functions are very long (100 - 300 lines). Some functions have insane amount of logical branches, loops, and recursions. Each request generates a ton of sql queries. Performance is very bad. Many obsolete code that are never used but never got the chance to be cleaned up. The core architecture is plain wrong or over engineered. Code coverage is only about 25%. Views and partials are chaotic and terrible to read and understand.
The manager is in a position trying to satisfy the CEO by continuously adding new features, however newer features are increasingly hard to get implemented correctly without breaking something else. He knows the code is bad, but doesn't want to put too much effort in fixing them as refactoring will take too long.
As a contractor / developer, what is a good way to clear this situation and convenience the Manager or CEO to partition some time for refactoring?
Related Questions
How can I convince skeptical management and colleagues to allow refactoring of awful code?
How to refactor on a budget
Dealing with illogical managers
In my limited experiance:
It's impossible to convince a manager that it's necessary to set aside time to refactor. You can make him aware of it, and reinforce the point every time that you run into an issue because of bad code. Then just move on. Hopefully your boss will figure it out.
It's quite common to get in on a running project and think "this is total junk". Give it some time. You might begin to see a pattern in the madness.
I've been in similar situation. There are basically only two options:
You get some relaxed time and you may be granted time to refactor something
Due to the bad code further development of some component comes to a stall. You can't proceed to add anything because every little change causes everything else to stop functioning. In this emergency case you will get a "go" with refactoring.
I have just answered in some other question, my horror story:
https://stackoverflow.com/questions/1333077/dirty-coding-tricks-to-deliver-project-on-time/1333095#1333095
I have worked on a project where dirty tricks were the main driving principle of the development. Needlees to say, after some time these tricks have started to conflict with each other. In one analytics component, we had to implement the other very dirty trick - to hide away those calculated values which due to the conflicting tricks were not calculated properly. Afterward, the second level tricks started to conflict and we had to create tricks to deal with those. Ever since, even the mentioning of this component makes me feel horror that I may have to work on it again.
It's exactly the second situation where refactoring is the only way out.
In general, many managers without a technical background (actually, those who come from bad programmers as well) neither care nor understand the value of quality code and good architecture. You can't make them listen until something interrupts their plans, like a blow of "non-implementable" features, increasing and reoccurring bugs, customer requests that cannot be satisfied and so on. Only then understanding of the code problems may come for the first time. Usually, it's too late by then.
Refactoring code that sucks is part of coding, so you don't need to get anybody's approval unless your manager is watching your code and or hours VERY closely. The time I save refactoring today is time that I don't have to bill doing mad tricks to get normal code to work tomorrow (so it works out, in the end).
Busting up methods into smaller methods and deleting methods that are not used is part of your job. Reducing DB calls, in code that you call, is also necessary so that your code doesn't suck. Again, not really refactoring, just normal coding.
Convincing your manager depends on other factors, including (but not limited to) their willingness to be convinced, and your ability to convince.
Anyway, what is massive refactoring in RoR? Even if the "core architecture is just plain wrong," it can usually be straightened out a bit at a time. Make sure you break it into chunks /use branches so you don't break anything while you're busy fixing.
If this is impossible, then you come back to the social question of how to convince your manager. That's a simple question of figuring out what his/her buttons are, and pushing them without getting fired nor arrested. Shaming, withholding food, giving prizes, being a friend, anonymous kidnapping threats where you step in and save the day... It's pretty simple, really: creativity is the key!
Everyone is missing a point here:
Refactoring is part of the software development life cycle.
this is not only a RoR or any specific project but any other software development project.
If somehow you could convince your PM why it is important to refactor the existing code base before adding any new feature, you're done. You should clearly tell your PM that any further addition of new feature without any refactoring will take more time than required. And even if the feature is added, somehow, bug resolving sessions will take even more time since the code is very bloat and unmaintainable.
I really don't understand why people forget the principle of optimise later. Optimising later also includes refactor later IMHO.
One more thing, when taking design decisions, you should tell the consequences, good or bad, to your PM very very clearly.
You can create a different branch(I assume you are using git) for refactoring and start adding new feature in some other branch if your PM insist on adding new feature along with refactoring.
A tricky one, i have recently worked in such a company... they were always pushing for new things, again they knew it was bad, but no matter how hard I pushed it - i even got external consultants in to verify my findings - they seen it as a waste of time.
Eventually they seen the light... it only took multiple server crashes and at one point almost a full 8 days of no website to convince them.
Even at that they insisted it 'must' be the hosting service.
The key is to try and quantify how long their site will last before it crunches, and get some external verification to back you up - 'they' always trust outsiders who know nothing about your app! Also, try - if you can - to give a plan that involves gradual replacement at worst, and a plan for how long it would take to do that way. Also a plan for if 1 or 2 bodies were working on a complete rewrite hwo long it might take - but be realistic too or it will bit you in the bum! If you go that route (which is what we done) you can still have some work on the existing site as long as you incorporate it into the new.
I would suggest that you put focus on things that they can see for themselves, that is, they will surely notice that the application is slow in some functionalities, so pick up one of them and say something like "I can reduce the waiting time here, can I take some time to improve this specific thing?" (more well said, but you got the point :P).
Also consider that 10 developers before you did not refactor the code base, this may mean that it is a monstruos task, likely to make the situation worse, in this situation if something will go wrong after the refactoring it will be your fault if the program does not work properly anymore.
Just a though, but worth considering.
I'd take one small chunk of application and refactored and optimized it 'till it shines (and I'd do it in my personal time in order not to annoy my manager). Then you'll be able to show your manager/CEO the good results of refactoring and SQL optimizations.
If there is a need to refactor then the code will speak for itself. Minor refactoring can continue in during development. If you cant convince the manager then probably you should rethink if its necessary at all.
However if it is absolutely necessary then constructing metrics of development activities and the benefits should convince the manager.
I think one of options would be to highlight to the manager how re-factoring the code base now will save time (i.e. money) in the long-run. If the project is expecting to be running long term then making the changes now will clearly save you and other developers time in the future.
Best to use an example of a feature you've worked on estimating how long it would have taken if you had the cleaner code to work from in the first place. Good luck!
I am in same position right now, but with an agreement with the manager that, when the new feature should be implemented in some existing module to re-factor the module too (if it needs re-factoring), we are struggling now with the code created 4-5 years ago and definitely I find out that the re-factoring someone else s code is not trivial nor amusing to do, but very very helpful for the future re-use.
There are some tasks, especially the ones that involve deleting folders as SU, that I do thoughtfully and slowly before I press the Enter key. I think if others saw me do these at the careful pace that I do they would cringe. Are there critical programming tasks that you perform that you believe deserve this thoughtful and careful consideration?
Changes to live databases, actually I do a backup first just in case even know I'm extra careful :)
It's kind of a programming task, because if I do it wrong, it will affect my ability to get paid for programming: Write emails on touchy subjects or to touchy people.
It can take me an hour to get the tone of a one paragraph email just right.
Anything that irrecoverably changes important data. I've learned my lesson the hard way, several times.
A release process is usually a methodical thing for me.
Everything. I've never been a "just dive into it" programmer. Always have, always will be.
Submits - 'cause its embarrassing if I break a test.
Code to evaluate the accuracy of something I'm developing. Otherwise, I spend all this time making the other code production-ready, only to find it doesn't compute the right thing after all.
Common code. I.e. changes to old, shared code which is used in multiple independent programs.
Kernel driver stuff - cause those blue screens are a pain !
Any collection juggling, especially in C (all it takes is one off by one error to shotgun your heap).
On the DB side, if I run an update/insert/delete and I don't want to backup the whole database, I always select * into myTable_backup from myTable
if make big changes in Visual Studio eg a big refactoring or maybe re-organising solution\project structure I will do it on a copy of solution first to see if there are any gotcha and that the bloody thing will still compile and play nice. Once satisfied this is the case I will do it on code under source control.
I do this because I have experienced situations where the 'rollback' functionality of whatever source control you are using won't let you rollback as required and\or does not get it %100.
Doing get from SourceSafe — really easy to hit a wrong button and lose your local version that you've been working on.
/I hate SS, but am forced to use it./
I took a data structures class in C++ last year, and consequently implemented all the major data structures in templated code. I saved it all on a flash drive because I have a feeling that at some point in my life, I'll use it again. I imagine something I end up programming will need a B-Tree, or is that just delusional? How long do you typically save the code you write for possible reuse?
Forever (or as close as I can get). That's the whole point of a source control system.
-1 to saving everything that's ever produced. I liken that to a proud parent saving every single used nappy ever to grace the cheeks of their little nipper. It's shitty and the world doesn't benefit from it's existence.
How many people here go past the first page in google on a regular basis? Having so much crap around only seems to make it difficult to find anything useful.
+1 to keeping code forever. In this day and age, there's just no reason to delete data which could possibly be of value in the future. Even if you don't use the B-Tree as a useful structure, you may want to look at the code to see how you did something. Or even better, you may wish to come back to the code someday for instructional purposes. You'll never know when you might want to look at that one particular sniblet of code that accomplished a task in a certain way.
If I use it, it gets stuck in a Bazaar repository and uploaded to Launchpad. If it's a little side project that pitters out, I usually move it to a junk/ subdirectory.
I'll use it again. I imagine something I end up programming will need a B-Tree, or is that just delusional?
Something you write will need a B-tree, but you'll be able to use a library for it because the real world values working solutions over extra code.
I keep backups of all of my code for as long as possible. The important things are backed up on my web server and external hdd. You can always delete things later, but if you think you might find a use for it, why not keep it?
I still have (some) code I wrote as far back as college, and that would be 18 years ago :-). As is often the case, it is better to have it and never want it, than to want it and not have it.
Source control, keep it offsite and keep it for life! You'll never have to worry about it.
I have code from many, many years ago. In fact, I think I still have my first php script. If nothing else, it's a good way to see how much you have changed over time.
I agree with the other posters. I've kept my code from school in a personal source code repository. What harm does hanging on to it really do?
I would just put it on a disk for historical sake. Use the
Standard Template Library - one mistake people make is assuming that thier implementation of moderate to complex data structures are the best. I can't tell you how many times I have found a bug in a home grown B-tree implementation.
Keep everything! You never know when it will save you some work. About a year ago I needed some c code to parse an expression, tokenize it for storage, and evaluate the results latter. Ugly little piece of code.. But is seemed familiar, as it should have- I had to do a post-fix evaluator in college (30 years ago)- and still had the code. Admittedly it needed a little clean-up, but saved me a couple of days of work.
I implemented a red black tree in Java while in in college. I have always wanted to find that code again and cannot.
Now I do not have the time to recreate it from scratch since I have three kids and do not develop in Java.
I now keep everything so that I can relearn much faster. I also find it fascinating to see how I did something 1, 5, 10 years ago. It makes me feel good because I either did it right or I am better now and would do it differently
If I ever go back to college to give a lecture to future students it in on the list of things to do:
Save everything...
I'm a code packrat, for better or worse, but I guard it, because sometimes it's client-confidential.
On occasion, this has been really useful, like if a client lost their stuff, or their documentation.
I lost a lot of old code (from 10 years ago) because of computer failure that wasn't backed up but in fact I do not really care because I do not really want to see code that is programmed in very old language. Most of this code was written in VB5...
I agree that now it's easy to keep everything but I think sometime it's good to clean up our backup/computer storage because it's like in the real world, we do not need to keep everything forever.
Forever is the beauty of the electronic medium. That's one of the most attractive aspects for me.
But, the keeping of it depends on your coding style, and what you do with it.
I'd suggest tossing your code if you're the type that...
Never looks back.
Would rather re-write from your memory to improve your craft.
Isn't very organized.
Is bothered by latent storage to no end.
Likes to live on the edge.
Worships efficiency of memory.
Logical reasons for tossing could would be...
It bothers you.
It disrupts your workflow by getting in your way.
You're ashamed of it.
It confuses you and distracts you.
Like anything that takes up physical space in life, it's value is weighed against it's usefulness.
All my code is kept indefinitely, with plans to return to it at some point, reflect, and refactor. I do that because it's fun to see my progress, and provides very accessible learning experiences. Furthermore, the incorporation of all my code into a consolidated framework is something I work towards all the time.
Forever...
Good code never dies. ;)
I don't own most of the code I develop: my employer does. So I don't keep that code (my employer does - or should).
Since I discovered computing, I wrote code for devices that no longer exist in languages that are no longer worth. Maybe there is some emulator but keeping that code and running it would be nostalgia.
You can find B-tree information (and many other subjects) on Wikipedia (and many other places). There is no need to keep that code.
In the end I keep only code that I own and maintain.
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 3 years ago.
Improve this question
Are there any methods/systems that you have in place to incentivize your development team members to write "good" code and add comments to their code? I recognize that "good" is a subjective term and it relates to an earlier question about measuring the maintainability of code as one measurement of good code.
This is tough as incentive pay is considered harmful. My best suggestion would be to pick several goals that all have to be met simultaneously, rather than one that can be exploited.
While most people respond that code reviews are a good way to ensure high quality code, and rightfully so, they don't seem to me to be a direct incentive to getting there. However, coming up with a positive incentive for good code is difficult because the concept of good code has large areas that fall in the realm of opinion and almost any system can be gamed.
At all the jobs I have had, the good developers were intrinsically motivated to write good code. Chicken and egg, feedback, catch 22, call it what you will, the best way to get good code is to hire motivated developers. Creating an environment where good developers want to work is probably the best incentive I can think of. I'm not sure which is harder, creating the environment or finding the developers. Neither is easy, but both are worth it in the long term.
I have found that one part of creating an environment where good developers want to work includes ensuring situations where developers talk about code. I don't know a skilled programmer that doesn't appreciate a good critique of his code. This helps the people that like to be the best get better. As a smaller sub-part of this endeavor, and thus an indirect incentive to create good code, I think code reviews work wonderfully. And yes, your code quality should gain some direct benefit as well.
Another technique co-workers and I have used to communicate good coding habits is a group review in code. It was less formal and allowed people to show off new techniques, tools, features. Critiques were made, kudos were given publicly, and most developers didn't seem to mind speaking in front of a small developer group where they knew everyone. If management cannot see the benefit in this, spring for sammiches and call it a brown bag. Devs will like free food too.
We also made an effort to get people to go to code events. Granted, depending on how familiar you all are with the topic, you might not learn too much, but it keeps people thinking about code for a while and gets people talking in an even more relaxed environment. Most devs will also show up if you offer to pick up a round or two of drinks afterwards.
Wait a second, I noticed another theme. Free food! Seriously though, the point is to create an environment where people that already write good code and those that are eager to learn want to work.
Code reviews, done well, can make a huge difference. No one wants to be the guy presenting code that causes everyone's eyes to bleed.
Unfortunately, reviews don't always scale well either up (too many cooks and so on) or down (we're way too busy coding to review code). Thankfully, there are some tips on Stack Overflow.
I think formal code reviews fill this purpose. I'm a little more careful not to commit crappy looking code knowing that at least two other developers on my team are going to review it.
Make criteria public and do not connect incentives with any sort of automation. Publicize examples of what you are looking for. Be nice and encourage people to publicize their own bad examples (and how they corrected them).
Part of the culture of the team is what "good code" is; it's subjective to many people, but a functioning team should have a clear answer that everyone on the team agrees upon. Anyone who doesn't agree will bring the team down.
I don't think money is a good idea. The reason being is that it is an extrinsic motivator. People will begin to follow the rules, because there is a financial incentive to do so, and this doesn't always work. Studies have shown that as people age financial incentives are less of a motivator. That being said, the quality of work in this situation will only be equal to the level you set to receive the reward. It's a short term win nothing more.
The real way to incent people to do the right thing is to convince them their work will become more rewarding. They'll be better at what they do and how efficient they are. The only real way to incentivize people is to get them to want to do it.
This is advice aimed at you, not your boss.
Always remind yourself of the fact that if you go that extra mile and write as good code as you can now, that'll pay off later when you don't have refactor your stuff for a week.
I think the best incentive for writing good code is by writing good code together. The more people write code in the same areas of the project, the more likely it will be that code conventions, exception handling, commenting, indenting and general thought process will be closer to each other.
Not all code is going to be uniform, but upkeep usually gets easier when people have coded a lot of work together since you can pick up on styles and come up with best practice as a team.
You get rid of the ones that don't write good code.
I'm completely serious.
I agree with Bill The Lizard. But I wanted to add onto what Bill had to say...
Something that can be done (assuming resources are available) is to get some of the other developers (maybe 1 who knows something about your work, 1 who knows your work intimately, and maybe 1 who knows very little about it) together and you walk them through your code. You can use a projector and sit them down in a room and you can drive through all of your changes. This way, you have a mixed crowd that can provide input, ask questions, and above all make you a better developer.
There is no need to have only negative feedback; however, it will happen at times. It is important to take negative as constructive, and perhaps try to couch your feedback in a constructive way when giving feedback.
The idea here is that, if you have comment blocks for your functions, or a comment block that explains some tricky math operations, or a simple commented line that explains why you are required to change the date format depending on the language selected...then you will not be required to instruct the group line by line what your code is doing. This is a way to annotate changes you have made and it allows for the other developers to keep thinking about the fuzzy logic you had in your previous function because they can read your comments and see what you did else-where.
This is all coming from a real life experience and we continue to use this approach at my job.
Hope this helps, good question!
Hm.
Maybe the development team should do code-reviews of each other codes. That could motivate them to write better, commented code.
Code quality may be like pornography - as the famous quote from the Justice Potter Stewart goes, "I know it when I see it"
So one way is to ask others about the code quality. Some ways of doing that are...
Code reviews by their peers (and reviews of others code by them), with ease of comprehension being one of the criteria in the review checklist (personally, I don't think that necessarily means comments; sometimes code can be perfectly clear without them)
Request that issues caused by code quality are raised at retrospectives (you do hold retrospectives, right?)
Track how often changes to their code works first time, or whether it takes several attempts?
Ask for peer reviews at the annuak (or whatever) review time, and include a question about how easy it is to work with the reviewee's code as one of the questions.
Be very careful with incentivizing: "What gets measured gets done". If you reward lines of code, you get bloated code. If you reward commenting, you get unnecessary comments. If you reward lack of bugs found in the code, your developers will do their own QA work which should be done by lower-paid QA specialists. Instead of incentivizing parts of the process, give bonuses for the whole team's success, or the whole company's.
IMO, a good code review process is the best way to ensure high code quality. Pair programming can work too, depending on the team, as a way of spreading good practices.
The last person who broke the build or shipped code that caused a technical support call has to make the tea until somebody else does it next. The trouble is this person probably won't give the tea the attention it requires to make a real good cuppa.
I usually don't offer my team monetary awards, since they don't do much and we really can't afford them, but I usually sit down with each team member and go over the code with them individually, pointing out what works ("good" code) and what does not ("bad" code). This seems to work very well, since I don't get nearly as much junk code as I did before we started this process.