Семинар ФКН: современные подходы к разработке ПО -...

Preview:

DESCRIPTION

Рассматриваются вопросы создания "чистого кода"

Citation preview

СОВРЕМЕННЫЕПОДХОДЫ К РАЗРАБОТКЕПРОГРАММНОГО ОБЕСПЕЧЕНИЯ

ХАРЬКОВСКИЙ НАЦИОНАЛЬНЫЙ УНИВЕРСИТЕТ ИМЕНИ В. Н. КАРАЗИНАФАКУЛЬТЕТ КОМПЬЮТЕРНЫХ НАУК

КАФ. ИСКУССТВЕННОГО ИНТЕЛЛЕКТА И ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ

К.Ф.М.Н., ДОЦ. КАФ. ИСКУССТВЕННОГО ИНТЕЛЛЕКТА И ПРОГРАММНОГО ОБЕСПЕЧЕНИЯГАХОВ АНДРЕЙ ВЛАДИМИРОВИЧ

ЧИСТЫЙ КОДClean Code

КОММЕНТАРИИ

Comments

Однострочные комментарии

Для кратких комментариев котдельным частям кода.

// quick check to see if we can acquire a lock, otherwise spawn to a thread poolif (mdLock.tryAcquire()) {

createIndex(request, userListener, mdLock);return;

}

while((phraseInfo = queue.top()) != null) { // pull until we crossed the spanEndif (phraseInfo.getEndOffset() > spanEnd) {

break;}

}

Многострочные комментарии

Для длинных и подробных объяснений.def luhn(candidate):

"""Checks a candidate number for validity according to the Luhnalgorithm (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 failsreturn False

Общепринятые теги

FIXME – потенциальная проблема,требующая специального внимания.

NOTE – замечание относительно кодаи объяснение «подводных камней».

TODO – описание возможныхбудущих улучшений кода.

XXX – предупреждение опроблематичном или «грязном» коде.

Общепринятые теги - примерыpublic class ShapeModule extends AbstractModule {

@Overrideprotected void configure() {

// TODO: We could wrap this entire module in a JTS_AVAILABILITY checkif (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

Читабельность

Комментарии пишутся для людей.

Лучше не оставить комментарий, чемоставить плохой комментарий.

Комментарии для объясненийнамерений программиста.

Для объяснения того, что делает кодиспользуйте правильное именованиеи понятную логическую структуру.

Визуальное выделение

Не надо недооценивать значимостьпробелов и визульного выделения.

Используйте один из стандартныхстилей для вашего языкапрограммирования.Например: javadoc, docstring

Во время кодирования

Пишите комментарии во времянаписания кода, а не после.

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

Полезные советы

Сделайте паузу и подумайте прежде,чем писать комментарий.Спросите себя, что для вас самоенепонятное в коде.Объясните проблему самым простымобразом и с минимальным числомслов.

ИМЕНОВАНИЕ

Naming

Именование

Используйте адекватные по длинеимена.Например: «i» для индекса цикла,«hostName» для переменной и«TransportSearchModule» для класса.

Используйте осмысленные имена.Например: dbName, lastAccessId и т.п.

Именование

Используйте только один язык дляименования (обычно, английский).

Не используйте в именах символы,отличные от ASCII, даже если языкпрограммирования это позволяет.

Именование

Соблюдайте общепринятыестандарты именования для вашегоязыка программирования.

Будьте последовательны приименовании.

Именование в Java

Используйте Lower Camel Case дляпеременных, методов и аргументов.Например: filterChain, getName,setSchoolName(String schoolName)

Используйте Upper Camel Case дляименования классов.Например: HttpServerAdapter

Именование в Java

Используйте заглавные буквы дляконстант.Например: DEFAULT_MIME_TYPES,static final int DEFAULT_WIDTH

Используйте строчные буквы дляимен пакетов.Например: com.google.common.collect

Именование в Python

Используйте символ «_» в началеимен для private полей и методов,классов и функций для внутреннегопользования.

Используйте Upper Camel Case дляименования классов.Например: HttpServerAdapter

Именование в Python

Используйте заглавные буквы дляконстант.Например: DEFAULT_MIME_TYPES

Используйте строчные буквы дляимен переенных, функций и методов,разделяя слова знаком «_».Например: db_name, get_connection

Именование переменных

Имена вида «value», «equals», «data»в большинстве случаев не верны.

Имя переменной должно определятьее содержание.

Не включайте в имя переменнойинфрмацию о типе.

Именование переменных

Переменная не нуждается вприставках и суффиксах,показывающих, что это переменная.Например: «o_», «obj_», «m_» и т.п.

Не включайте в имя переменнойинформацию о типе.Например: studentNameString

Именование переменных

Не используйте зарезервированныеимена, даже если языкпрограммирования это позволяет.

Не используйте символы «l» (L внижнем регистре), «I» (i в верхнемрегистре) и «O» (буква О) в качествесамостоятельных переменных.

Именование переменных

Не используйте без необходимостиочень длинные имена переменных.

Не используйте одно и то же имя вразных контекстах в одной и той жеобласти видимости.

Именование методов и функций

В большинстве случаев, начинайтеимя с глагола.Например: createPassword, getName,addPermissions, isPasswordValid,setAge, updateEmail, deleteAccount

Имя должно определять действие,выполняемое данным методом илифункций.

Именование методов и функций

Имена должны описывать вседействия (в том числе и «побочные»).Например: getOrCreate

Имена методов должны отвечатьуровню абстракции класса.Например: для класса Modem имеетсмысл иметь метод connect(), но неcall().

Именование классов

Имя должно быть существительнымв единственном числе (но можетвключать так же и прилагательные).Например: Account, BasicInterface

Испольуйте по-возможностистандартные ключевые слова.Например: «Interface», «Context»,«Module» и т.п.

ИСКЛЮЧЕНИЯ

Exceptions

Обработка исключений

Используйте текты сообщений обошибках, понятные пользователю.

Не включайте в сообщения обошибках данные, являющиесяперсональными (например, паролиили номера кредитнх карт), даже есливы выводите их только в log-файлы.

Обработка исключений

Используйте нестандартныеисключения только при крайнейнеобходимости.При создании классов нестандартныхисключений давайте им само-определяющие имена.Например: RateLimitException

Обработка исключений

Обрабатывайте только исключения,которые вы должны обработать.

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

Обработка исключений

Не используйте исключения дляконтроля за потоком выполнения:

static Boolean IsProductExists(string ProductId){

//... search for the Productif ( dr.Read(ProductId) == 0 ) // no record found{

throw(new Exception("Product Not found"));}return true;

}

Обработка исключений

Отсутствие продукта не являетсяздесь исключительной ситуацией.Имя функции предполагает наличиевозвращаемого значения (false вданном случае).

Генерация исключения как правилонамного медленнее, чем возвращениезначения.

ПРАВИЛА ОПТИМИЗАЦИИ

Rules of optimization

Д. Кнут, «Structured Programming withgo to Statements», 1974

Преждевременная оптимизация— корень всех зол.

Premature optimization is the rootof all evil.

Правила оптимизации

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

Recommended