x
 
Фёдор Борщёв
27 февраля 2020
Советы почтой каждую неделю
Пожалуйста, получите наше письмо, чтобы подтвердить свой адрес:
Вы подписаны на «Советы за неделю»:

Как написать аккуратный код? Часть вторая: связность


Аккуратный код

Связ­ность — мера, кото­рая пока­зы­вает, насколько чётко методы внутри класса сфо­ку­си­ро­ваны на реше­нии его основ­ной задачи. Слово «связ­ность» — это пере­вод англий­ского слова cohesion. К сожа­ле­нию, пере­вод не очень удач­ный, поэтому в раз­го­вор­ной речи про­грам­ми­сты часто упо­треб­ляют поня­тие «связ­ность» в зна­че­нии «зацеп­ле­ние», а «зацеп­ле­ние» не упо­треб­ляют вовсе. Чтобы дальше не путаться с тер­ми­нами, давайте сфор­му­ли­руем правило:

Аккуратный код

В хоро­шей архи­тек­туре каж­дый класс не зави­сит от сосе­дей и сфо­ку­си­ро­ван на реше­нии только одной задачи

Давайте пред­ста­вим, что «Поч­та­льон» из про­шлого совета решил жур­на­ли­ро­вать всю исхо­дя­щую кор­ре­спон­ден­цию. Чтобы такой жур­нал был полез­ным в рас­сле­до­ва­нии инци­ден­тов, в нём нужно хра­нить не только текст письма, но и иден­ти­фи­ка­тор сущ­но­сти, кото­рая отпра­вила письмо, к при­меру номер заказа. Решим задачу «в лоб», при этом не забы­вая, что почту в нашем при­ло­же­нии отправ­ляет не только «Заказ», но и «Догонятель»:

class Mailman:
  def __init__(self, customer, sender):
    self.customer = customer
    self.sender = sender

​
  def deliver(self, subject, message):
    ...
    self.log(subject, message)

​
  def log(self, subject, message):
    sender_name = 'Unknown'

​
    if self.sender.__class__.__name__ == 'Order':
      sender_name = f'Order #{self.sender.id}'

​
​    elif self.sender.__class__.__name__ == 'Chaser':
      sender_name = f'Chaser for Order #{self.sender.order.id}'

​
    LogEntry.objects.create(sender_name=sender_name, subject=subject, message=message)

Смот­рите, как раз­дулся метод для жур­на­ли­ро­ва­ния, — вме­сто того, чтобы про­сто запи­сать строчку в жур­нал, он вынуж­ден зале­зать внутрь класса, кото­рый его вызвал. АПИ «Поч­та­льона» поте­ряло в удоб­стве — теперь, когда в при­ло­же­нии появится новый класс, кото­рому нужна почта (к при­меру, вос­ста­но­ви­тель паро­лей), он не смо­жет отсы­лать письма, пока «Поч­та­льон» не узнает, как пред­став­лять его в журналах.

У нас полу­чи­лась сла­бая связ­ность и силь­ное зацеп­ле­ние. Вики­пе­дия

Давайте изба­вимся от зацеп­ле­ния и доба­вим связ­но­сти — пусть все классы, кото­рые поль­зу­ются «Поч­та­льо­ном», сами пока­зы­вают, как их зовут. Возь­мём стан­дарт­ный для Питона и Джанго метод пере­вода объ­екта в строку:

class Order:
  ...
  def __str__(self):
    return f'Order {self.pk}'

​
class Chaser:
  ...
  def __str__(self):
    return f'Chaser for {self.order}'

​
class Mailman:
  ...    ​
  def log(self, subject, message):
    LogEntry.objects.create(sender_name=str(self.sender), subject=subject, message=message)

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

Теперь — хорошо: силь­ная связ­ность и сла­бое зацеп­ле­ние. Вики­пе­дия
P. S. Это был совет об управлении разработкой. Хотите больше знать о планировании спринтов, управлении продуктом или о настройке инфраструктуры? Присылайте вопросы.

Поделиться
Отправить

Комментарии

Андрей Захаров
6 марта 2020

Coupling и cohesion непросто перевести на русский. Мне лично самым удачным видится вариант из «Code Complete» МакКонела: coupling — связность, cohesion — согласованность.

В случае с cohesion основной смысл в том, что всё смотрит в одну точку, реализует единую концепцию. А семантическая связность тут уже вторична.

«Зацепление» вызывает ложные ассоциации с замыканием.


Цель рубрики — обсуждение вопросов дизайна всех видов, текста в дизайне и взаимоотношений дизайнеров с клиентами.

Мы публикуем комментарии, которые добавляют к уже сказанному новые мысли и хорошие примеры. Мы ожидаем, что такие комментарии составят около 20% от общего числа.

Решение о публикации принимается один раз; мы не имеем возможности комментировать или пересматривать свое решение, хотя оно может быть ошибочно. Уже опубликованные комментарии могут быть удалены через некоторое время, если без них обсуждение не становится менее ценным или интересным.

Вот такой веб 2.0.

Что делать, если меня, технического директора, потихоньку отстраняют от дел? Как написать аккуратный код? Часть третья: заменяемость Есть СТО, он классный, но при этом редко выходит в свет. Насколько, на твой взгляд, это может быть важно или полезно компании в целом? Как быть, если всё моё время уходит на разработку всё новых и новых фич? 1




Недавно всплыло

Что такое профессиональная этика? 5 1 Как работать в Фигме быстрее. Часть 3 1 Как разделать папайю 2