You may organize software to be more robust for changes
- create classes, interfaces, packages: language / programming level
- use design pattern and design principles: design level
- separate modules, manage dependencies: build level
- create architecture, most times introducing tiers: architecture level
For example .Net client communicates with Java spring server and stores data in Oracle DB. The platforms are different, each tier has its own representation. You have to convert back and forth between models of adjacent layers. You can even have multiple models in the same tier justified by design. These conversions can easily make up half of your system
Have all these conversions added value to user?
Between nodes, processes you also need to serialize / marshal your data, maybe sending over the wire. This add extra layers where the same bit of information needs to go through.
What if we start from user perceptive and drive our development from concrete user stories. Imagine if you would be able to describe what user wants and test your code against it. You could avoid adding unnecessary complexity.
Here is where related test first approaches come into pictures.
Test Driver Development, Behavior Driven Development, Acceptance Test Driven Development and Specification by Example.
You may end up creating multiple models but you know that you start in simplest way possible, Will it have a good design? Probably not. But you are instantly ready for refactoring because your tests are covering your users' needs.