Файл: Применение объектно-ориентированного подхода при проектировании информационной системы (ОБЪЕКТНО-ОРИЕНТИРОВАННЫЙ ПОДХОД).pdf
Добавлен: 02.07.2023
Просмотров: 33
Скачиваний: 2
Некоторые поисковые системы также извлекают данные из баз данных и каталогов ресурсов в Интернете.
Требования к поисковой системе:
- Простой и удобный HTML интерфейс.
- Поиск по форумам
- Релевантность по датам
- Морфологический анализ (выделение корня искомого слова)
Система должна представляет из себя простую поисковую машину для форумов с базой данных и запросами пользователя. На данном этапе поиск планируется производить по начальному списку заданных сайтов.
2.2 Описание решения разработки поисковой системы
Построение Базы данных поисковика имеет структуру конвейера. Каждый модуль представляет из себя отдельную утилиту. Различные утилиты могут быть написаны на различных языках. Они передают друг другу управление работы с данными. В данном случае можно было бы передавать сами данные через стандартный ввод-вывод. Но по причинам быстродействия это было сделано через загрузку на диск.
Тем более это позволило повысить устойчивость всей системы к сбоям. В случае падения или зависания одной из утилит это слабо повлияет на работу остальных. При восстановлении работы мы можем начать с того момента, на котором обработка оборвалась. Для удобства использования утилит используется управляющая программа, которая запускает последовательно каждую утилиту и на стандартный вывод ошибок выводит лог работы всей системы. В окошко вывода управляющей программы выводится этап обработки конкретного сайта.
Рисунок 1 – Порядок обработки сайта
Паук загружает содержимое сайта на диск. Индексатор вычленяет нужные страницы из файлов сайта и создает индекс. Индекс представляет из себя текстовый файл в формате: СЛОВО РЕЛЕВАНТНОСТЬ.
Релевантность определяется по дате сообщения форума. Схема с полной загрузкой достаточно не экономична. Возможно, намного логичнее было бы предавать страницы сайта непосредственно индексатору, вернее той его части, которая отвечает за вычленение нужной информации. Но это значительно бы навредило быстродействию, и как было сказано выше уменьшило бы отказоустойчивость. Текстовый файл индекса берет модуль морфологического анализа. Он сам является частью утилиты, которая на выходе подает БД для поисковой системы. Сначала производится морфоанализ, а на основе его результатов создается база данных слов. Эту базу данных можно добавить к общей БД поисковой системы на сервере.
Взаимодействие базы данных на сервере и Web-интерфейса осуществляется по следующей схеме рис. 2.
Рисунок 2 – Порядок взаимодействия базы данных на сервере и Web-интерфейса
Пользователь — человек, который пытается найти какое-то слово. Оператор — человек, который создаст базу данных по списку сайтов.
Таблица 1 - Схема базы данных
Сторона |
Утилита |
Модуль |
Пользователь |
http://gt.m-team.ru/ |
finderData |
na.viga.torDa.ta. |
||
htmlDcsign |
finderData формирует результат запроса. Работает он следующим образом: на вход ему подаются слова, выход — таблица, содержащая поля: название страницы, дата последнего сообщения и найденные слова в последнем сообщении. Эти таблицы имеют имена типа а_1, а_2, а_3 и т. д. и сохраняются в нашей базе. Следующее имя для таблицы хранится в специальном файле captionTable. После того, как таблица сохранена под своим именем, finderData стирает текущее имя из captionTable и записывает туда имя для следующей таблицы, которое формируется следующим образом: из старого имени берётся числовая часть, она находится в конце после подчёркивания, и инкрементируется, после этого перед ней приписывается а_.
Для создания таблицы используются SQL запросы. Запросы формируются таким образом, чтобы было как можно меньше обращений к серверу БД. Эти запросы имеют следующий вид:
insert into table values (1, 2, 3), (4, 5, 6), (7, 8, 9).
За счёт того, что команда insert поддерживает такой синтаксис, мы можем за одно обращение к БД создать сразу всю таблицу результата.
navigatorData объекты этого класса позволяют отображать на экран какой-то кусок таблицы результатов. Получив имя таблицы, количество ссылок на страницы и количество записей в таблицы результатов, navigatorData выдаёт строки, которые потом можно как-либо отобразить, текущую страницу для подсветки, и количество страниц.
htmlDesign предназначен для оформления результата в виде html-страницы. Получив сведения от navigatorData, htmlDcsign генерит html код. Поскольку у страницы может быть лишь один дизайн, этот класс спроектирован таким образом, что можно создать лишь один экземпляр этого класса.
Взаимодействие объектов этих классов происходит следующем образом: слова, кото рыс ввёл пользователь для поиска сначала отдаются на обработку объекту, который сопоставляет слову определённую лексему (это нужно чтобы избавиться от проблемы окончаний, суффиксов и прочего). Затем эти лексемы идут к объекту flnderData, который создаёт таблицу результатов и возвращает её имя и количество записей. Эти данные идут к объекту navigatorData. Он по ним определяет возможное количество страниц и выдаёт строки, содержащие ссылку, дату, слова сообщения. Эти строки переходят на обработку объекту htmlDesign, который формирует страницу для браузера. Так работает скрипт, если нажать кнопку поиска. Если же происходит перемещение по страницам, то объект finderData нам не нужен и он не создаётся.
Основная база данных имеет простую схему с тремя таблицами. Достаточно очевидно, как связаны между собой – рис. 3.
Рисунок 3 –Связь база данных
WORDS:
id слова (ключ) само слово
PAGES:
id страницы (ключ) адрес страницы
DATA:
календарная дата (юн id слова id страницы
Для того, чтобы не осуществлять повторный поиск для часто запрашиваемого слова, временно создается другая вспомогательная база данных.
ТАБЛИЦЫ РЕЗУЛЬТАТОВ ("а_+"): список слов (ключ) адрес страницы дата
CORRESPONDENCE:
список слов (ключ) название таблицы результатов
Таблица 2 - Использованные шаблоны проектирования
Шаблон Что |
Где |
Зачем |
|
Singleton |
класс Config |
в модуле config в утилите indexer.py |
Конфигурация утилиты происходит один раз, на старте. Ее результаты могут быть использованы в любых модулях. |
класс htmlDcsign |
в Web-интерфейсе |
Поскольку у страницы может быть лишь один дизайн, этот класс спроектирован таким образом, что можно создать лишь один экземпляр этого класса. |
|
Адаптер |
класс Module |
в модуле Module в утилите main.py |
Класс Module использует уже существующий стандартный класс subproccss.Popcn. Но стандартный класс, не смотря на заявленную кросс-платформенность, не всегда работает на различных системах, это было исправлено в Module (в частности метод kill для ОС Windows). subprocess.Popen no-умолчанию запускает вызовы как консольное приложении, в Module это было заменено на «оконный старт». В результате у пользователя не возникает много лишних «черных окон». |
Продолжение табл. 2.
Ленивая инициализация |
Леммы из таблиц загружаются только по требованию (см. описание crawler) |
в crawler, php |
Леммы загружаются только по требованию, то есть файл с леммами начинающимися на соответствующую букву, загружается только если в запросе есть слово начинающееся с данной буквы. Это значительно ускорило быстро действие программы. |
класс finderData |
в Web-интерфейсе |
Нам не нужен объект finderData если мы не выполняем поиск, а просто перемещаемся по таблицам. |
|
Фасад |
класс RcgExpr |
в модуле RcgExpr в утилите indexer.py |
Нужно было некоторым образом обернуть, стандартные функции для работы с регулярными выражениями. Таскать их в естественном виде было бы громоздко и нечитаемое. |
Состояние |
Core |
в модуле Core в утилите main.py |
Core меняет свое поведение (action F() ), в зависимости от состояния своего сайтов из свое словаря. По-хорошему поведение должен менять сам сайт, но во избегания перепроектирования мы не создавали отдельно такого класса. |
Можно описать шаблоны, которые использовались, при создании графической оболочки, но это уже не наши шаблоны а шаблоны QT.
Интерфейс программы
1 Web
Сам поисковик имеет Web-интерфейс. Он доступен по адресу http: //gt. m-team. ru/.
Рис. 4 - окошко браузера, на сайте gt-mteam.ru до ввода искомого слова
Рис. 5 - Окошко браузера на сайте gt-mtcam.ru после того как искомое слово было найдено
2 Интерфейс конвейра
Для удобства использования утилит используется управляющая программа, которая запускает последовательно каждую утилиту и на стандартный вывод ошибок выводит лог работы всей системы. В окошко вывода управляющей программы выводится этап обработки конкретного сайта. У сайта может есть 4 атрибута:
Скачан / Не скачан
Проиндексирован / Не проиндексирован
Создана БД / Не создана БД
БД послана на сервер / БД не послана на сервер
Последний параметр является фиктивным. Пока нами не реализована посылка БД на сервер и в ближайшее время вряд ли будет. Но сама идея полной автоматики весьма заманчива и потому мы решили оставить этот параметр до лучших времен. На данный момент сами БД приходится загружать вручную.
Для управляющей программы можно ввести, что она будет использовать в качестве утилит скачки, индексации, создания БД. При желании пользователь сможет написать свои и их использовать.
Имена утилит можно запомнить «Меню Файл / Загрузить параметры » или сохранить «Меню Файл / Сохранить параметры ». Утилиты при этом сохраняются в файл в расширении «programs.ini», который можно редактировать. При старте программы имена утилит исключительно берутся из него. Настройки интерфейса программы хранятся в файле «coring.ini» Галочки у кнопок «Открыть» означают блокировку этих кнопок. При быстрой и напряженной работе оператора это бывает удобно.
Чтобы начать индексацию некоторого списка сайтов достаточно создать текстовый файл с их именами. А потом воспользоваться «Меню Файл / Открыть список сайтов ». При этом, в папке с текущем списком сайтов создастся файл со словарем, который также можно просматривать и редактировать от запуска к запуску. Словарь содержит имя и атрибуты каждого сайта.
Для успокоения пользователя окно управляющей программы снабжено индикаторами процесса, которые показывают прогресс. Прогресс вычисляется на по атрибутам сайтов.
3 Управляющая программа во время работы. Снимки – рис. 6.
Рис. 6 – Снимки управляющей программы
Тестирование
1 Модульное тестирование
При отладке индексатора использовалось модульное тестирование, в частности тестировался класс DatcFindcr. Модульное тестирование позволяет проверить на корректность отдельные модули исходного кода программы. Идея состоит в том, чтобы писать тесты для каждой нетривиальной функции или метода. Это позволяет достаточно быстро проверить, не привело ли очередное изменение кода к регрессии, то есть к появлению ошибок в уже написанных и оттестированных местах программы, а также облегчает обнаружение и устранение таких ошибок. Опишем работу модульного теста на тривиальном примере с одним тестирующим методом:
from Date import DatcFindcr
import unittest
4 class TestDateFinder (unittest.TestCase):
5 def sctUp(sclf):
6 sclf.dateFinder = DateFindcr ()
7
8 def test Year (self):
9 is_year=self.dateFinder.is Year (2009)
10 self.assertEqual(is_ycar, True)
11
12 if name = " main ":
13 unittest .main ()
Модуль unittest входит в стандартную библиотеку Python и служит базовым инструментом для организации регрессионных unit-тестов. Для того чтобы использовать все возможности модульных тестов, тестирующий класс необходимо унаследовать от базового — unittest.Case. Метод setUpQ — служебный. Он вызывается перед запуском каждого теста и подготавливает среду выполнения. В нашем случае метод sctUpQ просто создает экземпляр класса DateFindcr. Имена остальных методов начинаются с «test» (необходимое условие для нахождения тестов в коде модуля). Если запустить наш тестирующий модуль получим следующее:
1 .
2
3 Ran I test in 0.016s
4
5 OK
Что означает, что все тесты выполнены успешно.
Как и любая технология тестирования, модульное тестирование не позволяет отловить все ошибки программы. В самом деле, это следует из практической невозможности трассировки всех возможных путей выполнения программы, за исключением простейших случаев. Кроме того, происходит тестирование каждого из модулей по отдельности. Это означает, что ошибки интеграции, системного уровня, функций, исполняемых в нескольких модулях, не будут определены. Кроме того, данная технология бесполезна для проведения тестов на производительность. Таким образом, модульное тестирование более эффективно при использовании в сочетании с другими методиками тестирования, например функциональным.
Функциональное тестирование — это тестирование ПО в целях проверки реализуемости функциональных требований, т.е. способности ПО в определенных условиях решать задачи, нужные пользователям. Функциональные требования определяют, что именно делает ПО, какие задачи оно решает. В нашем случае функциональным тестом являлся запуск индексатора на нескольких уже выкаченных сайтах и визуальная проверка результатов его работы, т. е. проверялось корректность выделения слов и правильность соответствующих дат путем сравнения с исходными html-страницами. Проверять автоматически в данном случае не актуально, так как, при этом подразумевается тестирование на каких-либо тривиальных примерах, с уже строго известным результатом. Но индексатор предназначен для работы с html-страницами, имеющими сложную структуру, что преобладает на практике, и тестировать нужно именно на реальных документах, кроме того он может допускать некий процент ошибок из-за слишком нестандартного оформления сайтов и т. п.