Семинар ФКН: современные подходы к разработке ПО - часть 2
1. СОВРЕМЕННЫЕ
ПОДХОДЫ К РАЗРАБОТКЕ
ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ
ХАРЬКОВСКИЙ НАЦИОНАЛЬНЫЙ УНИВЕРСИТЕТ ИМЕНИ В. Н. КАРАЗИНА
ФАКУЛЬТЕТ КОМПЬЮТЕРНЫХ НАУК
КАФ. ИСКУССТВЕННОГО ИНТЕЛЛЕКТА И ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ
К.Ф.М.Н., ДОЦ. КАФ. ИСКУССТВЕННОГО ИНТЕЛЛЕКТА И ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ
ГАХОВ АНДРЕЙ ВЛАДИМИРОВИЧ
4. Однострочные комментарии
Для кратких комментариев к
отдельным частям кода.
// quick check to see if we can acquire a lock, otherwise spawn to a thread pool
if (mdLock.tryAcquire()) {
createIndex(request, userListener, mdLock);
return;
}
while((phraseInfo = queue.top()) != null) { // pull until we crossed the spanEnd
if (phraseInfo.getEndOffset() > spanEnd) {
break;
}
}
5. Многострочные комментарии
Для длинных и подробных объяснений.
def luhn(candidate):
"""
Checks a candidate number for validity according to the Luhn
algorithm (used in validation of, for example, credit cards).
Both numeric and string candidates are accepted.
"""
if not isinstance(candidate, six.string_types):
candidate = str(candidate)
try:
evens = sum([int(c) for c in candidate[-1::-2]])
odds = sum([LUHN_ODD_LOOKUP[int(c)] for c in candidate[-2::-2]])
return ((evens + odds) % 10 == 0)
except ValueError: # Raised if an int conversion fails
return False
6. Общепринятые теги
FIXME – потенциальная проблема,
требующая специального внимания.
NOTE – замечание относительно кода
и объяснение «подводных камней».
TODO – описание возможных
будущих улучшений кода.
XXX – предупреждение о
проблематичном или «грязном» коде.
7. Общепринятые теги - примеры
public class ShapeModule extends AbstractModule {
@Override
protected void configure() {
// TODO: We could wrap this entire module in a JTS_AVAILABILITY check
if (ShapesAvailability.JTS_AVAILABLE) {
bind(ShapeFetchService.class).asEagerSingleton();
}
}
}
if not (isinstance(index, basestring)):
# FIXME: not sure what to do here, but we only want one
# index and somehow this isn't one index.
index = index[0]
return index
8. Читабельность
Комментарии пишутся для людей.
Лучше не оставить комментарий, чем
оставить плохой комментарий.
Комментарии для объяснений
намерений программиста.
Для объяснения того, что делает код
используйте правильное именование
и понятную логическую структуру.
9. Визуальное выделение
Не надо недооценивать значимость
пробелов и визульного выделения.
Используйте один из стандартных
стилей для вашего языка
программирования.
Например: javadoc, docstring
10. Во время кодирования
Пишите комментарии во время
написания кода, а не после.
При изменении кода не забывайте
изменять или дополнять
соотвествующие комментарии.
11. Полезные советы
Сделайте паузу и подумайте прежде,
чем писать комментарий.
Спросите себя, что для вас самое
непонятное в коде.
Объясните проблему самым простым
образом и с минимальным числом
слов.
13. Именование
Используйте адекватные по длине
имена.
Например: «i» для индекса цикла,
«hostName» для переменной и
«TransportSearchModule» для класса.
Используйте осмысленные имена.
Например: dbName, lastAccessId и т.п.
14. Именование
Используйте только один язык для
именования (обычно, английский).
Не используйте в именах символы,
отличные от ASCII, даже если язык
программирования это позволяет.
16. Именование в Java
Используйте Lower Camel Case для
переменных, методов и аргументов.
Например: filterChain, getName,
setSchoolName(String schoolName)
Используйте Upper Camel Case для
именования классов.
Например: HttpServerAdapter
17. Именование в Java
Используйте заглавные буквы для
констант.
Например: DEFAULT_MIME_TYPES,
static final int DEFAULT_WIDTH
Используйте строчные буквы для
имен пакетов.
Например: com.google.common.collect
18. Именование в Python
Используйте символ «_» в начале
имен для private полей и методов,
классов и функций для внутреннего
пользования.
Используйте Upper Camel Case для
именования классов.
Например: HttpServerAdapter
19. Именование в Python
Используйте заглавные буквы для
констант.
Например: DEFAULT_MIME_TYPES
Используйте строчные буквы для
имен переенных, функций и методов,
разделяя слова знаком «_».
Например: db_name, get_connection
20. Именование переменных
Имена вида «value», «equals», «data»
в большинстве случаев не верны.
Имя переменной должно определять
ее содержание.
Не включайте в имя переменной
инфрмацию о типе.
21. Именование переменных
Переменная не нуждается в
приставках и суффиксах,
показывающих, что это переменная.
Например: «o_», «obj_», «m_» и т.п.
Не включайте в имя переменной
информацию о типе.
Например: studentNameString
22. Именование переменных
Не используйте зарезервированные
имена, даже если язык
программирования это позволяет.
Не используйте символы «l» (L в
нижнем регистре), «I» (i в верхнем
регистре) и «O» (буква О) в качестве
самостоятельных переменных.
23. Именование переменных
Не используйте без необходимости
очень длинные имена переменных.
Не используйте одно и то же имя в
разных контекстах в одной и той же
области видимости.
24. Именование методов и функций
В большинстве случаев, начинайте
имя с глагола.
Например: createPassword, getName,
addPermissions, isPasswordValid,
setAge, updateEmail, deleteAccount
Имя должно определять действие,
выполняемое данным методом или
функций.
25. Именование методов и функций
Имена должны описывать все
действия (в том числе и «побочные»).
Например: getOrCreate
Имена методов должны отвечать
уровню абстракции класса.
Например: для класса Modem имеет
смысл иметь метод connect(), но не
call().
26. Именование классов
Имя должно быть существительным
в единственном числе (но может
включать так же и прилагательные).
Например: Account, BasicInterface
Испольуйте по-возможности
стандартные ключевые слова.
Например: «Interface», «Context»,
«Module» и т.п.
28. Обработка исключений
Используйте текты сообщений об
ошибках, понятные пользователю.
Не включайте в сообщения об
ошибках данные, являющиеся
персональными (например, пароли
или номера кредитнх карт), даже если
вы выводите их только в log-файлы.
30. Обработка исключений
Обрабатывайте только исключения,
которые вы должны обработать.
Используйте глобальные обработчики
исключений для обработки всех
необработанных исключений в
программе и вывода общего
сообщения об ошибке. Не забывайте
освобождать ресурсы.
31. Обработка исключений
Не используйте исключения для
контроля за потоком выполнения:
static Boolean IsProductExists(string ProductId)
{
//... search for the Product
if ( dr.Read(ProductId) == 0 ) // no record found
{
throw(new Exception("Product Not found"));
}
return true;
}
32. Обработка исключений
Отсутствие продукта не является
здесь исключительной ситуацией.
Имя функции предполагает наличие
возвращаемого значения (false в
данном случае).
Генерация исключения как правило
намного медленнее, чем возвращение
значения.
34. Д. Кнут, «Structured Programming with
go to Statements», 1974
Преждевременная оптимизация
— корень всех зол.
Premature optimization is the root
of all evil.
35. Правила оптимизации
Make it clear before you make it fast
Make it correct before you make it fast
«Elements Of Programming Style», Brian Kernighan, P. Plauger, 1978