There are 5 technologies/design principles, that when used together, help to ensure that any software written is sufficiently adaptable to be ready to be reused in future architectures, regardless of what you know about those future architectures at the present time.
All communication between resources is done by URL, and the built-in REST actions: GET, PUT, POST, and DELETE. Every resource is assigned a URL, and you interact with that resource through its URL. (Imagine if your TV had a URL, or your light switch. You wouldn't have to learn complex programming languages to interact with it, only REST URLs. Query it for its API, and list of available resources, then you can write anything, in any language, on any platform, as long as it produces a REST HTTP request to that URL.)
Augmented HTML vs. Script-based Procedural Coding
Whitelist Role-based Security
Program so that by default your users only have access to public information. Then, grant them access by assigning them to different roles. The roles are assigned permissions to access certain data. Even if they have no special permissions, they should be assigned to a basic role, like "user". All programming should then begin by checking which roles the user possesses, and then collecting or building the data assigned to each role. That way you get in the habit of always checking roles as the first step in every function.
Only write atomic functions that are initiated based on get() or set() operations on objects. Getter functions ("filters") filter data and provide just-in-time resources. Setter functions ("listeners") trigger additional processing, and make sure that every property or child object is treated in exactly the same way. This encourages separation of functionality, reuse of atomic functions, and these functions can be attached anywhere they are needed, even for uses not yet dreamed of, because every object has properties. (See What is Pi Programming for more details.)
Degrees of Maintenance
Each time you make an object reusable, you are adding a layer of maintenance to your application. This layer will have to be debugged in the future. Make sure that the amount of time saved by making the object reusable outweighs the extra debugging time incurred by another layer of maintenance to your applications. (See Degrees of Maintenance Blog for more details.)