К написанию данной концепции меня побудила проблема, с которой я сталкивался раз за разом, приходя на новый проект: за 5 лет коммерческой разработки мне постоянно "везло" приходить на проект, с которого уходит ведущий разработчик. И каждый раз я унаследовал огромную базу кода — законы функционирования которого понимал лишь его создатель. Я же, в свою очередь, уже после первого года, приобрел привычку разработки через проектирование, а проектирование — через комментарии. Чем и хочу поделиться с вами под катом:
Парадигма разработки через комментирование
Idea. Comment-Design. Code. (IC-DC)
Идея.Проектирование через комментарии. Код.
- Идея
Инициатором идеи можете быть как вы, так и другой человек- например ваш ПМ(ТимЛид).
пример идеи: "Нужно очистить номер телефона от символов вроде '+,-, скобок и пробелов', так, чтобы на выходе получился только набор цифр. Фича нужна для реализации поиска по номеру телефона — введенного любым образом".
- Проектирование через комментарии
Написание комментариев с описанием логики работы программы.
пример проектирования через комментарии:
<?php
namespace App\Services;
use App\Entity\Users;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityManager;
class PhoneService
{
//Функция очистки телефона, принимает строку
//Перечислим символы которые нам нужно удалить из строки
//Очистим строку от символов
//Стандартизируем номер телефона, если в начале 8, то заменим ее на 7
//Вернем очищенный телефон
}
- Написание кода
Теперь нам необходимо преобразовать нашу коммент-проекцию в код:
пример:
<?php
namespace App\Services;
use App\Entity\Users;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\EntityManager;
class PhoneService
{
//Функция отчистки телефона, принимает строку
public function clear_phone(string $phone){
//Перечислим символы которые нам нужно удалить из строки
$symbols_for_delete = ['+','-','(',')', ' '];
//Очистим строку от символов
$phone = str_replace($symbols_for_delete, '', $phone);
//Стандартизируем номер телефона, если в начале 8, то заменим ее на 7
if( $phone[0] == '8' ){
$phone[0] = '7';
}
//Вернем очищенный телефон
return $phone;
}
}
Для чего это нужно
Зачем мне комментарии, код и так понятен?
Многие скажут что код и есть текст — и его легко прочитать. И я должен буду упомянуть что код — это метод изложения ваших мыслей, посредством синтаксиса используемого вами языка. И когда мы пишем сложную логику — мы используем свой, во многом уникальный стиль использования этого синтаксиса. Но если мы на этапе проектирования — опишем нашу логику на общепринятом языке, то и вернувшись к коду через 3 года поймем как он работает и наш код. Наследник, так же безболезненно сможет в нем разобраться. Использование проектирования через комментарии — уменьшает энтропию вашего проекта и делает код красивее.
Зачем мне нужно проектирование, я могу сесть и написать все сразу?
Если вы задаетесь этим вопросом — то вам просто необходимо, в срочном порядке, прочитать "Совершенный Код" Стив Макконнелл. Там данная концепция более чем раскрыта.
Приведу небольшую цитату:
На этапе проектирования кода обычно находятся 75% ошибок. Если бы их не нашлось — пришлось бы рефакторить.
И действительно, на этапе проектирования — вы можете понять, что задуманная бизнес-логика не будет работать, как планировалось, или вы можете увидеть лучший подход к решению той или иной задачи. И вам не нужно будет впоследствии возвращаться и рефакторить кусок логики — который работает не совсем так как было задумано.
Нужно ли мне комментировать все подряд?
Я привел элементарные примеры выше. Они полностью понятны и без комментариев, но я все равно использовал подход IC-DC при их реализации. Т.к. не хочу чтобы мой код обрастал энтропией. Я побывал на многих проектах, где большинство проектов приходилось переписывать с нуля именно по причине огромной энтропии в них. Задумайтесь — хотите ли вы, чтобы проект на который было потрачены месяцы или годы вашей жизни был просто стерт. Если ответ нет, тогда думаю стоит использовать этот подход всегда. Т.к. если вы уйдете с проекта или спустя несколько лет появится новая технология, которая сможет закрыть потребности лучше вашего старого решения — IC-DC поможет оптимально внедрить изменения, задевая минимум функционала, ведь новый сотрудник или новый вы: будете понимать, как и почему это работает.
Комментарии (64)
TheShock
15.12.2019 15:53+1Вы написали отличный пример мусорных комметариев, удалив которые можно значительно улучшить качество кода за счёт уменьшения его размера в два раза, убрав необходимость в синхронизации двух одинаковых блоков кода написанных зачем-то на разных языках.
TheShock
15.12.2019 16:01Кстати, улучшить вашу идею и убрать её недостатки можно заменив бесполезные комментарии на названия переменных, которые потом будут использоваться:
class PhoneService { //Функция очистки телефона, принимает строку //Перечислим символы которые нам нужно удалить из строки //Очистим строку от символов //Стандартизируем номер телефона, если в начале 8, то заменим ее на 7 //Вернем очищенный телефон } ===> public function clear_phone(string $phone) { $symbols_for_delate = ??; $cleared_phone = ??; $standarded_phone = ??; return $standarded_phone; }
Первый комментарий не нужен — он уже и так написан английским языком. Теперь нам надо вывести следующую переменную на базе предыдущей.
Думаю, это неплохой подход для всяких джунов, у которых ещё не собралось в голове понимание в кучу.
polar11beer
16.12.2019 11:02улучшить качество кода за счёт уменьшения его размера в два раза
Предлагаете измерять качество кода его размером? Ну так, спорная практика.
необходимость в синхронизации двух одинаковых блоков кода написанных зачем-то на разных языках.
Два разных языка — это Вы про собственно код и комментарии к нему? Так комментарии в любом случае должны соответствовать коду, на то их и пишут.TheShock
16.12.2019 21:34Предлагаете измерять качество кода его размером? Ну так, спорная практика.
Одна из метрик.
комментарии в любом случае должны соответствовать коду, на то их и пишут.
Ну это плохие комментарии.
Rsa97
15.12.2019 16:18$symbols_for_delate
Простите, функция действительно должна только очищать номер телефона?
Delate — доносить
Andy_U
15.12.2019 16:35Я лишь хотел бы отметить неудачное название функции «clear_phone». Лучше было бы что-то типа «cleanup_phone_number» или «standardize_phone_number». Ну и параметр переименовать тоже.
YemSalat
15.12.2019 17:35Тут много к чему можно придраться.
Вместо «standardize», больше подходит «normalise»
«symbols_for_delete» — неграмотно, надо «symbols_for_deletion» или «symbols_to_delete»
Кроме того, зачем-то есть список символов, которые нужно удалять. Что если придёт символ, которого нету в списке?
Почему просто не удалить «все что не цифра» регекспом?Andy_U
15.12.2019 19:26Что если придёт символ, которого нету в списке?
Генерировать ошибку?YemSalat
15.12.2019 20:56Текущее описание в «идея» нa это никак не намекает.
Если это был «простой пример» — то надо либо поменять код, либо «идею»
Иначе плохой пример.
Нужно очистить номер телефона от символов вроде '+,-, скобок и пробелов', так, чтобы на выходе получился только набор цифр. Фича нужна для реализации поиска по номеру телефона — введенного любым образом
chapuza
18.12.2019 13:09+1Текущее описание прямо намекает на то, что нужно удалять весь мусор, регуляркой
\D
.
YemSalat
15.12.2019 16:50Вы слышали что-нибудь про TDD?
По сути вы можете сначала написать тесты, в которых будет все возможное поведение вашей функции, затем уже саму имплементацию.VanKrock
15.12.2019 23:08+2Лично у меня так не получается писать, я несколько раз пробовал так делать, но у меня все равно не получается сначала учесть все ньюансы, а потом написать код. Обычно я пишу функцию, а потом пишу на нее несколько тестов, смотрю на них и на ум приходит еще несколько вариантов, из-за которых я вношу правки в функцию. То есть лично мне проще сначала подумать над алгоритмом как это должно работать в принципе, а потом подумать над ньюансами. Хотя справедливости ради мой код так часто переписывается, что с актуальностью многих тестов постоянно беда.
pdima
16.12.2019 01:09смотрю на них и на ум приходит еще несколько вариантов, из-за которых я вношу правки в функцию.
С TDD как раз подходящее время чтобы написать тест на новые случаи, проверить что он не проходит и написать реализацию.VanKrock
16.12.2019 14:38Для того, чтобы увидеть новые случаи я провожу в уме дебаг функции обдумывая каждую строчку на то, какие ньюансы тут могут произойти.
VolCh
16.12.2019 07:40Тесты тоже нужно документировать. Ну увижу я тест, из которого видно, что перед записью в базу номера из него удаляются пробелы. А зачем непонятно. Может место экономят, например.
Narical
16.12.2019 11:41Хорошо написанные тесты (вроде как) и есть документация. По ним нужно смотреть, какое поведение ожидается. А на вопросы «зачем» — отвечают внятные имена переменных и функций, и в целом контекст.
polar11beer
16.12.2019 10:53TDD показывает, что мы должны получить на выходе, в зависимости от того что пришло на вход, но никак не определяет как именно мы это получим. Описанный в статье подход, так называемый «псевдокод», как раз помогает проработать детали реализации. Т.е. TDD и псевдокод решают разные задачи.
Carduelis
15.12.2019 17:33Как уже некоторые отметили, такие комментарии действительно дублируют код. От таких комментариев (да еще и на другом языке) нужно избавляться.
Комментарии нужны, когда самодокументируемый код не справляется с заложенной там семантикой, и/или есть неочевидные способы решения, комментарии в таком случае должны подсказывать почему был выбран именно такой подход.
А от такого комментирования пользы никакой:
// модель пользователя class UserModel { // инициализуем constructor(id, name) {} // взять данные getData() {} // взять кешированные данные getCachedData() {} }
glagola
15.12.2019 17:40Я подобным образом приучаю своих разработчиков писать код, алгоритм также пошагово разбивается — 1 шаг это одна строка в комментариях, а потом каждый шаг превращается в 1 метод с нормальным говорящим названием. Таким образом получаем читаемый код, который не требует комментариев (функция получается 10-15 строчек). Таким образом пытаюсь выбить привычку, сначала в один метод накидать всю логику, добиться ее работоспособности, а потом начинать думать, а как же бы ее так разбить, чтобы код остался читаемым без комментариев.
YemSalat
15.12.2019 17:52Я подобным образом приучаю своих разработчиков писать код, алгоритм также пошагово разбивается — 1 шаг это одна строка в комментариях, а потом каждый шаг превращается в 1 метод с нормальным говорящим названием.
Почему сразу не писать названия методов, вместо комментариев?
glagola
15.12.2019 22:11+1Потому что алгоритмы формализуются, оптимизируются и обсуждаются на естественном человеческом языке, а уже потом переводятся в код.
Вся проблема в наименовании классов/методов/свойств в том чтобы назвать его так, чтобы без комментариев было понятно что происходит и при этом постараться сохранить терминологию во всем проекте, а не раздувать ее (например в одном месте используем user, в другом client, а подразумевается одно и тоже)ApeCoder
15.12.2019 22:56На codereview могут указать на неправильную терминологию. А переименовать ее достаточно легко — ide помогут.
VanKrock
15.12.2019 23:26+1Мне кажется, данные комментарии есть в названиях самих переменных, смысла их писать нет, если только вы не преподаватель по программированию для первых курсов. Есть смысл ставить комментарии только для того чтобы сказать пользователю о том что именно делает ваш метод или чтобы отметить особо сложный код, например сложную реализацию хеширования, желательно со ссылкой на страницу статью о данном алгоритме.
Я бы написал так:
//Приводит номер телефона к нормализованному виду. Пример: 79998889988 //$phone - номер телефона в виде: +7 (999) 888 99 88, 8-999-888-99-88 или 89998889988 public function normalize_phone(string $phone){ $symbols_for_delate = ['+','-','(',')', ' ']; $phone = str_replace($symbols_for_delate, '', $phone); if( $phone[0] == '8' ){ $phone[0] = '7'; } return $phone; }
TheShock
15.12.2019 23:39+2Кстати, в идеале эти комментарии тоже можно убрать, через типизацию аргумента и возврата. И практика и теория указывает, что багов будет намного меньше:
public function normalize_phone(UnnormalizedPhone $phone){ $symbols_for_delate = ['+','-','(',')', ' ']; $normalized = str_replace($symbols_for_delate, '', $phone->value); if( $normalized[0] == '8' ){ $normalized[0] = '7'; } return new NormalizedPhone($phone); }
VanKrock
15.12.2019 23:46+1Этот комментарий просто переедет к типам NormalizedPhone и UnnormalizedPhone, да и мы понимаем, что этот код только лишь для примера, если вы серьезно хотите поработать с номерами телефонов, то там все чуть сложнее.
pin2t
16.12.2019 11:34Если уж использовать классы, то логика нормализации должна быть внутри класса NormalizedPhone, а не в функции normalize_phone. Ибо инкапсуляция.
class NormalizedPhone { private $phone; public function __construct($phone) { $this->phone = $phone; } public function __toString() { $normalized = str_replace(['+','-','(',')', ' '], '', $this->phone); if( $normalized[0] == '8' ) $normalized[0] = '7'; return $normalized; } } echo new NormalizedPhone("+7(999)123-45-67");
akryukov
16.12.2019 15:06Почему у вас нормализация в __toString, а не в конструкторе? Так у вас при каждом преобразовании в строку будет выполняться нормализация. А если в конструкторе, то один раз — при создании.
Зачем вам в этом конкретном случае хранить сырое представление телефона?pin2t
16.12.2019 16:09Код в конструкторе это нехорошо. Конструктор он чтобы корректно создать объект, а не выполнять код.
Собстно можно и в конструктор перенести, моя основная мысль была не про это, а про то что если уж TheShock предлагает классы вместо функции, то надо их и использовать как классы, в смысле переделать функцию на классы, а не оставлять все вместе, и функцию и классTheShock
16.12.2019 18:45если уж TheShock предлагает классы вместо функции
Не обязательно. Я говорю о статической типизации. Она есть что в ФП, что в ООП
TheShock
16.12.2019 21:57Зачем вам в этом конкретном случае хранить сырое представление телефона?
Данные всегда лучше хранить сырыми. Если у вас есть проблемы с производительностью именно в этом методе — всегда можно кешировать результат. Единственно, конечно, в том примере toString — неудачное использование метода. На TS можно было бы сделать как-то так, а если, вдруг, будут проблемы с производительностью — раскомментировать мемоайз:
const NotNumberRegexp = /[^\d]/g; class NormalizedPhone { constructor ( public readonly value: number ){} } class UnnormalizedPhone { constructor ( public readonly value: string ){} // @memoize get normalized () { let normalized = this.value.replace(NotNumberRegexp, ''); if (normalized[0] == '8') { normalized = '7' + normalized.substr(1); } return new NormalizedPhone(Number(normalized)); } } console.log(new UnnormalizedPhone("+7(999)123-45-67").normalized)
Так же можно сделать в функциональном стиле, но без брендинга будут проблемы с типизацией (хотя это особенности реализации TS):
const NotNumberRegexp = /[^\d]/g; type UnnormalizedPhone = string; type NormalizedPhone = number; function normalizePhone (phone: UnnormalizedPhone) { const cleared = phone.replace(NotNumberRegexp, ''); const normalized = cleared[0] == '8' ? ('7' + cleared.substr(1)) : cleared; return Number(normalized) as NormalizedPhone; } var normalizedPhone = normalizePhone("+7(999)123-45-67" as UnnormalizedPhone) console.log(normalizedPhone);
Конечно, возле `type UnnormalizedPhone
` теперь нужно в комментарии описать, что он содержит. Но не в каждой функции, которая ожидает `UnnormalizedPhone
` или `NormalizedPhone
`
pin2t
16.12.2019 11:25Можно ещё упростить, если убрать ненужную переменную с длинным названием
//Приводит номер телефона к нормализованному виду. Пример: 79998889988 //$phone - номер телефона в виде: +7 (999) 888 99 88, 8-999-888-99-88 или 89998889988 public function normalize_phone(string $phone){ $phone = str_replace(['+','-','(',')', ' '], '', $phone); if( $phone[0] == '8' ) $phone[0] = '7'; return $phone; }
akryukov
16.12.2019 15:08Не путайте уменьшение количества кода и упрощение.
Убирание объясняющих переменных уменьшает количество кода, но не упрощает функции.pin2t
16.12.2019 16:16Вот такая переменная $symbols_for_delate нафик ненужна, слишком длинная, мало что объясняет и используется ровно в одном месте. Ещё и с ошибкой написана.
polar11beer
16.12.2019 21:19Мне кажется, что некоторые читатели слишком буквально восприняли идею использовать псевдокод вообще всегда, включая написание функции в три строчки.
Псевдокод хорош когда логика заковыристая, и метод строк на 50...100 и больше. Резонное замечание — в таких случаях применяют декомпозицию. Да, естественно. Но с псевдокодом сделать декомпозицию, поправить интерфейсы, дата-контракты и архитектуру классов можно ещё до того, как начали собственно писать код, а не тогда когда написали и решили что «получается как-то сложновато, надо порефакторить».
При использовании псевдокода никто не заставляет писать код построчно под каждым комментарием, равно как и оставлять комментарии к коду, который самоочевиден. Это вообще не серебряная пуля, а инструмент, который надо применять с умом. Как молоток — хорошая штука, но надо уметь использовать, если не хочешь бить по пальцам.
Автор не привёл примера посложнее, хотя не помешало бы, и тему не очень раскрыл. Но это не значит, что псевдокод плохая штука.
А насчёт «хороший код в комментариях не нуждается» — ну, это хороший, а на практике работать приходится с разным, да и свой получается не всегда идеальным, чего уж там.
Всем добра!TheShock
16.12.2019 21:58А насчёт «хороший код в комментариях не нуждается» — ну, это хороший, а на практике работать приходится с разным, да и свой получается не всегда идеальным, чего уж там.
А на практике люди, которые пишут плохой код — комментарии пишут ещё хуже
VanKrock
18.12.2019 16:24У автора проблема в том, что он оставил в конечном варианте плохие комментарии. Если бы автор сначала написал комментарии, а потом написал по ним код и удалил комментарии, то возможно никто бы ничего не сказал. А самое главное, что нужного комментария как раз нет, который бы описывал то, что именно делает функция. Из комментария не понятно, что за очистка телефона такая. То есть в конечном варианте автор оставил не нужные комментарии и не оставил нужных.
atomicus
16.12.2019 00:19Абстрагируясь от технических деталей приведенного в статье примера, не совсем понятно почему достаточно известный "Процесс программирования с псевдокодом (ППП)" (Глава 9, "Совершенный код" С. МакКоннелла) заменен на "Парадигму разработки через комментирование. Idea. Comment-Design. Code. (IC-DC)"?
Если вы задаетесь этим вопросом — то вам просто необходимо, в срочном порядке, прочитать "Совершенный Код" Стив Макконнелл. Там данная концепция более чем раскрыта.
Вдвойне странно, что автор статьи упоминает эту книгу. То есть по сути вместо этого можно было сослаться на конкретную главу в книге (тем более там описан не только сам подход, но и указаны его альтернативы). А также детальнее проработать сам пример примения с технической точки зрения (как минимум добавив методам и переменным более выразительные имена) или найти более подходящий пример где комментарии не являются избыточными и несут дополнительный смысл.
BugM
16.12.2019 00:22+1Принцип что комментарий должен описывать почему этот код такой, а не что он делает забыт?
Зачем описывать простейший алгоритм комментарием? Код это сделает надежнее и понятнее. А вот написать:
//Обрабатываем только форматы +7(999)123-45-67 и 8(999)123-45-67 на все остальное кидаем исключение, т.к. пользователи вводят чушь которую мы успешно интерпретируем как телефон и потом возникают проблемы. (ссылока не тикет с таким случаем)
имеет смыслOvervoid Автор
16.12.2019 11:27Да, я согласен. Данный комментарий очень информативен, но тогда мы не будем использовать проектирование через комментарии.
P.S. ох если бы подобные комментарии существовали хотя бы на одном проекте унаследованном мной. Наверное я был бы очень счастлив и подобной статьи бы не случилось :)
411
16.12.2019 00:29+1У нас так лабы в универе сдавали те, кто очень плохо в программирование умел.
В остальном выглядит как вредные советы. Если в теле функции нужны комментарии, то это скорей всего признак того, что код нужно переписать. Во всех остальных редких случаях это действительно сложная и/или специфичная логика, требующая пояснений.
Ну а про вариант с псевдокодом уже выше упоминали.
DmitryKoterov
16.12.2019 01:47+2(Все — ИМХО.) Комментарии в коде — это следствие одной из трех вещей (а часто комбинация):
1. Боязнь получить вопросы на код-ревью (часто — от ревьюверов, которые недостаточно заинтересованы, чтобы чуть подразобраться, прежде чем спрашивать). Т.е. как бы превентивный ответ на эти [бесполезные?] вопросы.
2. Бедное именование переменных/методов. Если с именованием все в порядке, то комментарии чаще всего не нужны.
3. Отсутствие нормального покрытия тестами, т.е. «боязнь регрессии» («кто-нибудь придет потом и натопчет тут, все сломает»).
За скобками также бедная архитектура (простой код не нуждается в комментариях, а сложного кода почти никогда не бывает при хорошей архитектуре), но это из разряда «лучше быть богатым и здоровым чем бедным и больным» или «ломиться в открытую дверь».VolCh
16.12.2019 07:46- Практика показывает, что комментарии или имена, говорящие зачем мы что-то делаем, нужны или в коде, или в тестах, а лучше и там, и там. Тот кто удаляет "ненужный" код, удалит или поправит и "ненужный" тест
chapuza
18.12.2019 13:42от ревьюверов, которые недостаточно заинтересованы, чтобы чуть подразобраться
Если ревьюеру нужно «подразбираться» — дело швах, есть там комментарии, или их нет.
sergeevik
16.12.2019 01:52Как первоначальное описание идея хорошая, но комментарии имеют свойство устаревать, или хуже, когда комментарий поменяли, а логику нет. Конечно это может отлавливатся на ревью, но все ошибаются.
Так же такой подход может спровоцировать длинные методы. Из-за комментариев сложно будет уследить за длинной самого метода и пропорций код/комментарии.
Это действительно полезно на этапе проектирования, но потом должно уходить в документацию (конфлюенс/javadoc)
mcroitor
16.12.2019 10:09+1В защиту автора. Ещё ни разу не видел коммерческий код, который документировал бы сам себя. Вероятно, что мне не везло. А вообще, смысл статьи не в том, чтобы писать комментарии, а в том, чтобы их написать ДО кодирования. Сформировать идею. Если вам так мешают комментарии, по окончанию можете их удалить.
Overvoid Автор
16.12.2019 11:18Да, вы абсолютно верно поняли.
Увидев тут, здравые замечания — я скорее всего реализую возможность ведения коммент базы- для тех кому они мешают непосредственно в коде.
Над реализацией еще подумаю — но сама идея будет заключаться в удалении комментариев из кода, с последующим хранением их в базе(например в файловой yaml_db), по команде из терминала. Ну и соответственно возвратом их в код, по команде.ghost404
17.12.2019 00:16А что, система контроля версий уже не канает как база для хранения комментариев к измеренному коду?
ssv32
16.12.2019 15:15Когда то может пару раз тоже так делал и сейчас в урезанном виде наверно использую, на каких то сложных задачах (для меня), это упрощало работу, теперь буду знать как это называется).
Например делаю класс и комментариями пишу методы какие нужны (что должны получить или сделать), к некоторым методам приписываю какие внутри должны вызываться, это помогает например если за день всё не можешь сделать на следующий день будет ясно что нужно реализовать и общий план по коду.
Мне кажется у автора просто пример слишком простой, а вообще такой метод для меня полезен.
Что бы не переписывать с нуля, портянку старого чужого кода, бывает просматриваю по кускам и сам добавляю комментарии, если задача делается не один день то это полезно, пришел на другой день ещё пересмотрел код закомментировал, а потом в итоге можно сказать чужой код становится твоим.
khajiit
16.12.2019 22:54Список кодов по странам
А теперь угадайте, что сделает этот код?
//Перечислим символы которые нам нужно удалить из строки $symbols_for_delete = ['+','-','(',')', ' ']; //Очистим строку от символов $phone = str_replace($symbols_for_delete, '', $phone); //Стандартизируем номер телефона, если в начале 8, то заменим ее на 7 if( $phone[0] == '8' ){ $phone[0] = '7'; }
Правильный ответПоломает все номера из азиатского региона.
Потому что нельзя сперва отбросить часть условного префикса переменной длины, а потом сделать абсолютную замену первого символа.ghost404
18.12.2019 11:54+1Так просто заменять 8 на 7 неправильно. Надо понимать, что за этим стоит.
8-10-7-903-XXX-XX-XX
8 — выход на междугороднюю связь
10 — выход на международную связь
7 — код страны
903 — код города или оператора
XXX-XX-XX — телефонный номер абонента
Для упращения код 810 заменили на +.
Таким образом, номер с +7 это полный международный номер, а номер начинающийся на 8 это номер в пределах страны. Для Греции например код страны 30 и звонить можно как по номеру 81030… так и по +30… И соответственно, если пользователь ПО в Греции, то 8 должно заменятся на +30, а не на +7.
Daddy_Cool
Я замечал, что есть героические люди которые могут просто сходу поправить свой код написанный и заброшенный… пару лет назад. Я же как-то дошел до того, что утром не мог понять, что я накодил вчера. ))) И да — комментарии для самого себя стали спасением.
Проблема что некоторые не любят комменты видимо банальна — если это относится к рабочим процессам — то проект сдан, или программист уволился — и это не его проблемы. А если к собственным проектам — то и так всё в голове пока есть интерес.
Думаю в open source сообществах дело с комментами должно обстоять лучше — но сам опыта такого не имею, было бы интересно если бы кто-то написал как там на самаом деле.
Magikan
так посмотрите на гихабе любой интересный Вам проект и сразу все станет понятно )
chapuza
Вот интересный мне проект, например:
Elixir
(ссылка просто на первый файл, там везде так).Скажете «ну это же целый язык!»? Ну вот ссылка уже на мою библиотеку, тоже случайный файл.
Что должно быть понятно?