Distinguish between the actual pieces of code (classes) and the modules in which they are delivered. In a simple case you launch an application and just generally say "you'll find the classes you need in these places" the places being a list of modules. We use PATHs (for DLLs) and/or CLASSPATHs (for Java classes). The application doesn't usually need to know which DLL or JAR a class came from. [What about the possibility that more than one module contains a copy, perhaps with different versions, of a class? That's when classloading gets to be so much fun, but taht's a whole other story.]
So how does a general framework decide which classes it needs? Lots of possible ways, but conceptually by some kind of configuration.
Have a look at the ideas of Inversion of Control and Dependency injection, maybe start here
I'll show how your example might be changed to do the kind of thing you're asking about. I don't want to use the word "module" here it has too many possible meanings. Instead I'll use "plugin" - one or more pieces of code are made available, our view wants to use all that are provided.:
Controller {
// the list of what you have been calling modules
List<IPlugins> myPlugins;
initialise() {
// somehow we initialise that list of plugins
// imagine we read a config file, or some such
// If you read about Dependency Injection you'll see
// how we might do that
}
index(){
viewModel.setUser("John");
viewModel.setCategory("Programer");
showView(viewModel);
}
}
View {
showView(viewModel) {
System.out.println(viewModel.getUser().toString());
System.out.println(viewModel.getCategory().toString());
forEach( onePlugin : viewModel.getPlugins() ) {
System.out.println( onePlugin.getDisplayString() );
}
}
}
This works if we can assume that all plugins conform to some agreed interface, here we expect to be able to call getDisplayString() for every plugin.
Typically the kind of modularity you are talking about depends upon some degree of control of what is getting plugged into the framework. It can get quite sophisticated. Languages such as Java allow you to get an Object and "reflect" to find all methods whose names look like "getXXXXX()". So the view could be given any old object, and simply print out the result of (say) getName(), getPhoneNumber() getPostCode() ...
The key here is that we can use some agreed pattern to determine which methids to call. In that case the View can be very flexible.