If the requirements are changing frequently and you want to deliver your code in time so What is the best solution or methodology used to overcome going to spaghetti?
I think one of the key points is to write code that is easily changable. This normally favours the specific instead of the abstract. There are also some design patterns that tend to build very big pillars through your code. Such pillars have a tendency to make changes happen in the wrong places because you get afraid of changing those monumental central pieces of your code that you really should be changing.
Test coverage is a really great helper in allowing you to do fearless refactoring. It's the parachute that makes the difference between the crazy and the sane test plane pilot.
Good test coverage is the best defense against frequent changes.
Catering for frequent requirements changes is the purpose of the following:
- Object oriented design(Abstracting Business domain and splitting it into manageable purpose-oriented concepts)
- Design patterns(reusing established coding solutions)
- MVC-based development(Separation of Data, Business logic and View/presentation)
- Architectural framework-based development(You design an architectural framework first before commiting any project-specific design and development)
So if you want to avoid spaghetti, learn and apply the above mentioned concepts.
What is your definition of spaghetti code? For me, spaghetti code is a too long, unstructured and chaotic method/function. This does not happen due to changing requirements, but due to developers' laziness. If you have to rewrite a method because things have changed, you can also clean it up directly without much overhead.
If you mean a badly designed object structure instead, you can be right. If requirements change too fast, you will easily end up with classes that no longer do what they were intended for, bad object hierarchies, and the like.
There are some tipps to avoid this:
Don't overdesign in the beginning. Try to keep your methods, classes and class hierarchies as simple as possible to make changes less difficult.
After a requirement changes, don't start implementing it right then, but take a step back and look if your code structure needs to be changed before the new feature can fit in.
Communicate to your client, that the change requires some time. If you know that they know that changing the requirement also implies changes in the structure of your code, you will have less pressure to squeeze your code into existing structures.
Always refactor while coding. In my experience, the small refactorings like moving redundant code from several places into a single method or class are most effective to keep your code clean. Be always on the lookout for code smells and remove them as fast as possible to make your work easier. This takes some experience, but now is the right time to start training this :-)
Like krosenvold said, play it safe by adding test cases to your code to take away your fear of big changes. Having worked on a large legacy system myself, I know this fear and what it feels like to work without a safety net. When you work on your safety net first, It becomes less of an adventure to make neccessary changes.
For any requirement, design your code for maximum possible changes. This can be done by separating the invariable part from the variable part. This wont take much time before development. Spaghetti code appears most of the time because of requirement change, and your design and programming should be able to withstand it.
http://www.dreamsongs.org/Files/DesignBeyondHumanAbilitiesSimp.pdf would be helpful.
- anticipate the changes, if/when you can, and generalize the requirements if possible
- more importantly, anticipate the time between changes
- chunk the work/features/iterations so they can be completed in the time between changes
- voila! you're now doing agile on the fly and constant change seems normal 8-P
- take aspirin, whine at boss, loop back to #1 ;-)
Frequent changes to a project's requirements, including adding or removing features, does not necessarily lead to spaghetti code, but it probably will if you don't write modular software (see Modular Programming). The things to strive for include the following:
- Each module (whether it is a function, class, library, or complete application) has a well defined purpose.
- Each module is ideally no larger than it needs to be to serve its defined purpose.
- Modules are loosely coupled, meaning they can be substituted for other modules without causing the software to break.
- Modules can be tested individually to verify that they serve their purpose without error.
- Modules are organized in a way which helps to make the problem domain intuitive to other programmers.
Given well organized modules (again, these can be functions, classes, libraries, and full applications) that work together while being loosely-coupled, the way to deal with changes in requirements is to write new modules, expand on existing modules, and connect modules in new ways.
As for how you arrive at a situation of having these nice software modules in the first place, refactoring is key. Other practices such as unit testing and a development methodology (such as Scrum) are also helpful, but refactoring is your bread and butter--and it is one thing that many business environments do not make enough time for.
For good advice on writing loosely coupled code, do some research on dependency injection.
scope creep/bad requirements analysis (ever changing):
avoid it like the plague is the best advice one can give to guarantee any quality (code or otherwise), it will always have negative effects (on all sides) regardless of how well you try to plan your development projects.
Best solution is to set milestones and to know when to show this link to whoever keeps changing the requirements.
You can be uber-human in your approach thinking out of the box and making the code as easy to change as possible, but you will still fail horribly if you just say yes to all features without understanding how that should affect the project's Quality-Time-Scope pyramid.
Frequently-changing requirements is a problem that Agile methods were developed to handle - they were created at least partly in recognition of the problem that requirements do change, often for very good reasons.
If a requirement changes that you have not already implemented, then the impact should be minimal if you don't invest much effort in up-front design but manage design evolution by small iterations, constant testing and refactoring.
If a requirement that has already been implemented changes, and you cannot move your completion date, then you have three choices: work longer hours to recover the lost time, drop requirements (reduce scope) to pay for the extra work, or reduce the quality of the product (which might be the "spaghetti" option").
If you are leaving with one advice: Refactor, refactor, refactor! Often!
Everything else is details about making refactoring easier.