Часть 1: Что и зачем проектировать? (Рейтинг: +2)

Печать RSS
Предисловие
Возможно это не лучший раздел для написания цикла статей по проектированию информационных систем (ИС), но так как специализированного раздела по этой теме я не нашел, буду писать здесь. Если что, надеюсь модераторы меня поправят и перенесут.
Так как нет возможности вставлять в статью изображения, постараюсь обойтись без них, правда описание UML без его графической нотации довольно сложная задача.
И так я приступаю к написанию цикла статей по проектированию ИС в web. Я буду ориентироваться на итерационно-инкрементарный процесс разработки ИС с использованием объектно-ориентированного подхода. Подробно углубляться в эти принципы и методы разработки я не стану, но в общих словах опишу, чтобы вы могли не отрываясь от цикла, понять о чем речь.

Введение
Часто меня спрашивают - как правильно написать масштабируемую, удовлетворяющую всем требованиям заказчика и в то же время понятную другим программистам систему? - и еще чаще меня спрашивают - зачем ты днями сидишь за этими блокнотами, не пора бы уже код писать?
Оба эти вопроса упираются в вопрос предварительного проектирования будущей ИС. Под ИС я буду понимать любую систему, целью которой является сбор, обработка, хранение и выдача информации, а так же автоматизация некоторых процессов. К таким системам в web можно отнести социальные сети, форумы, CMS и так далее, и не одна подобная система не будет достаточно гибкой и масштабируемой (более того скажу, что ни одна серьезная, крупная система вообще) без предварительного процесса проектирования.

"Что это за зверь?"
Обычно процесс создания новой ИС состоит из следующих пунктов:
1) Сбор и анализ требований к системе;
2) Проектирование системы;
3) Разработка системы;
4) Предварительное тестирование (или альфа и бета тестирование);
5) Внедрение и сопровождение системы.
В данном цикле статей я затрону только второй пункт, а остальные, возможно, затрону в других циклах.
И так проектирование системы это процесс осмысления будущей системы, ее функционала (на основе уже полученных ранее требований) и архитектуры. Обычно проектирование системы включает определение следующих элементов:
1) Диаграммы сущность-связь;
2) Определение прецедентов;
3) Объектно-ориентированный анализ и построение диаграммы классов (объектная нотация)
а) Диаграмма классов;
б) Модель базы данных (БД);
4) Диаграмма состояний системы;
5) Диаграмма деятельности;
6) Диаграмма последовательностей.

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

Что не помешало бы знать?
Для успешного осмысления статей вам не мешало бы знать основы объектно-ориентированного анализа и проектирования (ООА/П), иметь опыт разработки сложных систем или опыт командной разработки ИС, а так же наполнится желанием и терпением.
Если вы не уверены в ваши знаниях относительно ООА/П, то не расстраивайтесь, далее я затрону этот вопрос (хоть и поверхностно), так что кое какое представление вы все таки иметь будете. Если же вы никогда не писали ничего, сложнее "гостевой книги", то возможно вам еще рано углубляться в вопросы проектирования ИС. В этом нет ничего плохого, так как излишняя информация и умения иногда приводят к тому, что программист начинает использовать сложные механизмы для реализации простых задач. Когда вы столкнетесь с необходимостью использования предварительно проектирования, вы всегда сможете вернуться к этому циклу статей, а пока не утруждайте себя и не заполняйте голову не нужной информацией.

Объектная ориентированность
У большего количества начинающих.. хотя чего я вру.. почти у всех программистов возникает вопрос - на кой *** мне этот объектно-ориентированный подход? Неужели нельзя использовать старые добрые функции?. Вопрос вполне резонный! В большинстве случаев можно обойтись без использования ООП, в большинстве но не всегда! Когда же пора переходить на ООП? Обычно это такой момент, года начинаешь путаться в количестве функций и глобальных переменных, используемых этими функциями. Рассмотрим пример (который я, кстати, еще не раз использую в цикле) с аутентификацией пользователя. Нам необходимо получить от пользователя логин и пароль, а затем сравнить его с имеющимися в БД, если таковая пара найдена, будем считать пользователя аутентифицированным.
В процедурном подходе нам понадобятся:
Переменные:
Логин искомого пользователя (получаем от браузера)
Пароль искомого пользователя (получаем от браузера)
Соединение с БД
Функции:
Поиск пользователя по логину и паролю
Получение соединения с БД
Этого вполне достаточно для аутентификации по следующему алгоритму:
1) Заносим в переменные логин и пароль
2) Получаем соединение с БД соответствующей функцией и заносим его в переменную
3) Используя соединение, а так же логин и пароль, производим поиск пользователя в БД.
Процедурный подход в этом случае довольно удачный выбор, но если нам придется расширить функционал, на пример добавив возможность привязки прав доступа к пользователю, а так же сообщение о отсутствии логина в базе и сообщение о неверном пароле, то число функций и переменных увеличится, а алгоритм станет более запутанным.
ООП позволяет не уменьшить число функций и переменных, а скорее сделать их более группированными. В нашем случае мы просто создаем три объекта:
1) Пользователь - объект содержит свойства (внутренние переменные): логин, пароль, права доступа, соединение БД - а так же методы (внутренние функции): аутентификация, определение прав доступа, деаутентификация, переименование пользователя и др;
2) БД - объект содержит свойство: соединение с БД - и метод: соединиться с БД. Объект передается другим объектам как обычная переменная, но при этом имеет связанную с ним функцию, а не свободную функцию засоряющую глобальное пространство имен;
3) Права доступа - объект содержи свойство: массив прав доступа.
Алгоритм тут будет довольно простым:
1) Создаем объект "БД" и соединяемся с его помощью с БД.
2) Создаем объект "Пользователь", передаем ему объект "БД" в качестве свойства "соединение БД"
3) Передаем объекту "Пользователь" логин и пароль в качестве соответствующих свойств
4) Аутентифицируем объект по средствам вызова его метода "Аутентификация"
5) Получаем права пользователя по средствам вызова метода объекта "Пользователь" "Определение прав доступа", при этом в свойстве "Права доступа", этого объекта, попадет объект "Права доступа" с массивом прав доступа данного пользователя.
Удобство этого подхода в том, что объекты, получив определенные свойства, могут распоряжаться ими как им удобно, на пример при получении прав доступа, объект "Пользователь", автоматически создает соответствующий объект с массивом прав используя логин, заданный ранее в свойстве "Логин" данного объекта. Уже нет необходимости создавать функцию, принимающую логин пользователя и соединение с БД для получения его прав доступа, все необходимые данные вшиты в объект.

