A broad question, with many answers.
When designing a program you can use:
- Setting up requirements, possibly in a use-case form ("as a ... I want to ... so that ...")
- Mapping the verbs and nouns in your requirements to classes and operations
- Drawing UML diagrams of the subject matter
- Creating flow charts and sequence diagrams
- Identify component boundaries with thin interfaces to keep complexity organized and local