Think Twice, Code Once
The abstractions you choose define the overall structure of the system you build. Choosing well can save massive amounts of effort later. Working with a system built from well-designed abstractions is amazingly rewarding; the pieces slot together naturally, and you can solve problems with minimal effort. Badly designed abstractions, in contrast, cause you to spend more time fighting the system than using it.
Before you start implementing an abstraction, spend some time thinking about how the abstraction will be used. Modern computing is littered with examples of throw-away models that are still in use 40 or more years after they were initially created. You can't imagine every possible use, but you can try not to restrict them too much.