2013_09_21_L.pptx
- Количество слайдов: 76
Что будет, если не обращать много раз на мелкие проблемы? • Антипаттерн проектирования – большой комок грязи • Пример – все тестовое задание на C# в виде одной БОЛЬШОЙ функции (или двух) – на след. слайде 1
Две функции • • using System; using System. IO; using System. Collections. Generic; using System. Text; • • • namespace Txt. To. Html { class Txt. To. HTMLConverter { private int Max. Output. File. Lines; // Максимальное количество строк в выходном файле • • private File. Stream Text. File. Stream; // Поток для чтения файла с текстом private Stream. Reader Text. File. Reader; // • • private File. Stream Dictionary. Stream; // Поток для чтения файла словаря private Stream. Reader Dictionary. Reader; // • • private string current. Word = ""; // Текущее слово private char current. Symbol = ' '; // Текущий символ • • private string in. Line; // Прочитанная из файла строка private string out. Line; // Строка результат • • private int Out. Line. Count; // Число строк в выходном файле (текущее) private int Out. File. Number; // Номер выходного файла • • private File. Stream Output. Stream; // Поток для записи в выходной файл private Stream. Writer Output. Writer; // • private Dictionary<string, int> My. Dictionary; • • private bool text. Is. Loaded = false; private bool dictionary. Is. Loaded = false; • • public bool Text. File. Is. Loaded { get { return this. text. Is. Loaded; } • • public bool Dictionary. Is. Loaded { get { return this. dictionary. Is. Loaded; } }
« 7 смертных грехов программирования» 1. Поспешность 2. Пассивность 3. Ограниченность 4. Лень 5. Алчность 6. Некомпетентность 7. Гордость
1. Поспешность (Haste) • “Just “clean up” the code. We ship tomorrow” • Поспешные и необдуманные решения (особенно в условиях сжатых сроков) могут привести к: – Постановке недостижимых целей; – Отказу от преимуществ долгосрочных архитектурных решений в пользу экономической выгоды; – Отказу от полноценного тестирования; – Снижению качества программного продукта; 4
2. Пассивность (Apathy) • “Reuse? Reuse!! Who’s every gonna reuse this crappy code? NO ONE!” • Проблема проявляется в том, что разработчики не уделяют должного внимания решению хорошо известных и изученных проблем, считая это рутинной работой • Последствия: – Введение непредусмотренных зависимостей – Снижение стабильности системы – Усложнение модификации и расширения системы 5
3. Ограниченность (Narrow-Mindedness) • “I don’t need to know… and I don’t care to know” • Ограниченность проявляется в нежелании или невозможности разработчиков использовать решения, эффективность которых подтверждена практикой и широко известна • Проблемы: – Увеличение затрат времени и средств на разработку проекта – Ограничение функциональности продукта – Снижение управляемости изменений 6
4. Лень (Sloth) • “Sloth usually ends with sudden clarity” • Лень заставляет разработчиков выбирать решения, исходя из простоты реализации и минимизации локальных усилий, а не повышения эффективности системы в целом • Последствия принятия “ленивых” решений: – Частые изменения интерфейса – Значительная часть времени тратится на изучение поведения очередной версии системы – Документация быстро теряет актуальность – Повторное использование типа “белый ящик” 7
5. "Алчность" (Avarice) • “It certainly is complicated! I’m sure our clients will be very, very impressed!” • В процессе проектирования нередко возникает желание “улучшить” систему путем увеличения ее сложности • Проблемы: – – – Введение избыточной сложности Увеличение стоимости проекта и его рисков Увеличение времени разработки Усложнение разработки и сопровождения Повышение требований к квалификации разработчиков Итогом часто является выпуск продукта низкого качества и даже провал проекта 8
6. Некомпетентность (Ignorance) • “I don’t really have time to read this…” • Возникает в ситуации, когда разработчики не хотят или не имеют возможности изучать документацию системы • Последствия: – Появление непредусмотренных зависимостей – Снижение стабильности системы – Снижение качества продукта 9
7. "Гордость" (Pride) • “Attention! New Company Motto: ZERO DEFETCS” • Гордость проявляется в отказе от использования готовых решений и разработке собственных, но полученных в результате обратного проектирования существующего программного кода • Проблемы: – Увеличение сроков разработки – Появление новых рисков 10
Как надо писать код • Надо писать код так просто, что бы любой человек смог в нем разобраться. • Надо писать код так, что бы никто в нем не мог разобраться и побоялся его трогать • И все это еще с тестами для спокойствия
Антипаттерны • Программы пишутся человеком. Для машины. Но сопровождать их будет человек, поэтому и для человека тоже. • Таинственный код (Cryptic code): Использование аббревиатур вместо мнемоничных имён. 12
Класс Form 1 Отвечает за выполнение входа и перехода на окно регистрации В системе взаимодействует с Form 2, Form 3 Класс Form 2 Отвечает за регистрацию Взаимодействует с Form 1, взаимодействует с БД Класс Form 3 Отвечает за выполнение входа в программу по логину и паролю Взаимодействует с Form 1, Form 4 Класс Form 4 Отвечает за предоставление выбора пользователю между каталогом приложения и загрузкой своих изображений Взаимодействует с Form 6, Form 5 Класс Form 5 Отвечает за загрузку пользовательских изображений взаимодействует с Form 4 Класс Form 6 Отвечает за выбор стиля одежды перед тем, как перейти в каталог Взаимодействует с View Класс View Отвечает за просмотр одежды каталога, примерки и просмотра её на манекене Взаимодействует с БД, с Form 8, Zoom. Form Класс Form 8 Отвечает за содержание корзины и удаление оттуда одежды Взаимодействует с Form 9, с БД Класс Zoom. Form Отвечает за увеличение изображения для удобства просмотра Взаимодействует с View Класс Form 9 Отвечает за выбор цвета одежды и количества Взаимодействует с БД, Form 7 Класс Form 7 Отвечает за формирование отчетов Взаимодействует с Send_Mail Класс Send_Mail Отвечает за отправку на почту клиента информации о заказе Взаимодействует с Form 10 Класс Form 10 Отвечает за выход из программы или возвращение в начало приложения Взаимодействует с Form 1 13
Что улучшить • Дать нормальные имена переменным 14
• • • • • • • for (int i = 0; i < text. Box 7. Text. Length; i++) { if ((int)text. Box 7. Text[i] < 48 || (int)text. Box 7. Text[i] > 57) { Message. Box. Show("Номер телефона не корректен!"); text. Box 7. Text = ""; } if (text. Box 1. Text != string. Empty && text. Box 2. Text != string. Empty && text. Box 3. Text != string. Empty && text. Box 4. Text != string. Empty && text. Box 5. Text != string. Empty && text. Box 7. Text != string. Empty & combo. Box 2. Text != string. Empty) { //Random id = new Random(); //int id_client = id. Next(0, 10000); string login = text. Box 1. Text; string password = text. Box 2. Text; string fio = text. Box 3. Text; string sex = text. Box 4. Text; // int size = 42; //Convert. To. Int 32( f. text. Box 5. Text); string phone_number = text. Box 5. Text; string e_mail = text. Box 7. Text; string address =combo. Box 2. Text; int size = Convert. To. Int 32(combo. Box 1. Text); Uprav. Class u = new Uprav. Class(); Form 1. id_size = Convert. To. Int 32(combo. Box 1. Text); u. ADD_client( /*id_client, */login, password, fio, sex, phone_number, e_mail, address, size); 15
Методики по исправлению антипаттенов (возможно добавить примеров) • Для исправление всех антипаттернов, кроме кодирования – методология кайдзен • Для исправления антипаттернов в существующем коде – рефакторинги • Для обнаружения антипаттернов – метрики, легкость тестируемости, знание антипаттернов
Что улучшить • Можно уменьшить цикломатическую сложность кода • Можно переменных объявить до проверки и тогда проверка хоть будет более читаемой • Программисты – люди и все от психологии им близко. Средний программист может держать в памяти 3 -7 объектов. 17
Из опыта Возможные названия сортировок • • • Sorting Quick. Sortirovka Sortir Tree. Sort
Антипаттерн • Вызов предка (Call super): Для реализации прикладной функциональности методу класса-потомка требуется в обязательном порядке вызывать те же методы классапредка. • Пример из автоматических действий в проекте на след. слайде 19
Пример public abstract class Base. Subroutine : ISubroutine { public Date. Time Last. Run { get; set; } public virtual Time. Span Run. Interval {…} public virtual void Run() { Last. Run = get. Now; } } namespace Auto. Actions { public class Delete. User : Base. Subroutine { public override Time. Span Run. Interval {…} public override void Run() { using(var db = new Sila. Db. Context()) { var users. For. Deleting = db. user. Where(u =>u. Is. Blocked). To. Array() foreach (var del. User in users. For. Deleting) { …. } db. Save. Changes(); } base. Run(); } } 20
Что плохо и надо изменить • Абстрактный класс без абстрактного метода • При перегрузке метода необходимо не забыть вызвать метод базового класса для установки времени последнего вызова • Что надо – добавить абстрактный метод, который вызывать в базовом 21
Что изменить? public abstract class Base. Subroutine : ISubroutine { public Date. Time Last. Run { get; set; } public virtual Time. Span Run. Interval {…} public abstract void Action(); public void Run() { Action(); Last. Run = get. Now; } } namespace Auto. Actions { public class Delete. User : Base. Subroutine { public override Time. Span Run. Interval {…} public override void Action() { using(var db = new Sila. Db. Context()) { var users. For. Deleting = db. user. Where(u =>u. Is. Blocked). To. Array() foreach (var del. User in users. For. Deleting) { …. } db. Save. Changes(); } } 22
Программирование методом копирования-вставки (Copy and paste programming). Общая характеристика • Общая характеристика – Боязнь рефакторинга чужого кода, который не покрыт тестами – Не знание основ ООП – Нет абстрагирования – Кривые руки 23
Характерные признаки • Похожий код • Программист используется Ctrl+C, Ctrl+V, Ctrl+Insert, Shift+Insert 24
Пример • • • • • • • • public View(Image. List Up, Image. List Down, Image. List Full) { Initialize. Component(); up = Up; down = Down; full = Full; picture. Box 1. Mouse. Down += picture. Box 1_Mouse. Down; picture. Box 2. Allow. Drop = true; picture. Box 2. Drag. Enter += picture. Box 2_Drag. Enter; picture. Box 2. Drag. Drop += picture. Box 2_Drag. Drop; back. Ground = new Picture. Box(); back. Ground. Image = picture. Box 2. Image; if (up. Images. Count != 0) { picture. Box 1. Image = up. Images[0]; } if (full. Images. Count != 0) { full_pic. Image = full. Images[0]; } if (down. Images. Count != 0) { down_pic. Image = down. Images[0]; } public View() { } public View(Image. List Up, Image. List Down, Image. List Full, Dictionary<int, string> Up_addresses, Dictionary<int, string> Down_addresses, Dictionary<int, string> Full_addresses) { Initialize. Component(); up = Up; down = Down; full = Full; up_addresses = Up_addresses; down_addresses = Down_addresses; full_addresses = Full_addresses; picture. Box 1. Mouse. Down += picture. Box 1_Mouse. Down; picture. Box 2. Allow. Drop = true; picture. Box 2. Drag. Enter += picture. Box 2_Drag. Enter; picture. Box 2. Drag. Drop += picture. Box 2_Drag. Drop; back. Ground = new Picture. Box(); back. Ground. Image = picture. Box 2. Image; if (up. Images. Count != 0) { picture. Box 1. Image = up. Images[0]; } if (full. Images. Count != 0) { full_pic. Image = full. Images[0]; } if (down. Images. Count != 0) { down_pic. Image = down. Images[0]; } } 25
Решение • Заставить прочитать книгу по рефакторингам • Использовать тесты, что бы было не страшно исправлять чужой код 26
Затычка на ввод данных (Input kludge): Отсутствие корректной обработки возможного неверного ввода. • Общая характеристика: – В коде нет обработки неверного ввода или глушение ошибок 27
Характерные признаки: • Нет валидации входных данных • Все обрамлено глобальным try catch 28
Что делать • Почитать, как тестировать, что такое эквивалентные множества, крайние значения и т. д. 29
Затычка на ввод данных (Input kludge): Отсутствие корректной обработки возможного неверного ввода. • Загрузка из csv файла – экранирование запятых • Тестовое задание – отсутствие проверки наличия html тегов • Примеры из дорогих ошибок – не было проверки, что такое количество акций у фирмы вообще есть. 30
Из опыта • Была Оля в проекте. Ей сказали отверстать страницу. Она сказала, что сможет. Продемонстрировала на своем экране отверстанную страницу… было нормально • Потом она ушла • Потом открыли её творение… – Выравнивание по центру было сделано смещением от левого края на нужный размер, который был вычислен от фиксированного размера карточки товара Переписали все, что она сделала. Причем это еще было в CSS, и наверно там остался мусор
Глушение ошибок Error Hiding • Антипаттерн: – Error Hiding • Причины появления: – Лень – Некомпетентность 32
Общая характеристика • Отслеживание возникающих в системе сбоев очень сложно, а зачастую невозможно • Ошибки уходят в никуда 33
Характерные признаки • Система работает не так, как положено, но логи безоблачно чисты • Система выводит пользователю красивые «Извините, но. . . » , а логи безоблачно чисты • Пользователи жалуются, что ничего не работает, но логи с production безоблачно чисты 34
Наглядный пример try { Input. Stream is = new // do smth. . . File. Input. Stream("hello. txt"); } catch (IOException ex) { throw new User. Visible. Message. Exception(“EEVIL!”); } 35
Решение • Передача изначального исключения наверх • Если необходимо вызвать специальное исключение, то исходное нужно зафиксировать в логах • Внутренние исключения • Не допускать сокрытия ошибок в дальнейшем 36
Магическая (волшебная) кнопка (Magic pushbutton): Написание бизнеслогики в коде пользовательского интерфейса (например в обработчике события нажатия на кнопку). • Пример – samplessrc 37
Предложения для решения проблемы?
Один из вариантов обнаружения проблем - метрики кода
В VS есть возможность вычисления Code metrics • Maintainability Index – комплексный показатель качества кода. Чем больше – тем лучше • Cyclomatic Complexity – показывает структурную сложность кода, т. е. количество различных ветвей в коде. Чем больше этот показатель, тем хуже. • Depth of Inheritance – глубина наследования. • Class Coupling – степень зависимости классов друг с другом. Чем больше, тем сложнее в дальнейшем переиспользовать этот класс, а также поддерживать, т. к. существует очень много зависимостей. • Lines of Code – показывает количество строк кода (основан на IL -коде) Большое количество строк в методе/классе может показывать на ошибки в проектировании и на то, что этот код можно разделить на несколько частей.
Maintainability Index • комплексный показатель качества кода. Рассчитывается метрика по следующей формуле: MI = MAX(0, (171 — 5. 2 * ln(HV) — 0. 23 * CC — 16. 2 * ln(Lo. C)) * 100 / 171) – HV – Halstead Volume, вычислительная сложность. Чем больше операторов, тем больше значение этой метрики; – CC – Cyclomatic Complexity. – Lo. C – количество строк кода. Эта метрика может принимать значения от 0 до 100 и показывает относительную сложность поддержки кода. Чем больше значение этой метрики, тем легче поддерживать код. Теория - Visual Studio помечает методы/классы зеленым цветом, если значение метрики находится в пределах от 20 до 100, желтым цветом, если значение находится в пределах от 10 до 20, и красным цветом, когда значение меньше 10.
Практика – оценка 28 для кода
11 й уровень вложенности… public override void Action() { int investment. Order. Lifetime = Configuration. Get<int>(Configuration. Config. Name. Investment. Order. Lifetime); //const int CURRENCY_ID = 2; //Тип валюты. Потом необходимо будет реализовать получение Id валюты. Пока Id задается константой. int REQUEST_LIFETIME = Configuration. Get<int>(Configuration. Config. Name. Send. Request. Lifetime); System. Mode system. Mode = Configuration. Get<System. Mode>(Configuration. Config. Name. System. Mode); using (var db = new Sila. Db. Context()) { //Получение поручений у которых заявки на отправку имеют статус "В процессе" var invesment. Orders = (from investment. Order in db. investment_order join order. Sent in db. order_sent on investment. Order. Investor. Request. Id equals order. Sent. Id where order. Sent. Status == (int)Investment. Order. Request. Status. In. Process || order. Sent. Status == (int)Investment. Order. Request. Status. New select investment. Order). To. Array(); foreach (var invesment. Order in invesment. Orders) if ((invesment. Order. order_sent. Status == (int)Investment. Order. Request. Status. In. Process || invesment. Order. order_sent. Status == (int)Investment. Order. Request. Status. New)
Вывод из практики • В районе 60 – нормально, можно понять. Ниже - проблемы
Cyclomatic Complexity • показывает структурную сложность кода, т. е. количество различных ветвей в коде. Чем больше этот показатель, тем больше тестов должно быть написано, для полного покрытия кода.
Depth of Inheritance • глубина наследования. Эта метрика показывает для каждого класса, какой он по счету в цепочке наследования. • A – 1 • B – 2 • C - 3
Class Coupling • показывает степень зависимости классов друг с другом. В расчет берутся уникальные классы из параметров, локальных переменных, возвращаемого типа, базового класса, атрибутов и т. д. Хороший дизайн программного обеспечения предполагает небольшое количество связанных классов. Чем их больше, тем сложнее в дальнейшем переиспользовать этот класс, а также поддерживать, т. к. существует очень много зависимостей.
Lines of Code • показывает количество строк кода. Этот показатель показывает не точное количество строк в вашем файле, подсчет основан на IL-коде. • Большое количество строк в методе/классе может показывать на ошибки в проектировании и на то, что этот код можно разделить на несколько частей.
Кайдзен • Суть концепции кайдзен – улучшение или совершенствование. Слово “кайдзен” состоит из двух иероглифов – «изменения» и «хорошо» . Изменяй к лучшему, изменяйся к лучшему. Причем изменяться надо немедленно, и маленькое небольшое изменение лучше чем отложенное совершенствование
Принципы кайдзен (1/2) • • • Придерживайся концепции “ориентация на рынок” (Клиент прежде всего. Тот кто выполняет следующую технологическую операцию — твой потребитель. Если ты сторонник концепции “поскорее сбыть” то название нашей компании вскоре исчезнет даже из телефоной книги) Всегда будь внимателен к возникающим проблемам (Там где нет проблем — совершенствование невозможно) Управлять — значит начать с планирования и сравнить план с результатом. (Давайте вертеть колесо PDCA и менять свой подход к работе) Горы сокровищ высятся на каждом шагу (Хронические проблемы могут научить тебя большему чем те, которые возникают внезапно) Управляй процессом по результатам (Исправление и подгонка — проблемы, возникающие изза упущений руководства. Решение этих проблем уже не менеджмент, а манипуляции) Анализируй происходящее на предприятии и действуй на основе фактов (Делай выводы, опираясь на достоверные факты. Не полагайся на интуицию или внутренний голос)
Принципы кайдзен (2/2) • • Будь внимателен к отступлениям от стандарта (Важнее установить отклонения, чем повысить средние показатели) Разделяй объекты наблюдения на группы перед наблюдением (Классификация помогает лучшему пониманию) Совершенствование начинай с себя (Приучи себя определять вопросы, за которые отвечаешь ты лично, в отличии от тех, за которые отвечают другие и начинай с собственных задач) Устраняй основную причину и предотвращай рецидивы (Не путай причину проблемы с ее проявлениями) Встраивай качество в процесс как можно раньше (Качество должно встраиваться в процесс, проверка не создает качества) Никогда не забывай о стандартизации (Нам нужны методы, позволяющие закрепить достигнутый результат) Всегда помни о развертывании по горизонтали (Личный опыт должен становиться достоянием всей компании) Внедрение TQC касается всех (Приятная и осмысленная работа в цехе начинается с активного “кружка качества”, который способствует взаимному обучению и саморазвитию)
Часть методологии Кайдзен которая применима к кодированию • Непрерывные изменения — есть, непрерывные малые изменения во всех сферах организации • Открытое признание проблем — все проблемы открыто выносятся на обсуждение • Развитие по горизонтали. (Личный опыт должен становиться достоянием всей компании) • Развитие самодисциплины — умение контролировать себя и уважать как самого себя, так и других работников и организацию в целом • Устранение основной причины и предотвращение рецидивов • Ни один день не должен пройти без того, чтобы какоенибудь улучшение не было сделано где-то в компании.
Выводы • Ошибаться – нормально, главное – не повторять ошибок. • Лучше если знать список стандартных ошибок дру • Сегодня озвучили некоторые проблемы, но антипаттернов на самом деле большое количество • Антипаттерны имеют множество причин и если хотите добиться повышения эффективности работ команды придется заниматься не только антипаттернами кодирования.
Git. Супер краткое руководство
Системы контроля версий (централизованные) CVS, Subversion и Perforce. • есть центральный сервер. • централизованный Много лет это было сервер является стандартом для систем уязвимым местом всей контроля версий системы. • все знают, кто и чем занимается в проекте. У администраторов есть чёткий контроль над тем, кто и что может делать. • администрировать ЦСКВ легко.
Распределенные системы контроля версий (Git, Mercurial, Bazaar или Darcs) • клиенты не просто выгружают последние версии файлов, а полностью копируют весь репозиторий. Каждый раз, когда клиент забирает свежую версию файлов, он создаёт себе полную копию всех данных • можно работать с несколькими удалёнными репозиториями • Так, в одном проекте можно одновременно вести несколько типов рабочих процессов, что невозможно в централизованных системах.
Ставим программу Git Extentions
2. Заходим на https: //github. com/ • Регистрируемся. После регистрации
Выбираем Create Repository
• Кликаем по созданию репозитория (под пунктом 1) • Вводим свободное имя репозитория + описание
• Нажимаем create repository
Переключаемся на http
• Запускаем Git Extentions
• Во время передачи изменений затребует ввести имя пользователя и пароль от гитхаба
2013_09_21_L.pptx