可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
When i start writing something complex, I find that restart the writing like 10 times before I end up with what I want, often discarding hundreds of lines of code.
Am I doing something wrong, or do others have workflows like this?
EDIT: Right now, I'm working on a modular compiler. The last project I was working on was a server in java. Before that it was some concurrency stuff.
I do a fair bit of planning, and I never start coding before I've got interfaces for everything.
Given that, is it normal to just wipe the slate clean repeatedly?
回答1:
Discarding many lines of code is usually a positive aspect of refactoring. That's great. But starting over ten times means that you probably haven't analyzed your problem and solution. It's fine to backtrack and sometimes to start over but not that often. You should lay out your code in such a way that when you backtrack and refactor, you keep most of what you created because it will exist in nicely isolated and logical chunks. (Using vague language since language of choice wasn't specified.)
From author's comment:
Usually I restart because I get
confused by all the stuff going on in
my code.
Study your craft and make good use of design patterns and other best programming philosophies to lend your code a well-defined structure... something you'll recognize months and even days down the road.
回答2:
If you're starting something complex, a little planning before you start writing would seem to be a good idea.
Design first.
回答3:
Perfectly normal. No matter how much I plan ahead, I very often have an "Aha!" moment once the hands hit the keyboard.
Just as often it's a "What the heck was I thinking?" moment.
It's all good. You're making better code.
回答4:
All the suggestions here are valid, however, remember that there's a moment in a programs lifetime that is "good enough". It's easy to fall into a trap of never ending refactoring, just because you see that "yes, this could be done better!". Well, face the truth -- unless your program has just a few lines, there's ALWAYS a way to do it better.
I believe there are happy programmers out there that don't suffer from that, but at least I need to keep reminding myself that there's a line that's called "good enough".
And it's especially true if you're writing code for someone else -- nobody will note that you did something "nicer", all that counts is "does it work well?".
Also, a VERY GOOD practice is at least to get it to WORK before rewriting. Then you can always fall back to a working previous solution.
(since 12 years I'm constantly rewriting a game I'm writing, and I'm nowhere near the end...)
回答5:
On a complex problem, this is common. If you aren't totally stabbing in the dark, it really helps to sketch out our ideas first, but then again you're just moving the 'retries' from code to paper.
If it helps you get to a good solution, how can it be wrong?
回答6:
It depends on how well I know the problem space. If it is familiar territory, then I'd be worried if it took 10 iterations. If it is unfamiliar territory, then it might take as many as 10 iterations, but at least some of them would be reduced to prototype - or an attempt at a prototype - before being discarded.
回答7:
If you are learning something with each iteration then there probably isnt a problem. Deadlines and pesky things like that might make your life a little more difficult. :)
When I am working on a new problem I like to pseudocode it out in comments in the actual function handler, as part of generating the stub for my TDD. Then add the code in to each step I had in the comments of the function body.
It helps me to keep focused on what the problem that I am solving is, and not get lost in the details to early.
回答8:
The single biggest change you can do to help yourself would be to plan your code first. On paper.
Your plan doesn't have to be super in-depth (although sometimes that's good too). Just sketch out a rough idea of what you want your program to do. Jot down the key functionality points. "I want it to do this, this and this".
Once you have that, sketch out a rough design. Classes, methods, functions, objects. Give it a little form. Do a rough allocation of functionality to various portions of your design.
Depending on the nature of the project, I might take a rough design such as that and turn it into a much more detailed design. If it's a small project, maybe not. But no matter the projected complexity, time spent designing will reward you with better code, and less time spent coding. If you have obvious mistakes that require you to refactor large portions of your program, they should be apparent in your initial design and you can adjust it. You won't have wasted hundreds of lines of code on an obvious mistake.
回答9:
Compilers are very complex applications, and you can't write an optimizing compiler from start to finish in one pass - no matter how much thought you put into it at first. Usually you attempt to get something to work correctly from start to finish and then go back to modularizing it and adding new features like optimizations. This process means lots of refactoring and replacing whole sections outright. This is also part of the learning processes - as no one can know everything and remember it!
(I'm also working on a .NET compiler as part of the MOSA project - www.mosa-projet.org.)
回答10:
solve your problem on paper . . . dont be in such a rush to type.
回答11:
There are two situations. (1) I've been able to confidently plan ahead and isolated my abstractions. (2) I haven't.
For (1), an effective technique is to put in dummy versions of certain classes or functions just to drive the rest of the code. (or conversely, to write said classes and functions and drive them with a test script.) This allows you to tackle only part of the complexity in each pass.
As much as everyone says people should plan in advance, it often doesn't work that way, resulting in situation (2). Here, be careful to manage what you are trying to accomplish in one iteration of code. As soon as you find your brain unable to juggle all the things you are doing, scale back your ambition for what you want to achieve before the next compile-and-test. Allow your code to be flawed but easy-to-write on the first pass, and then develop it through refactoring. This improves efficiency over repeatedly wiping the slate clean.
For example, one way I used to get into messes was by sniffing out common code and refactoring into subroutines too early, before I really knew the shape of the code. I've since started allowing myself to duplicate code on the first pass, and then going back and factoring it into subroutines later. It has helped tremendously.
回答12:
It's called refactoring buddy and it's good, you just need to limit it so you won't end up wasting all your time refactoring code you have and is working instead of writing new code.
Some of the reasons why one must refactor are:
- Enhancing performance.
- Organizing code.
- You need to write your code in a different way to get something to work.
- To do something in a different way because it saves a lot of work (i.e.: Using MXML instead of ActionScript).
- You used the wrong name for a variable.
回答13:
Consider learning some framework in whatever language you're using (or in any language for that matter).
I think that learning frameworks made my code a million times better. By learning the frameworks (and more importantly how they work) I learned not just design patterns, but how to implement them realistically.
Consider looking at rails, cakephp, or django (assuming you're in a scripting language; I don't know any desktop language frameworks. Sorry!). Then see how their pieces fit together.