One thing I've understood years after experiencing it in real life is that the activities design -> implementation do not necessarily follow such sequence!
I've learned it during my formal studies, but never got consciousness of such reality until I've found (again) the terms "forward-design" (FD) and "backwards-design" (BD). The traditional understanding of the sequence to build a system is FD. Seems logical, obvious, inevitable. But perhaps such is appropriate just part of the time.
The rest of the time (and mostly when building large systems), FD is simply not possible. That, because our brain is not able to grasp a complex set of systems (complexity essentially means difficulty of understanding), and make them interact mentally. In such cases, one usually starts by building POCs (Proofs of Concept) in order to identify the complexities and divide the problem based on them. Building a POC usually provides the necessary inputs and understanding to proceed with... Design!
That's how Backwards-Design works. Coding something without a previous design helps identifying the elementary concepts and constraints that one should take care of during the formal design process. BD is quite common, few architects and engineers pay attention to the strategy, but if you have a previous design that you need to modify at a certain point because during the implementation you've discovered an issue, you are doing BD.
A couple of examples. We needed an overloaded communications broker, which should run in Java, c++ and python. How did we addressed the design? Just started by coding, because we had no idea of what we were facing, which was the real problem behind. As soon as we got to run our POC, then, we started the real design. Second example. We needed a tool to run tests in largely heterogeneous conditions. The process was the same. Tried a couple of solutions, investigated how other systems address such complexity and there we got it: the secret was finding the adequate layering to make the parts interact (there are hundreds of ways of diving and solving a problem, finding the right one is really an art). After that, formalizing the design was smooth sailing.
And perhaps more: for my personal experience (ymmv), design is an interactive process between the experience of the path vs. the target goal. That is, there's no pure FD or BD. They normally go together. When you design without a previous process of coding it's because you already have such experience from past implementation processes. If you can design something without coding, you are not; you are in fact basing the design on previous coding experiences.
So, independently of your position being a developer, or an architect, you will always end up making implementation and design. The only difference is who writes the document.
The main consequence I've got to experience from this learning is that the design period should not be exclusive with the implementation period in the planning document. Both should overlap. Such change has helped me relaxing about the design, and to be confident about being wrong, and helped me to make a weekly or a monthly deep revision of the design and the implementation. In addition, this approach goes perfectly with Agile!
An important note: this approach, for the construction of a complex system is not possible for someone not having strong programming AND designing skills. A lot of architects fail due to such cause. A good scrum master could compensate equivalent lacks in a team and make the members work as a single wise and experienced mind, though.
Second important note: solving a problem means essentially knowing how to divide it in parts that can be solved independently and individually. BD is the only methodical process to identify the complexities of a BIG problem and divide it in parts that can be solved independently. This seems absolutely evident, but it's not. A lot of technicians don't know how to divide a problem and make highly heterogeneous problem divisions, endind up with multiple simple parts and a few number of parts loaded with larger complexity. That is not dividing the problem: that is growing it. With the consequential budget growth.