• Курсы Академии Кодебай, стартующие в мае - июне, от команды The Codeby

    1. Цифровая криминалистика и реагирование на инциденты
    2. ОС Linux (DFIR) Старт: 16 мая
    3. Анализ фишинговых атак Старт: 16 мая Устройства для тестирования на проникновение Старт: 16 мая

    Скидки до 10%

    Полный список ближайших курсов ...

[Что нам стоит покер бот построить] Построение архитектуры. ОО-анализ и проектирование

mrOkey

Grey Team
14.11.2017
967
976
BIT
0
[Введение] Что нам стоит покер-бот построить
[Что нам стоит покер-бот построить] Взгляд на проблему с высоты
[Что нам стоит покер-бот построить] Каркас для сервера

Доброе время суток, codeby.

К моему большому удивлению предыдущая статья, мягко говоря «не взлетела» 1 лайк на 100 просмотров. Это фиаско. Меня, конечно, радует писать статьи и пока есть хоть один кому это интересно, я буду писать. Но делится своей разработкой в паблике, да ещё и не получать фидбэка – это такое. Я допускаю, что в фиаско есть моя вина, я не технический писатель, да и учитель из меня не очень, но я работаю над собой и опять же – если я делаю что-то не так, мне нужно знать об этом, мне нужен фидбэк. Выход – раздел грей, сделаю хорошо всем: для себя получу компетентную публику, для codeby – больше премиумов плюс активность грей, да и успокоюсь, якобы не просто так в паблик слил два месяца работы.

Но не будем о грустном. Сегодня поделюсь опытом разработки софта в целом. Иными словами отвечаю на вопрос: как спроектировать систему так, чтобы удовлетворить все потребности заказчика, при этом сохранить в ней гибкость и уложиться в срок. Всё настолько просто, что даже стыдно.

Итак, процесс построения архитектуры начинается с беседы с заказчиком (пишите софт для себя – заказчик вы). Многие называют его:

1. Сбор требований.

Наша цель, для данного этапа – это понять, как заказчик видит систему. Понять, что система должна делать с точки зрения пользователя. Этим мы частично занимались в статье «Взгляд на проблему с высоты». Итогом данного этапа должен стать перечень функциональных возможностей системы. Функциональная возможность - высокоуровневое описание чего-то, что должна делать система.

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

Пример моей функциональной возможности из тз о покер боте.

2. Анализ функциональных возможностей.

Помните фразу: «чужая душа потёмки»? В контексте разработки, это значит, что мы никогда не сможем полностью понять - чего хочет заказчик (особенно если заказчик вы сами). Парадокс, не так ли? Поэтому нам нужен промежуточный этап, чтоб точно убедиться в том, что мы будем делать в точности то, что хочет заказчик. Целей на данном этапе две:

· Абстрактная: наше виденье системы должно синхронизоваться с виденьем системы заказчика.

· Конкретная: у нас должны появиться диаграммы вариантов использования.

Что такое диаграмма вариантов использования? Проще показать на самом деле.
1.PNG


Урезанный пример из тз покер бота. Диаграммы вариантов использования - это план системы. Для проверки вариантов использования, можно воспользоваться списком функциональных возможностей: Возьмите диаграмму вариантов использования и убедитесь в том, что перечисленные варианты использования охватывают все функциональные возможности, о которых вам сообщил заказчик. Делаем мы это для лучшего понимания системы и устранения прокрастинации.


3. Разбиение системы на меньшие функциональные блоки.

Думаю, каждый из вас умеет делить задачу на подзадачи? То же самое и тут. Вот некоторые из моих функциональных блоках:
2.PNG


Всё очевидно.

4. Расстановка приоритетов.

Вот теперь мы плавно подошли к срокам. После того как у нас есть «идеальный план» мы частенько не понимаем с чего начать. В этом я постараюсь вам помочь. Секрет в том, что начинать следует со значимых, с точки зрения архитектуры аспектов. Но как их определить? Когда вы пытаетесь определить имеет ли некоторый аспект архитектурную значимость задайте себе три вопроса. Три основных вопроса архитектуры:

Относится ли эта часть к сути системы? Является ли данная функциональная возможность неотъемлемой частью системы? Иначе говоря, можно ли представить систему без нее? Если нельзя, то, скорее всего ваша функциональная возможность относится к сути системы.

Что это означает? Если вы не уверены в том, какой смысл заложен в описание некоторой функциональной возможности, то, скорее всего, она достаточно важна, чтоб уделить ей особое внимание. Если вы в чем-то не уверены, работа над этим "чем-то" может занять много времени или создать проблемы с остальными составляющими системы. Лучше заняться этими функциональными возможностями на ранней, чем на поздней стадии.

