Различают фактические фрагменты кода (классы) и модули, в которых они поставляются. В простом случае вы запускаете приложение и просто говорите: «вы найдете нужные вам классы в этих местах», где список представляет собой список модулей. Мы используем PATH (для DLL) и / или CLASSPATH (для классов Java). Приложению обычно не нужно знать, из какой DLL или JAR пришел класс. [А как насчет возможности того, что более одного модуля содержит копию, возможно, с разными версиями, класса? Именно тогда загрузка классов становится такой веселой, но это совсем другая история.]
Так как общая структура определяет, какие классы ей нужны? Множество возможных путей, но концептуально с помощью какой-то конфигурации.
Посмотрите на идеи внедрения инверсии управления и зависимости, возможно, начните здесь
Я покажу, как можно изменить ваш пример, чтобы делать то, о чем вы спрашиваете. Я не хочу использовать слово «модуль», здесь у него слишком много возможных значений. Вместо этого я буду использовать «плагин» - один или несколько фрагментов кода становятся доступными, наше мнение хочет использовать все, что предоставляется .:
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() );
}
}
}
Это работает, если мы можем предположить, что все плагины соответствуют некоторому согласованному интерфейсу, здесь мы ожидаем, что сможем вызывать getDisplayString () для каждого плагина.
Обычно тип модульности, о которой вы говорите, зависит от некоторой степени контроля над тем, что подключается к фреймворку. Это может стать довольно сложным. Такие языки, как Java, позволяют вам получить объект и «отразить», чтобы найти все методы, имена которых выглядят как «getXXXXX ()». Таким образом, представлению может быть присвоен любой старый объект, и просто распечатать результат (скажем) getName (), getPhoneNumber () getPostCode () ...
Ключевым моментом здесь является то, что мы можем использовать некоторую согласованную модель, чтобы определить, какие метиды вызывать. В этом случае представление может быть очень гибким.