UML Diagrams take time and even though they provide knowledge about program design, the design changes and so do requirements, and hence it becomes a chore to keep UML Diagrams in Sync with code. I am trying to figure out how should we use UML in an optimum way.
It depends on how you are using UML and what information you need to capture and share with other people.
I've seen two primary use cases for UML. The first is as a language to capture design ideas at a high level. These diagrams wouldn't include every detail of the system, just the important ones. Often, these are also the more abstract diagrams - use case diagrams, state machine diagrams, activity diagrams, deployment diagrams, and to a lesser extent component diagrams and package diagrams. Some work might be done toward sketching class diagrams with an emphasis on public interfaces (ignoring, at this time, any private members or functions) and sequence diagrams. The other use case for UML is to capture the current state of a system, using reverse engineering tools. These are often more detailed class diagrams, sequence diagrams, communication diagrams, object diagrams, composite structure diagrams, and so on. This serves as documentation into how the system actually is for discussions about changes to the system.
As far as when to apply UML, it depends. At the right granularity, some of the diagram types can be used as soon as you start discussing system architecture. Others are more suited to discussions of detailed design and the specifics of the system. It all comes down to choosing the right diagrams to display relevant information to the people who need it in a timely fashion.
With regards to the problems with keeping UML in sync with code, there are two things to consider. First, review the types of documentation that you are keeping. If none of it is actively consumed or value-adding, this might be a good idea to eliminate it. If it's difficult to update, the act of updating it might be something that's pushed aside. Out-of-date documentation is worse than non-existent documentation, since no one can make a decision based on incorrect information. Second, if you have a codebase already, there are tools for facilitating the generation of UML diagrams from code, often called CASE tools or reverse-engineering tools - considering automating the process.
UML is a great tool to use during and after program design but only if you use it right.
First you need to ask yourself, why are you producing UML diagrams? Then you need to be honest with yourself and ask, is anyone actually going to read these, ever?
During design, having a UML diagram provides something for the development team that they can focus on and discuss. But this diagram doesn't need to be formal or even in any kind of document. Just take a whiteboard or a napkin and start drawing boxes. In this case, UML is just a loose set of rules that provides "common language" to everyone looking at your whiteboard.
After the design, and I mean, WAY after the design, when your code has settled down and you are not moving classes around, this is when you might decide that you want to capture some of the knowledge in a formal design document to preserve organizational memory. In this case, I would suggest to keep the design document at a high level (if people need details, that's what code is for). But UML could certainly be useful to highlight some of the major classes in your application and how they relate to each other. The key is that you want to produce these documents only after all (or at least most) changes are done, otherwise you will discover that maintaining UML can be a pain.
UML can be used in a whole spectrum of ways - from the back-of-the-envelope drawings all the way through the round-trip engineering, and everything in between these two ends. Deciding how to use UML depends a lot on the preparedness of your organization, and your management's stomach for the risk.
Deciding on round-trip engineering would address the synchronization problem, but will cost your team in terms of learning curve, and will almost certainly tie you to a single expensive vendor of software tools. This becomes especially important when the vendor has higher priorities than fixing a bug that annoys most of the developers in your organization; you don't have to worry about it if your organization is among the IBMs of the world, but in most other cases the concern is very real.
Deciding on UML as a drawing convention (i.e. no ties to code) brings along the code synchronization problem, but gives you flexibility to choose vendors for your UML tools, or even using free tools if you wish. In this case UML diagrams become just another piece of documentation that you maintain along with the code of your project. You should decide when this documentation gets updated.
One example that I've seen working reasonably fine required the UML documentation to be in sync at the time the coding starts, and at the time the coding is complete. During the coding phase we updated UML on paper if necessary, but we did not bother updating the electronic copy each time we added a method or refactored a class.
UML is great for conveying ideas and getting your mind wrapped around a given problem domain. However, like ANY documentation, it is only good for a moment in time. Go back to the agile manifesto regarding documentation. It is more important to provide working software than it is to provide comprehensive documentation that needs to be updated continuously.
When given a problem, use UML to understand the problem and then design a solution. You can use it in peer discussions to convince your co-workers to your solution, or as a catalyst for collaboration.
Build your solution and then check in your diagram along with your story or attach it to your work item in your project management software. Then, move on to the next story. You have it for later reference, but you should not be expected to keep going back and updating it.
Take note however - All of this is true unless this is some sort of flight controls software for a fighter jet where the government requires comprehensive documentation - but most of our work is in a business environment where MIL-STD-2167A is not required, thank goodness.
As the other answers already indicate there are many ways to use UML. Especially you are using it with different detail levels and different times in a project.
But you are asking about synchronizing code with UML. Our primary focus for one of our tools (UML Lab) was the cycle between Design and Implementation phases. To adapt the UML design while changing the source code becomes necessary. Being able to switch back and forth between fine design and code is called round-trip-engineering. Using such techniques failed for quite some time as there still is some abstraction necessary to really make use of such techniques. But it is possible now: One can reverse engineer Java code with custom templates and generate the very same source code from it afterwards. This enables developers (or architects) to modify the class design while the implementation is already running. We are doing this with Class Diagrams only. Regarding analysis of behavior, there are other tools, of course. But there is no round-trip-engineering for those parts of UML, as far as I can tell.
Tools for mapping back code to earlier phases than Design or even Requirements do not exists (yet:). Usually this problem is addressed by "traceability": The tools keep track of the results for artifacts so they can tell which requirements are affected by a source code (or whatever) change.
In his book, UML Distilled, Martin Fowler discusses UML as having three usages: An implementation language facilitated by code generators and round-trip software engineering tools, a blue print for manual creation of the code, or a method of sketching ideas to be used in a design.
When we talk about UML, I think of a system put together by many people (the three amigos, Rumbaugh, Booch, and Jacobson being the most visible) that includes around 13 different diagram types. Perhaps it follows a development life cycle described through the Rational Unified Process (RUP), but given the number of diagrams available, what are we talking about when we refer to basic program design?
I think we start with requirements elicitation using use case diagrams and use cases. A lot of Agile developers swear by story cards, which is also great. When we have the use case diagram, and use cases, we have something of a partitioning of the system, and maybe it is not too early for a deployment diagram or package diagram to identify the parts. Activity, sequence, and class diagrams give a lot of detail, and may be too low level to show the design in a basic way?
My interpretation of UML is that its advocates expect it to provide all the diagrams needed. If you want to use a block diagram or data flow diagram, they would probably point you back at one of their diagrams with the rational that those diagrams are remnants of structured design and have dissonance with the object oriented decomposition we are trying to make. Personally, I think that any diagram or written plan that tells you how to begin and proceed effectively toward your goals has merit.