Iterative development, with frequent releases to the end users, is the
traditional solution to that problem, i think. It's fiendishly hard to
realise in practice, of course, because a user who doesn't know what he
wants usually also doesn't want to spend time finding out. He just wants
you to make it for him.
If the users are not complete numptys, seeing the first few screens and
sitting down to talk about it often sorts things out.
But, as I said, having somebody who's familiar with the target processes
in the design team works super-well. The best example of this I know
started when four of us (PM, designer, designer's mate, user rep) locked
ourselves in a room with a white board and drew, argued and discussed for
6 weeks, having spent the first two days making sure everybody could read
and understand a simple ERD. At the end of this we had a data model
nobody could poke holes in and that we knew was a good match with the
subject area. In parallel with this the pair of us techies had designed,
presented and had sign-off on a consistent screen design, a control
dialogue that both casual and power users could use easily, and we had a
system structure sorted out as well.
Its true that we released a small part of the system as soon as it was
running to get feedback. That was accepted without incident.
There were also two complex database search routines and a date parser
which nobody could predict the acceptability of until there was a fairly
large amount of data to scan. We put all three in self-contained modules
and explained to the users that we weren't sure how good they'd be, so
we'd written the simplest code we thought would be acceptable and asked
for feedback: that was exactly the right approach. In the event one of
the searches was exactly what was needed and the other needed two
rewrites. The date parser was also good though we later added a couple
more formats that nobody had realised we needed (BC dates, two and three
digit years for dates before 1000AD).