I have many hints that are often helpful in designing computer systems, and I also know a few principles. There are several ways to organize them: .Goals (What you want)-simple, timely, efficient, adaptable, dependable, yummy. .Methods (How to get it)-approximate, increment, iterate, indirect, divide and conquer. .Phases (When to apply them)-requirements, architecture, process, techniques.
Of course the goals are in conflict, and engineering is the art of making tradeoffs, for instance among features, speed, cost, dependability, and time to market. Some simpler oppositions are: .For adaptable, between evolving and fixed, monolithic and extensible, scalable and bounded. .For dependable, between deterministic and non-deterministic, reliable and flaky, consistent and eventual. .For incremental, between indirect and inline, dynamic and static, experiment and plan, discover and prove.
It also helps to choose the right coordinate system, just as center of mass coordinates make many dynamics problems easier. You can view the system state as a name?value map, or as an initial state and a sequence of operations that transform the state. You can view a function as code or as a table or as a sequence of partial functions. Notation, vocabulary, and syntax are other kinds of coordinates.
In the complex process of designing systems, both principles and hints can only be justified by examples of what has worked and what has not.