On his talk at the Java Zone 2014, Kent Beck listed what he considers to be key skills in software design. According to him, they don’t come naturally to programmers, but can be learned. Those skills are:

Tolerance for ambiguity

Developers must be able to accept that their design will never be completely clean. There’ll always be forces pulling it in different directions and assuming there’s only one “correct” solution will most likely just lead to frustration.

Ability to wait

Ambiguity can only be tolerated when developers are able to postpone a design decision to the last responsible moment. Many will be tempted to jump to a particular design change too soon. Or worse, ignore relevant design aspects completely.

Treating design as a social process

That’s what Kent considers to be the biggest cosmical joke on programmers. Effective design requires an understanding of the human side of software. The skills and dynamics of the team will inevitably affect how software is made. And grasping what the next person is going to think when they see the solution requires as much social as technical skills.

Personally, I’m not sure if the first two can exist separately. The last I consider to be the most important, and definitely the hardest.