Ступенька на пути к чистому и поддерживаемому коду

Предисловие

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

Введение

В этой статье ООП противопоставляется кодированию в процедурном стиле. Кроме того, в статье объясняется, почему в некоторых случаях может потребоваться кодирование в процедурном стиле. Если вы предпочитаете читать только код, смело переходите к концу статьи. Там вы найдете ссылку на код на GitHub.

Что такое объектно-ориентированное программирование (ООП)?

ООП — это парадигма проектирования программного обеспечения, в которой программа структурирована вокруг объектов и структур данных, а не функций и логики. Классическими языками программирования ООП являются Python, Java, C# и другие.

Пример

Представьте, что вас попросили создать программу, вычисляющую площадь круга, квадрата и прямоугольника. Требование — писать код в стиле ООП. Как бы Вы это сделали? Не стесняйтесь написать какой-нибудь псевдокод или попробуйте его!

Намекать

  1. Как будет выглядеть структура вашей программы?
  2. Сколько классов и методов будет в вашей программе?
  3. Как будут организованы эти классы и методы?

Одно из возможных решений:

// Data Object Asymetry
// Object Oriented example
case class Square(var side: Double = 0) {
  println(side * side)
}
case class Rectangle(var height: Double = 0, var width: Double = 0) {
  println(height * width)
}
case class Circle(
    var pi: Double,
    var center: Double = 0,
    var radius: Double = 0
) {
  println(pi * radius * radius)
}
object Geometry extends App {
  val pi = 3.141
  val side = 2.0
  val height = 1.0
  val width = 2.0
  val center = 2.0
  val radius = 0.5
  Square(side)
  Rectangle(height, width)
  Circle(pi, center, radius)
}

Программа разработана с классами, которые инкапсулируют данные и функциональность. Каждый объект класса независим от другого. Это затрудняет добавление новых функций, потому что все классы должны быть изменены. Однако легко добавить новые классы. Например, если бы я хотел напечатать каждую окружность Shape, такую ​​функцию нужно было бы добавить в каждый класс отдельно. Однако добавление класса Trapeze было бы простой задачей. Другими словами, если мы добавляем класс, мы редактируем код только в одном месте. Мы должны редактировать код как минимум в трех местах, если мы добавляем функцию.

Что такое кодирование в процедурном стиле?

Код процедурного стиля — это парадигма проектирования программного обеспечения, в которой логика программы находится в центре дизайна программы. Среди основных процедурных языков — Fortran, COBOL и C#.

Задача — процедурный пример

Далее, как бы вы реализовали приложение Geometry в процедурном кодировании? Подумайте над теми же вопросами, что и в подсказке для примера ООП.

Возможное решение:

// Data Object Asymetry
// Procedual example
case class Square(var side: Double = 0) {}
case class Rectangle(var height: Double = 0, var width: Double = 0) {}
case class Circle(var center: Double = 0, var radius: Double = 0) {}
object Geometry extends App {
  val pi = 3.141
  val square = Square(2.0)
  val rectangle = Rectangle(1.0, 2.0)
  val circle = Circle(1, 0.5)
  val shapes = List(square, rectangle, circle)
  def hasArea(shape: Any): Unit =
    shape match {
      case Square(side) => println(side * side)
      case Rectangle(height, width) => println(height * width)
      case Circle(center, radius) => println(pi * radius * radius)
      case _ => println("Not a Shape")
    }
  
  shapes.foreach(shape => hasArea(shape))
}

Объяснение

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

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

Когда и зачем их использовать?

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

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

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

Ключевые вынос

В своей известной книге «Руководство по Agile Software Craftsmanship» Роберт С. Мартин писал: «Зрелые программисты знают, что представление о том, что все является объектом, — это миф. Иногда вам действительно нужны простые структуры данных с работающими с ними процедурами». В конце концов, знание того, в каком стиле вы хотите запрограммировать свое приложение, значительно повысит его удобство сопровождения.

Заключительные слова

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

Гитхаб:

https://github.com/DataBach-maker/ScalaExamples/tree/main/OOP_vs_PSC

Рекомендации

Мартин, RC (2011). Чистый код — руководство по гибкому программному обеспечению. Пирсон Образование.