Как написать main () в ООП? - PullRequest
       44

Как написать main () в ООП?

6 голосов
/ 28 ноября 2008

Когда я впервые начал программировать, я написал все в основном. Но, как я узнал, я пытался сделать как можно меньше в моих main() методах.

Но где вы решаете поручить другому классу / методу взять на себя ответственность за программу с main()? Как ты это делаешь?

Я видел много способов сделать это, например:

class Main
{
  public static void main(String[] args)
  {
    new Main();
  }
}

и некоторые подобные:

class Main {

   public static void main(String[] args) {

    GetOpt.parse(args);

    // Decide what to do based on the arguments passed
    Database.initialize();
    MyAwesomeLogicManager.initialize();
    // And main waits for all others to end or shutdown signal to kill all threads.
  }
}

Что следует и не следует делать в main()? Или нет серебряных пуль?

Спасибо за время!

Ответы [ 8 ]

17 голосов
/ 28 ноября 2008

код в основной функции:

  • Не может быть проверено юнитом.
  • Невозможно получить зависимости путем внедрения.
  • Не может быть повторно использовано другими приложениями, похожими на первое, которое вы пишете.

Поэтому код в основной функции:

  • Должно быть настолько просто, что вас устраивают только функциональные / системные тесты.
  • Должен нести ответственность за настройку «катящегося шарика» для зависимостей, используемых всем вашим другим кодом (то есть main действует как uber-factory, создающий ваше приложение).
  • Должен делать только то, что относится к настройке вашего приложения (т. Е. Не то, что тестовый код или демонстрационная версия должны делать точно так же).

На практике это означает, что реальные приложения не имеют много в основном. У игрушечных приложений и одноразовых программ может быть много общего, потому что вы все равно не планируете их тестировать или использовать повторно.

На самом деле, кое-что из того, что я говорю выше, относится к C ++. Конечно, основные методы Java могут быть вызваны тестовым кодом или различными приложениями. Но они по-прежнему не принимают объекты в качестве параметров, а только аргументы командной строки, поэтому степень, в которой они могут быть изолированы при тестировании или вести себя хорошо с точки зрения повторного использования, довольно низка. Я думаю, вы могли бы передать им имена классов для создания экземпляров и использования для создания остальной части приложения.

[Редактировать: кто-то удалил теги "C ++, Java" из этого вопроса. Итак, то, что я говорю выше, относится к C ++ и Java. Другие языки могут относиться к основному так, чтобы он был менее особенным, и в этом случае у вас может не быть особой причины относиться к нему особым образом.]

7 голосов
/ 28 ноября 2008

По моему мнению, "основной" проекта большого размера должен содержать около 3 вызовов функций:

  • Вызов функции инициализации, которая устанавливает все необходимые настройки, предпочтения и т. Д. Для приложения.
  • Запуск основного «контроллера» приложения
  • Ожидание завершения основного контроллера, а затем вызов функции завершения, которая очищает все, что необходимо очистить, в «main» (хотя контроллер уже позаботился о большей части очистки).

Любое значительное приложение будет разделено на функциональные блоки, обычно с некоторой иерархией. Главный контроллер может иметь несколько дочерних контроллеров для определенных функций.

Делая это таким образом, гораздо легче найти определенную функциональность, а разделение проблем лучше.

Конечно, как уже говорили другие ответы, в разработке программного обеспечения действительно нет серебряной пули. Для короткого проекта я мог бы поставить все на первый план, просто чтобы все было быстро запущено. Я думаю, что также зависит от языка - некоторые варианты могут быть проще, чем другие на определенных языках.

4 голосов
/ 28 ноября 2008

Как говорится, все, что плавает на твоей лодке. :) Вы должны сосредоточиться на том, чтобы сделать код простым, легким для чтения и эффективным, используя любые инструменты, необходимые для достижения этой цели. Если это требует ввода большого количества кода в main - сделайте это. Если вы чувствуете, что объекты сделают вещи более организованными - идите этим путем.

Создание одного экземпляра class Main с последующим вызовом метода экземпляра Main(), который выполняет всю работу, так же хорош, как и запись всего непосредственно в метод main.

2 голосов
/ 08 декабря 2008

Посмотрите, содержание и форма «основного» метода сильно зависят от языка и среды. В Java каждый класс может иметь метод public static void main(), поэтому вполне возможно иметь более одного.

Но теперь давайте подумаем об этом с помощью закона модульности Парнаса: «Каждый модуль скрывает секрет, и этот секрет может измениться». «Секрет» модуля, который вызывается изначально, - это детали взаимодействия процесса с операционной системой: такие как получение аргументов и обработка нерегулярных завершений. В Python это приводит к чему-то вроде этого:

def main(args=None):
    #argument processing
    #construct instances of your top level objects
    #do stuff

if __name__ == "__main__":
   try:
      main(Sys.Argv)
   except: # everything
      # clean up as much as you can
   else:
      # normal cleanup, no exceptions

Дело в том, что вы получаете все из среды, которую можете, затем вызываете функцию main (); вы перехватываете все неперехваченные исключения и делаете с ними что-то умное, прежде чем программа умрет.

2 голосов
/ 28 ноября 2008

Я бы сказал, что дело не в вашей основной функции, а в том, что нет. В зависимости от сложности вашего проекта вы можете разбить его на функциональные разделы, такие как «Функции базы данных», «Функции отображения», «Полдник с викарием» и т. Д.

Все дело в читабельности кода. Может ли кто-то еще, кто никогда раньше не видел вашу программу, натолкнуться на нее и сначала получить хорошее обобщенное представление о том, что она делает?

Может тогда легко увидеть, куда идти, чтобы покопаться немного глубже в механизм?

Каждый функциональный раздел, который вы используете, выполняет только логический блок процессов? Это не должно делать только одну вещь, но это не должно делать все плюс кухонная раковина.

Разбейте ваш код так, чтобы его можно было поддерживать из внешнего источника.

Потому что бог знает, что когда дело доходит до того, что кто-то еще может исправить ошибку, тем лучше =)

В качестве прямого ответа на ваш вопрос, я бы поставил вызовы функций для каждого из основных компонентов в основном, настройки, процесса и завершения, чтобы каждый, кто на это посмотрел, получил быстрый обзор того, как программа работает. Затем они могут продолжить бурение, если потребуется.

0 голосов
/ 08 декабря 2008

Помните, что если кто-то хочет получить представление о том, как работает ваша программа, первое место, которое он, вероятно, будет искать, - это главное (по крайней мере, я бы). Так что я не думаю, что это хорошая идея - вкладывать в это как можно меньше. Но я бы сказал, что нужно ставить как можно меньше, чтобы с высоты птичьего полета понять, как работает ваша программа.

Таким образом, я думаю, что вашей самой большой проблемой при реализации основной функции должна быть удобочитаемость.

0 голосов
/ 28 ноября 2008

Дизайн вашей программы будет определять форму вашего "основного".

Наличие «правила», которое говорит о том, какой должна быть ваша основная функция, - ИМХО, - бессмысленно.

0 голосов
/ 28 ноября 2008

Я думаю, что основной метод должен объяснить, что программа делает при запуске. Поэтому он может вызывать методы инициализации, но логика должна быть извлечена в методы.

В вашем примере я бы не создавал метод Main (), но поместил бы его в исходный.

...