Автор книги: Алексей Лот
Жанр: Языкознание, Наука и Образование
Возрастные ограничения: +12
сообщить о неприемлемом содержимом
Текущая страница: 2 (всего у книги 10 страниц) [доступный отрывок для чтения: 3 страниц]
Горизонтальное выравнивание не применяется.
Отступы выделяют области видимости.
Не применяются вырожденные области видимости.
Группа разработчиков согласует единый стиль форматирования.
Код продукта оформлен в едином стиле.
Внешний пользователь не в курсе деталей реализации.
Методы интерфейса устанавливают политику доступа к данным.
Классами предоставлены абстрактные интерфейсы, посредством которых пользователь оперирует с сущностью данных.
Пользователь не имеет представления о фактическом формате данных.
Объекты скрывают свои данные за абстракциями и предоставвляют функции, работающие с этими данными.
Структуры данных раскрывают свои данные и не имеют осмысленных функций.
Процедурный код (код, использующий структуры данных) позволяет легко добавлять новые функции без изменения существующих структур данных.
ООП-код упрощает добавление новых классов без изменения существующих функций.
Процедурный код усложняет добавление новых структур данных, так как требуется изменение всех функций.
ООП-код усложняет добавление новых функций, так как требуется изменение всех классов.
Данные необязательно представляются в виде объектов.
Закон Деметры – модуль не должен знать внутреннее устройство объектов, с которыми работает.
Метод f класса С должен ограничиваться вызовом методов следующих объектов: С; объекты, созданные f; объекты, переданные f в качестве аргумента; объекты, хранящиеся в переменной экземпляра С.
Метод не должен вызывать методы объектов, возвращаемых любыми из разрешенных функций.
Не использовать цепочки вызовов (разделять).
Не используются гибриды объектов и структур данных.
Разные уровни детализации не смешиваются.
Объекты передачи данных – Data transfer object – классы с открытыми переменными без функций используются для преобразования низкоуровневых данных, получаемых из базы, в объекты кода приложения.
Bean – компоненты из приватных переменных, операции с которыми осуществляются при помощи методов чтения и записи, преимуществ не имеют.
Активные записи – active records – структуры данных с открытыми переменными, а также с навигационными методами – это структуры данных и бизнес-логику не содержат.
Обработка ошибок не заслоняет логику программы.
Ошибки обрабатываются стильно и элегантно.
Используются исключения вместо кодов ошибок.
Начинать с написания команды try-catch-finally для кода, способного вызывать исключение.
Тип исключения сужается до реально инициируемого.
Блоки try должны напоминать транзакции.
Использовать непроверямые исключения.
С исключениями передавать содержательные сообщения об ошибках.
Из сведений об исключении должно быть понятно, с какой целью выполнялась операция.
Классы исключений определены в контексте потребностей вызывающей стороны.
Инкапсулированы вызовы сторонних API.
Для обработки особых случаев использовать паттерн особый случай.
Вместо null выдается исключение или особый случай.
Для API, возвращающего null, – делать обертки.
Не возвращать null из методов.
Не передавать null при вызове методов.
Запрещать передачу null по умолчанию.
Чистый код должен быть надежным.
Вместо приведения типа контейнера лучше использовать параметризованные контейнеры.
Ограничить передачу граничных интерфейсов по платформе (можно инкапсулировать).
Для стороннего кода писать тесты.
Сторонний код тестировать в рамках понимания его работы.
Конструкторы по умолчанию должны иметь конфигурацию.
Писать учебные тесты, граничные тесты.
Можно заранее определять интерфейсы, затем писать паттерн-адаптер к готовым.
Для граничного кода необходимо четкое разделение сторон и тесты, определяющие ожидания пользователя.
Количество обращений к границам стороннего кода сводится к минимуму.
Законы TDD:
– не пишите код продукта, пока не напишете отказной модульный тест;
– не пишите модульный тест в объеме большем, чем необходимо для отказа (невозможность компиляции является отказом);
– не пишите код продукта в объеме большем, чем необходимо для прохождения текущего отказного теста.
Тесты не уступают в качестве коду продукта.
Тесты развиваются вместе с продуктом.
Модульные тесты обеспечивают гибкость, удобство сопровождения и возможность повторного использования кода.
Без тестов любое изменение становится потенциальной ошибкой.
Некачественные тесты приводят к некачественному коду продукта.
Чистый тест характеризуется удобочитаемостью: ясностью, простотой и выразительностью.
В тестах использовать паттерн «построение – операции – проверка».
Тесты не делают ничего лишнего, в них используются только действительно необходимые типы и функции.
Использовать наборы функций и служебных программ, использующих API.
Код тестов не такой эффективный, как код продукта.
Чтобы избежать дублирования, можно воспользоваться паттерном шаблонный метод.
Не более 1 assert в функции теста.
Одна концепция в тесте (1 тест – 1 проверка).
Характеристики чистых тестов:
– тесты должны выполняться быстро;
– тесты не зависят друг от друга;
– тесты дают повторяемые результаты в любой среде.
Результатом выполнения теста должен быть логический признак (результат очевиден).
Тесты создаются своевременно непосредственно перед кодом продукта.
Класс должен начинаться со списка переменных.
Сначала перечисляются открытые статические константы.
Далее следуют приватные статические переменные.
За ними идут приватные переменные экземпляров.
Затем открытые функции.
Приватные вспомогательные функции, вызываемые открытыми функциями, непосредственно за самой открытой функцией (газетная статья).
Открытые переменные обычно не используют.
Предпочтительно объявлять переменные и вспомогательные функции приватными.
Иногда переменную или вспомогательную функцию приходится объявлять защищенной, чтобы иметь возможность обратиться к ней из класса.
Ослабление инкапсуляции должно быть последней мерой.
Классы должны быть максимально компактными.
Компактность класса определяется его ответственностью.
По имени класса можно определить его размер.
Краткое описание класса должно укладываться в 25 слов, без выражений «если», «и», «или», «но».
Принцип единой ответственности: SRP – класс или модуль должен иметь одну и только одну причину для изменения (одну ответственность).
Система должна состоять из множества мелких классов со сформированной структурой.
Класс взаимодействует с другими классами для реализации желаемого поведения системы.
Классы должны иметь небольшое количество переменных экземпляров.
Чем с большим числом переменных работает метод, тем выше связность этого метода со своим классом. Создавать классы с высокой связностью не рекомендуется.
Высокая связность означает, что методы и переменные класса взаимозависимы.
Рост числа переменных экземпляров свидетельствует о необходимости выделения класса.
Рефакторинг может удлинить программу.
Приватные методы, действие которых распространяется на небольшое подмножество класса, – признак возможности усовершенствований.
Структурирование проводится с учетом изменений.
Время, необходимое для понимания класса, падает почти до нуля.
Вероятность того, что одна из функций нарушит работу другой, ничтожно мала.
Принцип открытости-закрытости: классы должны быть открыты для расширений, но закрыты для модификации.
Структура системы должна быть такой, чтобы обновление системы создавало как можно меньше проблем.
В идеале новая функциональность должна реализовываться расширением системы, а не внесением изменений в существующий код.
С помощью интерфейсов и абстрактных классов класс изолируется от конкретных подробностей.
Принцип обращения зависимостей: классы системы должны зависеть от абстракций, а не от конкретных подробностей.
В программных системах фаза инициализации, в которой конструируются объекты приложения и «склеиваются» основные зависимости, должна отделяться от логики времени выполнения, получающей управление после ее завершения.
Инициализация – область ответственности.
Код инициализации пишется системно и отделен от логики времени выполнения.
Удобные идиомы не ведут к нарушению модульности.
Приложение ничего не знает о main или о процессе конструирования.
Все аспекты конструирования помещаются в main или в модули, вызываемые из main.
Если момент создания объекта должен определяться приложением, то использовать паттерн «Фабрика».
Вся информация о конструировании хранится на стороне main.
Приложение изолировано от подробностей построения.
Использовать внедрение зависимостей Dependency Injection или обращение контроля Inversion of Control для отделения конструирования от использования.
Итеративная разработка – сегодня реализуем текущие потребности, а завтра перерабатываем и расширяем систему для реализации новых потребностей.
Архитектура программных систем может развиваться последовательно, если обеспечить правильное разделение ответственности.
Компонент-сущность (entity bean) – представление реляционных данных в памяти.
Применять АОП – модульные конструкции, называемые аспектами, определяют, в каких точках системы поведение должно меняться некоторым последовательным образом в соответствии с потребностями определенной области ответственности (изменения вносит инфраструктура без необходимости вмешательства в целевой код).
Посредники (proxies) хорошо подходят для простых ситуаций – вызова методов отдельных объектов или классов.
Использовать POJO-объекты.
DAO – Data accessor object – объект доступа к данным.
Использовать aspectJ.
Не полагаться на BDUF.
На каждом уровне абстракции архитектура должна оставаться простой и обладать минимальными привязками.
Хороший API должен исчезать из вида большую часть времени.
Один человек не может принять все необходимые решения.
Принятие решений лучше всего откладывать до последнего момента.
Стандарты применяются разумно, когда они приносят очевидную пользу.
Главная задача – реализовать интересы клиента.
Использовать DSL (их код читается как структурированная форма текста, написанного экспертом в данной предметной области).
Используйте самое простое решение из всех возможных.
Четыре правила простой архитектуры:
– архитектура обеспечивает прохождение всех тестов;
– не содержит дублирующегося кода;
– выражает намерения программиста;
– использует минимальное количество классов и методов.
Система должна делать то, что задумано ее проектировщиком.
Существует простой способ убедиться в том, что система действительно решает свои задачи.
Система, тщательно протестированная и прошедшая все тесты, контролируема.
Обеспечение полной контролируемости системы повышает качество проектирования.
Для системы необходимо написать тесты и постоянно выполнять их.
Рефакторинг – последовательная переработка кода.
Рефакторинг проводится при наличии полного набора тестов.
В системе не дублируется реализация.
Применять повторное использованием даже в мелочах.
Дублирование – главный враг системы.
Код системы возможно понять без глубокого понимания решаемой проблемы.
Постараться сделать код выразительным.
Неравнодушие – драгоценный ресурс.
Использовать прагматичный подход взамен бессмысленного догматизма.
Применять нагрузочное тестирование.
Многопоточность – стратегия устранения привязок.
Многопоточность – аналогия работы нескольких компьютеров.
Многопоточность повышает быстродействие не всегда.
Многопоточность может изменить архитектуру.
При многопоточности нужно предусмотреть проблемы многопоточной взаимной блокировки, одновременное обновление.
Многопоточность требует больше производительности и кода.
Правильная реализация многопоточности сложна.
Ошибки в многопоточности обычно не воспроизводятся.
Многопоточность обычно требует фундаментальных изменений в стратегии проектирования.
Предусмотреть перебивание потоками друг друга (требуется знание обработки байт-кода и атомарных операций модели памяти).
Многопоточные архитектуры должны отделяться от основного кода.
Код реализации многопоточности имеет собственный цикл разработки, модификации и настройки.
При написании кода многопоточности возникают специфические сложности.
Предусмотреть обработку обращений к общему объекту.
Инкапсулировать данные: жестко ограничить доступ и область видимости общих данных.
Вместо использования общего объекта каждому потоку можно предоставить копию.
Использовать синхронизацию.
Потоки должны быть как можно более независимы.
Постараться разбить данные на независимые подмножества, с которыми могут работать независимые потоки (возможно, на разных процессорах).
Использовать потоково-безопасные коллекции.
Использовать неблокирующие решения.
Изучать доступные классы на предмет потоково-безопасности.
Модели логического разбиения поведения программы при многопоточности:
– производители-потребители: потоки-производители создают задания и помещают в буфер или очередь. Потоки-потребители извлекают задания из очереди и выполняют их. Производители перед записью дожидаются появления свободного места в очереди, а потребители дожидаются появления заданий в очереди. Производитель записывает задание и сигнализирует о том, что очередь непуста. Потребитель читает задание и сигнализирует о том, что очередь не заполнена. Обе стороны готовы ждать оповещения о возможности продолжения работы;
– модель читатели-писатели: писатели пишут в общий ресурс, который считывают читатели. Писатель может блокировать читателей. Нужно найти баланс между потребностями читателей и писателей, чтобы обеспечить правильный режим работы, нормальную производительность и избежать зависания;
– модель обедающих философов: за круглым столом сидят философы-потоки и думают, в центре – тарелка еды. Каждому философу для еды доступно 2 вилки-ресурсы – по 1 от соседей. Когда философ проголодается – берет вилки, поел – кладет обратно. Сложности проектирования – взаимные блокировки, обратные блокировки, падение производительности и эффективность работы.
Изучать базовые алгоритмы, разбираться в решениях.
Избегать использования нескольких методов одного совместно используемого объекта.
Избегать зависимостей между синхронизированными методами.
Или использовать 3 стандартных решения:
– блокировка на стороне клиента;
– блокировка на стороне сервера;
– адаптирующий сервер.
Код не должен перегружаться лишними синхронизированными объектами, так как блокировки создают задержки и увеличивают затраты ресурсов.
Синхронизированные секции должны иметь минимальные размеры.
Корректное завершение не может быть бесконечным ожиданием потока.
Реализовать логическую изоляцию конфигураций многопоточного кода.
Протестировать программу с количеством потоков, превышающим число процессоров.
Применять инструментовку кода для повышения вероятности сбоев.
Сначала отлаживать основной код.
Не игнорировать системные ошибки, считая их случайными разовыми сбоями.
Убедиться, что сам код работает вне многопоточного контекста, созданием POJO-объектов, вызываемых из потоков.
Реализовать многопоточный код так, чтобы он мог выполняться в различных конфигурациях: с разным числом потоков, тестовых заменителей, времени работы тестов, количеством повторов тестов.
Найти средства измерения производительсноти системы в разных конфигурациях.
Реализовать систему так, чтобы количество программных потоков могло легко изменяться, в том числе во время работы системы, в том числе с автоматическим регулированием количества потоков.
JVM не гарантирует вытесняющей многопоточности.
Протестировать систему во всех средах, которые могут использоваться для ее развертывания, начиная с ранней стадии.
Заставить поток исполняться по разным путям в тесте методами object. wait (), object.sleep (), object. yield (), object.priority () – инструментовка кода.
Автоматическая инструментовка с использованием Aspect-Oriented Framework, CGLIB, ASM, ConTest.
Суть тестирования – сломать предсказуемость пути выполнения.
Использовать стратегию случайного выбора пути выполнения для выявления ошибок.
Типичные источники многопоточных ошибок: работа с общими данными из нескольких потоков, использование пула общих ресурсов.
Использовать длительное тестирование многопоточного кода перед включением в систему.
Программирование ближе к ремеслу, чем к науке.
Спасать положение нужно именно сейчас.
Во время переработки кода не добавлять в программу новые возможности.
Предусмотреть, в каких местах будет появляться новый код.
Множество разных типов со сходными методами – причина выделить класс.
TDD: не вносить в систему изменения, нарушающие работоспособность системы.
Добавление теста или класса ничего не нарушит.
Удалять бесполезные функциии.
Тесты всегда должны хотя бы запускаться.
Прочитать последовательное очищение.
Переработка кода напоминает кубик Рубика.
Важный аспект хорошей архитектуры – логическое разбиение кода.
Плохой код тянет группу ко дну.
Открытый код требует смелости и доброй воли.
Полезные высказывания из книги «Отладка приложений для Microsoft. Net» Джона Роббинса
В разделе приведены цитаты из [4].
Большинство команд тратит в среднем 50% цикла разработки на отладку.
Отладка требует специального обучения.
Для того чтобы эффективно отлаживать любую технологию, нужно знать намного больше, чем может дать книга, сфокусированная на конкретной технологии.
Книги по программированию бывают посвящены менеджменту и технологиям.
Основные программы отладки. NET: VisualStudio и WinDBG.
Разработчики должны использовать только учетные записи, обладающие привилегиями пользователя.
[email protected] – автор.
Ошибки помогают понять работу вещей.
Ошибки в ПО могут привести к смене работы.
Ошибка – все что угодно, что заставляет пользователя страдать.
Категории ошибок: аварии и зависания, низкая производительность и масштабируемость, неверные результаты, нарушения безопасности, противоречивые пользовательские интерфейсы, неудовлетворенные ожидания.
Нельзя выпускать на рынок продукт с авариями и зависаниями.
Windows Error Reporting.
Пользователи иногда перестают пользоваться продуктом из-за одного неудачного опыта.
С точки зрения управления проектами главное – уделить внимание производительности.
Должны быть заданы конкретные цифры, связанные с производительностью.
Не делать продукт более медленным, чем его предыдущая версия.
Тестировать приложения по сценариям, наиболее точно отражающим реальный мир.
Наборы данных из реального мира брать у клиентов.
Реальные данные должны быть модифицированы – удалена конфиденциальная информация.
Писать код проверки результатов.
Выставлять требования к производительности, масштабируемости, безопасности.
Проводить тестирование безопасности и моделирование угроз.
Интерфейс приложения не должен противоречить интерфейсу среды.
Приложение не противоречит сочетаниям клавиш среды запуска.
«Designing web usability: the practice of simplicity» Якоб Нильсен.
«Don’t make me think! A common sense approach to web usability» Стивен Круг.
cnn.com – лучший пример дизайна.
joelonsoftware.com/articles.
Все члены команды должны посещать клиентов и наблюдать за использованием ПО.
Никогда не обещать того, чего не сможете дать, и всегда реализовывать обещанное.
Категории причин появления ошибок: слишком короткие или нереальные сроки выполнения; подход «сначала код, потом подумаем»; неправильное понимание требований; невежество разработчиков или недостаточное качество обучения; наплевательское отношение к работе.
Учитывать время на обучение, необходимое для того, чтобы реализовать какую-либо функцию.
Команда разработчиков должна быть истинным хозяином своего расписания, определять реалистичные даты выпуска за счет сокращения числа функций.
Перед написанием кода хорошенько подумать об архитектуре.
Продумать все «что, если».
Определить все риски проекта.
Члены команды не должны отдавать контроль над конструированием системы не умеющим это делать людям.
Не начинать сразу кодировать при получении плана.
Должна быть реалистичная оценка технологии и план разработки еще до включения компьютера.
Исключить добавление новых функций в планировании, которые изначально не планировались.
Чем больше деталей будет обнаружено в ПО и продумано до начала кодирования, тем меньше будет ошибок.
Нарисовать пользовательский интерфейс и полностью проработать каждый сценарий использования.
Коридорное тестирование.
Инженеры должны проявлять желание изучать предметную область.
Лучшие инженеры – это не те, кто умеет жонглировать битами, а те, кто качественно решает проблему пользователя.
Разработчики должны знать достаточно хорошо операционную систему, язык, технологию, которые используются в проектах.
Эффективно использовать выделяемые на обучение средства, проанализировав сильные и слабые стороны команды.
Лучший способ узнать что-то о технологии – сделать что-либо с применением этой технологии.
Все, о чем в действительности заботится ваш менеджер, – это возможность ежедневно сообщать своему боссу, чем вы занимаетесь день за днем.
Настоящие инженеры проникнуты глубокой гордостью за то, что они производят, и хотят тратить время и усилия на всех этапах разработки.
Компании и люди с реальной приверженностью качеству демонстрируют множество общих черт: тщательное предварительное планирование, личную ответственность, жесткий контроль качества и отличные коммуникационные навыки.
Только те, кто уделяет внимание деталям, выпускают продукты вовремя и с отличным качеством.
Проводить ревизии эффективности работы ежемесячно.
Регистрировать число ошибок в продукте ежемесячно (общее число обнаруженных за месяц).
«Software reliability: measurement, prediction, application» Джон Мьюз.
В среднем коде содержится одна ошибка на каждые 10 строк.
«Code complete» МакКоннелл.
По мере того как продукт создается, цена исправления ошибки растет экспоненциально, как и цена отладки.
Ускорять отладку и тестирование на этапе планирования.
Хороший отладчик = хороший разработчик.
Самая важная черта отладчика – интуиция.
Чтобы превратиться в отличного отладчика, необходимо быть специалистом в следующих областях: ваш проект, ваш язык, ваша технология/инструменты, ваша операционная система/среда.
Должна быть хорошая документация или объяснение на 15 мин от разработчиков, чтобы лучше узнать проект.
Нужно знать, что используемый язык делает за сценой.
Необходимо четко представлять себе, где можно найти более подробную информацию на случай, если она понадобится.
Писать утилиты.
Показывать свой код интервьюерам – сразу попадаем в первые 20%.
Изучение кода других инженеров и добавление новых функций – хорошая практика.
Читать код framework.
Друзья и коллеги-инженеры – лучшие источники знаний о разработке и отладке.
Подход к отладке:
Воспроизведите ошибку.
Опишите ошибку.
Всегда предполагайте, что это ваша ошибка.
Разделяйте и властвуйте.
Думайте творчески.
Используйте инструменты.
Начните тяжелую отладку.
Убедитесь, что ошибка исправлена.
Извлеките урок и поделитесь им с другими.
Правообладателям!
Данное произведение размещено по согласованию с ООО "ЛитРес" (20% исходного текста). Если размещение книги нарушает чьи-либо права, то сообщите об этом.Читателям!
Оплатили, но не знаете что делать дальше?