In a post to his site Matthias Noback looks at an interesting idea when it comes to the structure of your code: the idea of negative architecture and making assumptions.
In "Negative Architecture", Michael Feathers speaks about certain aspects of software architecture leading to some kind of negative architecture. Feathers mentions the IO Monad from Haskell (functional programming) as an example, but there are parallel examples in object-oriented programming. For example, by using layers and the dependency inversion principle you can "guarantee" that a certain class, in a certain layer (e.g. domain, application) won't do any IO - no talking to a database, no HTTP requests to some remote service, etc.
[...] A negative architecture is what's "between the lines". You can look at all the code and describe a positive architecture for it, but given certain architecture or design rules, there's also the background; things we can be sure will never happen.
He goes on to give a few examples of "negative architecture":
- "An object does nothing meaningful in its constructor"
- "An object doesn't also fetch dependencies statically if it also gets any number of dependencies injected"
- "If a class is not marked final, it has at least one subclass"
- "If a property is not marked "private", it's used by at least one subclass"
- "An abstract class won't use methods that aren't part of its published interface"
- "If an object has one public method, it won't have any public static methods"
For each item in the list there's a summary (and sometimes code) included to help clarify the point.