Как это сделать? Также следует как можно раньше сосредоточиться на функциональных возможностях, которые действительно трудны в реализации или сопряжены с решением совершенно новых (для вас) задач из области программирования. Если вы понятия не имеете, как взяться за ту или иную задачу, лучше заняться ею пораньше, чтоб избежать серьёзных проблем в процессе работы.

Задав эти три вопроса, мы выберем несколько ключевых возможностей, на которых мы должны сосредоточиться на первой стадии работы. Ключевые возможности - вводят РИСК в ваш проект, неважно с чего начинать, важно двигаться в направлении снижения РИСКОВ. Наша цель - СОКРАЩЕНИЕ РИСКА.

Занимайтесь одной функциональной возможностью за раз, чтобы снизить риски. Не отвлекайтесь на функциональные возможности, которые не помогут снизить риски. Старайтесь строить новые возможности на основе того, что уже сделано. Помните, что Архитектурой называется организационная структура системы, которая выделяет важнейшие части приложения и отношения между ними.

Каждый раз, когда вы не уверены в смысле той или иной функциональной возможности используйте эти действия: Спросите заказчика -> (что это означает?) -> Анализ общности -> (Как реализовать эту функциональную возможность в моей системе?) План реализации. ( На всякий случай – Анализ общности отражает принцип: Старайтесь строить новые возможности на основе того, что уже сделано.)

5. На этом шаге с предварительным анализом своей софтины мы закончили. Теперь начинается итеративный процесс который мы применяем к каждому нашу блоку.

a. Написать вариант использования для сценария с шага 2. Сценарий – это детализированный «кружочек» из диаграммы вариантов использования. Это чёткий алгоритм действий, которые необходимо выполнить для реализации «кружочка» (функциональной возможности)

b. Анализ предметной области. Данный этап знаком вам из предыдущей статьи, поэтому кратко: мы берём наш вариант использования и разбираем его по кирпичикам с помощью текстологического анализа. Текстологический анализ - поиск существительных (потенциальных классов) и глаголов (потенциальных методов) в варианте использования

c. Предварительное проектирование. На этом этапе уже можно писать код, основываясь на все наши данные. Вот некоторые советы, которые вам помогут:

Напишите класс, который как вы считаете необходим. Затем примените к этому классу следующие правила:

Инкапсуляция.

Инкапсуляция - процесс размещения программных элементов в больших, более абстрактных сущностях. Также используются термины "сокрытие информации" и "разделение обязанностей". Под инкапсуляцией понимается сокрытие реализации класса, обеспечивающие простоту его использования и изменения. Класс работает по принципу чёрного ящика: он предоставляет сервис своим пользователям, но скрывает свою реализацию, чтобы другие программисты не могли ничего изменить или некорректно использовать его. Инкапсуляция играет ключевую роль в соблюдении принципа открытости\закрытости. Инкапсуляция отделяет данные от приложения. Что позволяет нам управлять тем, как каждая часть приложения используется его остальными компонентами.

Программирование для интерфейса, а не для реализации.

Абстрактные классы могут рассматриваться как условные представители конкретных классов реализации. Абстрактный класс определяет поведение, а субклассы это поведение реализуют. Когда в двух и более местах обнаруживается общее поведение, постарайтесь абстрагировать это поведение в отдельный класс. Программирование для интерфейса, а не для реализации упрощает расширение ваших программ. При программировании для интерфейса ваш код будет работать со всеми субклассами этого интерфейса, даже с теми, которые ещё не созданы.

Сцепление - степень логического сопряжения элементов одного модуля, класса или объекта. Чем выше сцепление программного продукта, тем четче определены обязанности каждого класса приложения. Каждый класс обеспечивает выполнение четко определенного набора взаимосвязанных действий. Класс с высоким сцеплением хорошо делает что-то одно и не пытается делать что-то другое. Классы с высоким сцепление сконцентрированы на выполнении конкретных задач.

Для иерархий классов используйте следующие: Делегирование, Композиция и Агрегирование.

Делегирование - когда объекту требуется выполнить некоторую задачу и вместо того, чтобы выполнять ее самостоятельно, он может поручить ее выполнение (или выполнение её части) другому объекту. Делегирование упрощает повторное использование кода. Каждый объект имеет дело с собственной функциональностью (вместо распределения кода, относящегося к поведению одного объекта, по всему приложению)

Делегирование позволяет каждому классу обеспечить выполнение проверки равенства (или любой другой операции) для объектов своего типа. Таким образом, объекты в меньшей степени зависят друг от друга, что способствует ослаблению связности. Слабосвязанные объекты можно извлечь из одного приложения и легко использовать в другом, потому что они не имеют жестких связей с кодом других объектов.

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

