There are a couple of different approaches to designing
software. One popular approach in big companies is to try and
emulate the way design is done in engineering and construction,
starting with lots of planning and design by 'experts' who then
give the plans to 'laborers' to go build. In software circles this
is often called Big Design Up Front, and generally speaking it
never works well. To get good results costs far too much time and
money for most software companies to bear.
There's a good reason why BDUF works for making physical things
but doesn't work for software, and it's not something that can be
changed. With physical things, at some level details don't matter
anymore, but with software the details matter all the way down to
the hardware.
Let me give an example: if you're designing a bridge, you can
draw blueprints on paper which shows girders. The girders are
described by giving their dimensions (accurate to 1/16th of an
inch, say) and the particular alloy the girder is made from. This
is sufficient to accurately model how that girder will behave under
all kinds of different stress loads which is important for ensuring
the bridge will be safe, and also to model how the girders will fit
together like a puzzle which is important for allowing the
steelworkers to build the bridge correctly, on-time, and
on-budget.
The key to all of this is the fact that you don't need to create
a real girder in order to test the design and make sure it's
correct. A few easily described properties of the girder are
sufficient; it doesn't matter where every atom goes, it doesn't
matter if the surface isn't perfectly uniform, it doesn't matter if
there is some rust, etc. Lots of the details just don't matter at
design time, and most of them don't matter at construction time
either.
Software just doesn't work this way. Software development
languages are extremely detail-sensitive: get one letter wrong, one
punctuation character in the wrong place or left out, and the
software won't work right. There is no way to accurately model
something this sensitive to detail without building it first, and
if you have to build it first you lose the biggest benefit of doing
design up-front: the ability to test and iterate on your design
cheaply before committing to a full build of it.
Some modeling does happen in software design, of course. The
models are typically imprecise diagrams and textual descriptions of
what the software needs to do, lacking most of the detail of
exactly how the software will actually do those things. These
aren't the equivalent of blueprints, they're more like conceptual
drawings that architects create of buildings and bridges before the
engineering designs start. You can't jump from a conceptual drawing
to construction on a bridge, but that's what most software firms
doing BDUF expect to be able to do with their software designs.
The reality is that software is ultimately designed by the
laborer, the programmer who is typing in the source code. That
programmer has to make all of the detailed decisions about how the
software will work, which requires an understanding of the overall
design and purpose of the software. The programmer is assisted by a
software architect and technical lead who produce the higher level
designs to provide a general direction, but in the grand scheme of
things their role is ultimately secondary to the programmer. They
teach and guide, while the programmer creates.