Основные понятия ОО
Объектно ориентированный подход к программированию включает следующие понятия:
1) Класс - общий шаблон, описывающий какими свойствами и методами должны обладать объекты, созданные по его образу и подобию. Класс, в более обыденном смысле, это чертеж описывающий все данные о объекте. По этому чертежу и создаются объекты;
2) Объект - конкретный экземпляр класса. Объект имеет собственные свойства и методы, которые не зависят об других объектов того же класса. Другими словами данные в свойстве одного объекта, принадлежат только этому объекту и никакому другому;
3) Свойства - принадлежащие конкретному объекту переменные;
4) Методы - принадлежащие конкретному объекту функции.
И так обобщив вышеизложенное, скажем что объект, это конкретная реализация некоторого класса, с принадлежащими только ему свойствами и методами. Возможно такое определение слишком узкое и неверное, но для начала пойдет.

Инкапсуляция, наследование и полиморфизм по Русски
Чтобы никто не заснул на данной теме, буду описывать эти понятия в примерах.
И так.. Инкапсуляция это как дядя Федор из соседней квартиры, у него целая куча орденов и медалей (хотя никто не знает откуда они старому пьянице, не видавшему даже автомата, не то что военных действий), при чем они именно его и ни чьи другие, то есть именные (может быть, никто по пьяне не думал проверить). Инкапсуляция это принадлежность чего либо к объекту. Говорят что объект инкапсулирует свои свойства, когда хотят сказать что доступ к его свойства имеет только он, и никто другой. Для получения доступа к его свойствам медалям других пьяниц соседей, необходимо напоить и упросить дядю Федора (то есть вызвать определенные методы), иначе никак. Свойства как бы вшиты в объект, и получить их можно только по средствам вызова методов этого объекта.
Для чего это нужно? Ну по ассоциации с реальным миром, для изменения свойств реальных объектов (на пример трезвости дяди Федора), необходимо использовать определенные функции (спаивания и подбадривания), и невозможно непосредственно (без функций объекта) изменить трезвость дяди Федора свойства объекта.
[d]Наследование[/d] это генно-обусловленный механизм. Посмотрите на цвет своих глаз и волос, и цвет глаз и волос своих родителей. Заметны сходства. В ООП этот механизм используется для представления частности и общности. На пример возьмем нашу любимую ВАЗ-2109, со спойлером, дисками 18'', затемненными стеклами и нев*** аппаратурой. Этот объект является дочерним, по отношению к такому объекту, как легковые автомобили ВАЗ, а тот в свою очередь дочерним по отношению к легковым автомобилям. Если рассматривать их свойства дочерних и родительских объектов, можно заметить одну важную особенность: Собака[Цвет шерсти]->Водолазы[Цвет шерсти, длина шерсти, порода]->Ньюфаундленд[Цвет шерсти, длина шерсти, порода, родословная] - каждый дочерний объект использует и расширяет набор свойств родительского. Вот вам и наследование, только наследование не значений свойств, а самих свойств.
Полиморфизм это такая страшная вещь, которая позволяет использовать одни и те же функции, но для различных ситуаций. Так как это в островном встречается в языках более сложных, нежели PHP, особо вдаваться в подробности не буду, скажу лишь, что это позволяет объекту самому выбирать, какой из схожих методов использовать, в зависимости входных данных.

"Итерационный или инкрементарный?"
"Не пора бы уже о проектировании?" - Нет не пора ))
Дело в том, что проектирование (у меня), по мимо того, что объектно ориентированное, так еще и итерационно-инкрементарное!
Это значит, что мы сначала создаем простой шаблон системы, это первая итерация, затем выделяем часть и системы и работаем только с ней, это вторая итерация. При этом результат второй итерации дополняет и расширяет всю систему, то есть проявляется инкрементарность разработки (помним что такое инкремент?). Вот так вот сложный механизм выглядит изнутри. Зачем он нужен? Его плюсами являются то, что:
1) Каждая итерация четко ограничена в сроках (на пример за 4 недели нужно закончить механизм авторизации);
2) Она адаптивная за счет постоянного обратного отклика (то есть при завершении итерации, мы обязательно сверяемся результат с заказчиком и корректируем дальнейший план, а не делаем всю систему, и только потом показываем результат);
3) Она проста в реализации за счет разделения сложных задач на итерации.
Плюсов конечно намного больше, но не буду захламлять чужую БД )

Проектирование!
Наконец-то! Пришли к тому, ради чего все это и задумывалось! А нет.. Перейдем к вопросам проектирования в следующей статье )) Не ругайте сильно )
Добавил:
Рейтинг: +2
Просмотры: 1060
Комментарии (1) »