Делегирование - всего лишь одна из возможных альтернатив наследованию. Делегирование лучше всего применять в ситуациях, в которых нужно использовать функциональность другого класса "как есть", без каких-либо изменений. Если вам потребуется использовать функциональность другого класса без ее изменения, рассмотрите возможность использования делегирования вместо наследования.

Композиция.

В некоторых случаях желательно иметь выбор из нескольких вариантов поведения. Например, вспомним предыдущую статью и поймём зачем вся эта «кутерьмя».

Композиция используется для выбора поведения из семейств возможных вариантов. Композиция особенно эффективно используется тогда, когда вы хотите использовать поведение, определенное в интерфейсе с возможностью выбора из разных реализаций этого интерфейса, как во время компилирования, так и на стадии выполнения. Композиция позволяет использовать поведение из семейств других классов и изменять это поведение на стадии выполнения. Если один объект содержит другие объекты, то при уничтожении объекта-владельца объекты, образующие композицию, тоже будут уничтожены.

Агрегирование.

Используется вместо композиции, когда внутренние объекты должны существовать вне главного объекта. Использование одного класса как части другого с возможностью существования за его пределами.

Для классов применяйте это:

Принципы проектирования. Общий инструмент или приём, который может применяться при проектировании или написании кода для улучшения гибкости, удобства сопровождения и расширения программы.

Принцип открытости\закрытости

Он допускает изменения, но только те, которые предотвращают необходимость переписывания существующего кода. Определение: Классы должны быть открыты для расширения, но закрыты для изменения.

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

Но открыто для расширения - при этом вы хотите, что бы ваш код можно было использовать и расширять. Вы разрешаете субклассирование, и внешние пользователи переопределяют ваш метод, чтобы он лучше подходил для их целей.

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

Don’t repeate yourself (Не повторяйтесь)

Избегайте дублирования кода, абстрагируя общие аспекты и размещая их в одном месте. Сначала, следует выделить общий код и разместить его в одном месте. Удалить код из других мест. Обратится к коду из шага один. Так же данный принцип применяется к требованиям: одно требование в одном месте.

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

Принцип единственной обязанности

Каждый объект в системе должен иметь единственную обязанность и все действия объекта должны быть сосредоточены на ее выполнении. Принцип считается соблюденным, если каждый из ваших объектов имеет только одну причину для изменения.

[LifeHack] Выявление множественных обязанностей:

Записать на листке набор строк вида [имя класса][операция, выполняемая с объектом класса] - по одной строке для каждого метода класса, проверяемого на SRP

Прочитайте каждую строку вслух (при необходимости добавьте связки или слова, чтоб текст читался нормально). Имеет ли смысл то? что вы прочитали? Действительно ли у вашего класса есть обязанности, обозначенные этим методом?


Если то, что вы прочитали не имеет смысл, значит метод нарушает принцип SRP. Возможно, метод должен принадлежать другому классу. Рассмотрите возможность его перемещения.

Ещё одна рекомендация: действие должно выполняться тем классом, который имеет максимально необходимую информацию для его выполнения.

Принцип подстановки Барбары Лисков

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

Суть LSP заключается в правильно спроектированной иерархии наследования. При наследовании от базового класса замена последнего субклассом не должна ничего нарушить. Если это условие не выполняется, значит, вы не правильно используете наследование.

Соблюдая эти рекомендации, вы легко сможете реализовать что угодно, я серьёзно это очень упрощает жизнь. Это своего рода выжимка из прочитанных мной книг о проектировании приправленная реальным опытом разработки. Конечно в книгах, всё подробнее и я надеюсь, что вы заинтересуетесь этим и сами углубитесь при необходимости. Обеспечивайте меня фидбэком, задавайте вопросы, лайкайте, спрашивайте. Я же не для себя стараюсь, если вам не интересно, так мне проще не писать.
 
Последнее редактирование:

Gunn1110

Green Team
01.03.2017
25
1
BIT
1
Продолжение будет или все остальное планируется в привет? И еще вопросик, удалось ли достигнуть цели т.е. заработать на бонусах 100К?
 

mrOkey

Grey Team
14.11.2017
967
976
BIT
0
Продолжение будет или все остальное планируется в привет? И еще вопросик, удалось ли достигнуть цели т.е. заработать на бонусах 100К?
Про достижение писал в первой статье. Статьи будут, сейчас занят подготовкой курса для школы codeby
 
Мы в соцсетях:

Обучение наступательной кибербезопасности в игровой форме. Начать игру!