Почему хорошо разбить программу на несколько классов? [закрыто]

62

Я все еще учусь в средней школе (поступаю в 10-й класс), и мне еще предстоит пройти настоящий курс компьютерного обучения в школе. Все, что я до сих пор делал, это через книги. Эти книги научили меня таким понятиям, как наследование, но как помогает разделение программы на несколько классов? Книги никогда не говорили мне.

Я спрашиваю это в основном из-за недавнего проекта. Это аркадная видеоигра, вроде Flash-игры, как говорили некоторые люди (хотя я понятия не имею, что такое Flash-игра ). Дело в том, что это только один класс. Он отлично работает (хотя и с небольшим отставанием) только с одним классом. Итак, я просто спрашиваю, как разделение на несколько классов могло бы помочь.

Этот проект был на Java, и я единственный человек, работающий над ним, для записи.

kullalok
источник
1
Чтобы сделать каждый кусок программного обеспечения более простым! infoq.com/presentations/Simple-Made-Easy-QCon-London-2012
TehShrike
49
Когда вы читали свои книги, они были разделены на главы и разделы? Мы разбиваем программу на классы, чтобы упорядочить вещи, как книги делят текст на главы, чтобы упорядочить вещи.
riwalk
12
Римляне говорили: разделяй и властвуй.
Джорджио
7
@Giorgio: или по-английски, потому что латынь больше не используется: разделяй и властвуй .
Матье М.
40
Учитывая, что вы в 10 классе и уже смогли сформировать интеллектуальный вопрос, предоставив все детали, необходимые для хороших ответов, предоставив контекст и ваш относительный опыт, а также справочную информацию о том, почему вы задаете вопрос; вы уже более квалифицированы, чем многие люди, с которыми я сейчас работаю ...
CaffGeek

Ответы:

71

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

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

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

Oleksi
источник
7
Многие концепции / идеи в программировании (ОО-принципы, управление распределенным исходным кодом, стандарты кодирования) действительно имеют смысл, только когда вы работаете над относительно большими проектами в команде. Вы поймете, почему, когда вы действительно работаете над такими проектами.
joshin4colours
40
Стоит отметить, что простое разбиение проекта на несколько классов / файлов мало чем поможет. Что действительно важно, так это наличие автономных классов, поэтому изменение одного класса не требует знания чего-либо другого о программе (а использование класса не требует никаких знаний о том, как она реализована). Я поднял это, потому что я часто вижу код с большим количеством классов, но без реальной инкапсуляции. Инкапсуляция - это важная часть - то, как вы ее достигнете, это просто детали.
Восстановить Монику
2
Некоторыми ключевыми словами могут быть «связь» или «развязка», «инкапсуляция», «сокрытие информации».
Марктани
@BrendanLong, я согласен и добавлю, что инкапсуляция практически невозможна. Если, конечно, вы не пишете отдельные программы ... НО обычно есть много частей, которые не зависят друг от друга, но имеют только общие зависимости
Jo So
29

Ну, самый простой ответ может быть «Это помогает организовать вещи». Если ничего другого, вы можете сравнить его с разделами в блокноте - просто проще, если у вас есть «все, что связано с пользовательским интерфейсом», и «все, что связано с игровым процессом».

Более сложный ответ заключается в том, что разделять работу не просто удобно, но очень важно для управления сложностью (а «управление сложностью» - это почти название игры, когда речь идет о программировании). Классы или другие типы модулей позволяют вам «разделять задачи». Вы не только знаете, где искать «вещи, связанные с пользовательским интерфейсом», но вы можете быть уверены, что если вы хотите внести изменения в пользовательский интерфейс, вы можете просто сделать это в одном месте, и вам не нужно волнуюсь "сейчас, это единственное место, где я установил свой шрифт Comic Sans?" И вы можете внести изменения и знать, что эффект от этих изменений только в той (небольшой) области, которая подходит. Если все в одном классе или модуле, по сути, все является глобальным,

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

Ларри Обриен
источник
12

Это хороший вопрос! Просто и хорошо задано. Что ж ... ответ не так прост для понимания студентом, который изучает информатику и, вероятно, не знает глубоких знаний и, вероятно, не имеет опыта работы.

Итак, я могу ответить, описав сценарий и заставив вас представить, что мультиклассовое программное обеспечение лучше монолитного (созданного только одним классом):

  • Удобочитаемость : гораздо сложнее просматривать и писать код внутри файла с 10000 строками, чем несколько маленьких и организованных файлов.
  • Возможность повторного использования : если вы пишете один класс, вы можете избежать дублирования кода . Это означает больше строк кода и, возможно, больше ошибок (!)
  • Тестируемость : как насчет тестирования одной функциональности? Если вы выделите одну функциональность логики в одном классе, ваша жизнь станет проще.
  • Возможность сопровождения кода : Вы можете исправить ошибку или улучшить функциональность с помощью нескольких классов в одном месте: милые маленькие классы.
  • Структура проекта : оооооо, вы можете себе представить, насколько уродливым будет проект с одним исходным файлом?
AngeloBad
источник
Мне нравится ваш ответ, и я только что сделал некоторые изменения (которые все еще должны быть рассмотрены коллегами). Я упускаю момент, когда легче обнаружить изменения в системах управления версиями программного обеспечения, таких как SVN / GIT. Также проще работать с несколькими программистами параллельно для одного проекта.
Мартин Тома,
Я бы сказал, что разделение интересов, сплоченность и разделение - это концепция, которая находится на более высоком уровне, чем дисциплина ООП. Императивные, логические и функциональные программисты одинаково стремятся к высокой сплоченности и слабой связи.
Сара
8

