Предисловие

Это первая из серии статей, которые я пишу для начинающих программистов, особенно для тех, кто выбрал специальности, не относящиеся к CS, для своего формального образования. Я описал свой путь смены карьеры в предыдущей статье о Medium и знал, что изучение программирования для новичка может быть ошеломляющим или даже пугающим. В Интернете или где-либо еще есть множество учебных пособий и курсов, которые научат вас делать то или это; однако существует мало руководств, которые помогли бы новым программистам развить навыки и принципы более высокого порядка. Несмотря на то, что часто люди изучают программирование, занимаясь этим, все же необходимо периодически систематизировать все полученные знания, соединять точки и строить концептуальную основу для сильной и компетентной практики разработки программного обеспечения.

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

Урок 1. Абстракция.

Источник силы программистов

Первая программа - Абстракция - Когда и зачем абстрагироваться

Первая программа

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

Скажем, я хочу создать программу, которая считывает мой счет за электричество в формате PDF и извлекает сумму, которую я должен заплатить. Я хочу создать эту программу, потому что электроэнергетическая компания каждый месяц отправляет мне электронное письмо со счетом в формате PDF, но никогда не сообщает мне, какая сумма подлежит оплате в теле письма, поэтому мне нужно открыть вложение электронной почты и найти его. Да слишком много работы!

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

# Lang: python
# Let’s start with a document. Every line that starts with '#'
# is a comment, i.e. not code
doc = get_document()  # This function is not defined yet!
pages = get_pages(doc)  # Same here and below. It’s fine!
# Go through the pages.
for page in pages:
    content = get_content(page)
    if has_amount_due(content):
        amount_due = get_amount_due(content)
        do_something_with(amount_due)
    else:
        continue  # Go to the next page.

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

  • Сначала документ открывается и присваивается переменной с именем doc, которая представляет документ PDF, то есть счет.
  • Затем программа получает все страницы этого документа.
  • Затем он просматривает страницы в так называемом «цикле for». Другими словами, программа будет повторять набор операций для каждой из страниц, а операции, которые должны быть выполнены, представляют собой операторы прямо под строкой с циклом for.
  • Внутри цикла программа сначала считывает страницу и получает ее содержимое.
  • Затем в условном операторе программа проверяет, есть ли в содержимом данные, которые я ищу, например Сумма долга.
  • Условный оператор может иметь значение true или false. Если это правда, то есть на странице есть данные, которые я ищу, программа получает данные из содержимого; в противном случае программа переходит к следующей итерации и проверяет следующую страницу.

Обратите внимание, что я использовал много вызовов функций в этой маленькой программе, которые имеют форму func_name (arguments). Так же, как функция, которую вы изучили в математических классах, то есть y = f (x), эти функции принимают некоторое количество аргументов (может быть ноль, один или много) и возвращают что-то (или ничего, в некоторых случаях называется «недействительным»).

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

# Declare the get_amout_due without actually implementing it
# This function takes one argument called ‘content’, which is a
# string, i.e. a series of text characters, and returns a float,
# i.e. decimal number
def get_amout_due(content: string) -> float:
    # TODO(Di): implement for real.
    return 3.1415926

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

Абстракция

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

В Википедии когда-то было действительно хорошее определение для абстракции:

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

Это дает много преимуществ:

  • Абстрагированный код сравним с человеческими мыслями, точно так же, как раньше программа строилась шаг за шагом, все описывалось человеческим языком.
  • В идеале абстракция должна быть хорошо инкапсулирована. Другими словами, изменение того, как работает один шаг, не должно изменять другой, что позволило бы: 1) разрабатывать программы без предварительного знания программиста, как заставить программу работать на 100%, как ожидалось, поскольку 2) проблема может быть решена. по одной маленькой части за раз, и 3) можно было бы передать каждую из меньших частей другому разработчику / команде, что потенциально позволяет организации работать параллельно.
  • Так же, как и некоторые повторяющиеся операции, например поиск суммы, причитающейся на странице для каждой страницы в документе, может быть реализован один раз и использоваться снова и снова в цикле, общие функции могут быть созданы, а затем использоваться снова и снова.
  • Это в основном то, что происходит с программным обеспечением и веб-сайтами: они создаются только один раз, но затем распространяются и используются многими людьми.

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

Когда и зачем абстрагироваться

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

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

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

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

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

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

Здесь стоит выделить два очень важных момента:

  1. Код пишется людьми для чтения людьми; это должно быть легко понять. Машины просто выполняют код.
  2. Сила программного обеспечения заключается в том, что оно мягкое. Программное обеспечение можно легко изменить, чтобы приспособиться к постоянно меняющейся реальности. Жесткий код, неустойчивый к изменениям, стоит очень дорого.

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

Следующий

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