Здесь есть много хороших ответов, и я определенно с ними согласен, но я чувствую, что стоит упомянуть кое-что еще.

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

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

Проведение программы в голове. Ссылка от Джорджио

Sephallia
источник
1
+1: работа в команде тоже важна! См., Например, paulgraham.com/head.html и параграф с заголовком «Не разрешайте нескольким людям редактировать один и тот же фрагмент кода».
Джорджио
@Giorgio Я вроде только пробежался по нему, но кажется потрясающим ресурсом! Я добавлю его в свой ответ просто потому, что некоторые люди могут не заглядывать в раздел комментариев. Определенно собираюсь дать ему более тщательное чтение через некоторое время.
Сефалия
Это также относится к контролю версий - работа с отдельными файлами означает меньше конфликтов и слияний.
Восстановить Монику
7

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

Это означает, что если вы разбиваете свой код на различные логические единицы (классы, модули и т. Д.), То это означает, что у вас может быть много коротких и простых для понимания фрагментов кода. это можно сохранить позже. Многие из моих модулей содержат менее 20 строк кода. Я знаю, что весь код на заданную тему находится в определенном месте. Это также означает, что если кто-то присоединится к проекту, ему будет намного легче находить вещи.

Как сказал Джеральд Суссман, наши программы должны быть написаны в первую очередь, чтобы люди могли их читать, а во-вторых, чтобы компьютер мог их запустить. (И если вы еще не прочитали «Структура и интерпретация компьютерных программ», вы должны это сделать)

Захари К
источник
4

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

Вы просто должны разделить и победить, чтобы справиться с этим.

Лорен Печтель
источник
3

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

Если вы можете посмотреть «структурированное программирование», вы, вероятно, найдете что-то более полезное для себя. (Убедитесь, что вы читаете о старом структурированном программировании. Старые термины часто приобретают новые, более причудливые значения, и вам пока что не нужно ничего причудливого.) Это довольно простая концепция разбить вашу программу на подпрограммы, что намного проще, чем разбить его на объекты. Идея в том, что ваша основная программа - это короткая подпрограмма, которая вызывает подпрограммы («методы» в Java) для выполнения работы. Каждая подпрограмма знает только то, что ей говорят по своим параметрам. (Одним из этих параметров может быть имя файла, так что вы можете немного обмануть.) Итак, просмотр заголовка подпрограммы / метода дает вам краткое представление о том, что он делает, делает почти с первого взгляда.

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

Java специально разработана для людей, которые пишут объектно-ориентированный код. Но даже самая интенсивная OO-программа использует некоторое структурированное программирование, и вы всегда можете испортить любой язык. (Я сделал OO на простом C.) Так что вы можете делать SP или что-нибудь еще на Java. Забудьте о классах и сосредоточьтесь на больших методах, которые можно разбить на маленькие, управляемые. Я должен добавить, что SP очень помогает с возможностью повторного использования вашего кода, а также с принципом СУХОЙ (Google, но это означает «Не повторяй себя»).

Надеюсь, я объяснил, почему и как разделить ваш код на несколько частей, не вводя «классы». Они - отличная идея и просто для игр, а Java - отличный язык для ООП. Но лучше знать, почему ты делаешь то, что делаешь. Оставьте ООП в покое, пока оно не станет иметь для вас какой-то смысл.

RalphChapin
источник
0

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

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

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

gorengpisang
источник
0

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

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

Однако, это не то, где классы сияют. Рассмотрим Stringкласс: вы можете иметь все те же функции, используя charмассивы и некоторые статические функции. На этом этапе функции дают вам немного дополнительной безопасности и синтаксического сахара. Вы можете написать string.length()вместо length(char_array); это не очень большое дело, но многим это нравится. Более того, вы знаете, что если кто-то дал вам String, он был создан с помощью Stringконструктора и что он должен работать с lengthфункцией - если версия массива не может обработать какой-либо символ, то у него нет способа помешать вам вставить его туда. ,

Это все еще не это, все же. Ключевым моментом является то, что классы связывают данные и функции, которые работают с ним, и абстрагируют их оба. Когда у вас есть метод, void f(Builder b)вы знаете, что получите Builder, и можете ожидать, что он будет поддерживать определенное поведение. Тем не менее, вы ничего не знаете о данных или выполняемых функциях - на самом деле, определения для обоих могут быть еще не написаны во время написания и компиляции f.

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

Антон Голов
источник
0

Вся идея основана на общем правиле под названием разделяй и властвуй .
Эта парадигма может использоваться почти везде; Вы делите проблему на более мелкие проблемы, а затем решаете эти маленькие, простые и хорошо известные проблемы.
Разделение вашей программы на классы является одним из типов разделения, которое стало распространяться в последнее десятилетие. В этой парадигме программирования мы моделируем нашу проблему с помощью некоторых объектов и пытаемся решить проблему, посылая сообщения между этими объектами.
Некоторые люди могут сказать, что этот подход легче понять, расширить и отладить.
Хотя некоторые люди не согласны :)

Rsh
источник
0

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

Идея в том, что вы не начинаете с длинной программы, а затем разбиваете ее на классы. Но вы сначала моделируете свое приложение с точки зрения объектов / классов, а затем соединяете их для создания приложений.

Vamsi
источник