p align="left">Итак, обратимся к основным принципам ASP.NET 2.0. Чтобы не отходить от задач работы, сделаю на примере моего сайта. Первое и главное - это извечное «разделяй и властвуй». Если код на разных языках находится в одном файле (т.н. спагетти-код), это может означать неудачный выбор инструмента, или неумение им пользоваться (разумные исключения, конечно, приветствуются, нет смысла из-за двух строк на JavaScript заводить отдельный js-файл). В ASP.NET этот принцип реализован целиком и полностью. Весь код, который выполняется на сервере, лежит в отдельном от разметки страницы файле, именуемом codebehind-файлом. Этот код может быть написан на любом языке, более того, в одном проекте могут быть codebehind-файлы на разных.NET-совместимых языках (но это, вообще говоря, крайности). Класс страницы, описанный в codebehind-файле, реагирует на определённые события, таким как запрос страницы с сервера, загрузка её, рендеринг содержимого, нажатия кнопок и т.п. Всё, что требуется - это написать в обработчиках этих событий нужный код на любимом языке. Это не просто удобно, это эстетично. И самое главное - это читается! Программист, сопровождающий код, не должен будет сталкиваться со смесью разметки и кода (Вспомнилась цитата про PHP-программиста, который в одном файле писал на шести языках: русском, английском, PHP, HTML, JavaScript и SQL. При использовании ASP.NET это не грозит. Второе - это объектная ориентированность. Все страницы являются объектами своих классов. Важно, что элементы управления (кнопки, списки и т.п.) тоже являются объектами, и работа с ними соответственно упрощается. Серверному коду неинтересно, как они визуализируются браузером - каждый элемент управления уже умеет себя «рисовать»! Третье - это компромисс между браузерами. Всем, кто работал с веб, известно, что компании-производители тянут одеяло на себя и разные браузеры воспроизводят одинаковую разметку по-разному. Элементы управления ASP.NET умеют генерировать различный код дл различных браузеров. А для создаваемых вами элементов существует возможность задать, допустим, две ширины, для браузеров ie и для браузеров mozilla. Дальше идёт такая немаловажная вещь, как единообразие облика сайта. В лучших традициях объектно-ориентированного программирования дизайн страниц теперь наследуем и создав одну так называемую мастер-страницу, на остальных можно описывать только конкретные элементы, специфичные для данного раздела. Это достигается посредством размещения тегов <ContentPlaceHolder> на мастер-странице и <Content> на наследниках. Пользовательские элементы управления также имеют файл с разметкой и файл серверного кода. Замечательны они тем, что могут вставляться в неограниченном количестве (а также создаваться динамически) на любых страницах. Более глубокий объектно-ориентированный подход, применяемый мной на сайте, использует модель MVP (Model-View-Presenter), которая позволяет ещё сильнее разделить логику приложения. При обзоре взаимодействия компонентов на это будет обращено внимание. 1.2.3 Проектирование архитектуры сайта Начнём рассмотрение с самого верхнего уровня и будем спускаться ниже, изучая структуру сайта. На самом верхнем уровне лежит классическая модель клиент-сервер-БД, к которой добавлено несколько промежуточных уровней. Как видно из схемы, клиент взаимодействует с сервером ASP.NET через веб-сервер (IIS), который выполняет запросы к базе через подсистему NHibernate. Рассмотрим реализацию данной структуры более детально. Веб-интерфейс состоит из пяти проектов, каждому из которых отведена строго определённая роль. 1) Admin - проект, содержащий Windows-приложение - административную подсистему, служащую для управления содержимым базы данных. 2) BL - проект, содержащий бизнес-логику приложения, в том числе базовые классы и интерфейсы. 3) Core - проект, посвящённый объектной модели NHibernate и интерфейсам доступа к данным. 4) Data - проект содержит фабрику классов NHibernate и классы доступа к данным, реализующие интерфейсы из Core. 5) Собственно веб-сайт. Для того чтобы понять роль, отведённую основным классам проекта, необходимо обратиться к модели MVP (Model-View-Presenter), отлично ложащейся на веб-приложение. Смысл её в отделении Модели (в данном случае это размеченные классы под управлением NHibernate) от Представления (это классы, стоящие за codebehind-классами страниц и не знающие о них ничего, кроме интерфейсов) и от Вида - собственно codebehind-классов страниц, которые таким образом лишаются бизнес-логики, вынесенной в Представления и отвечают только за внешний вид страницы. Для того чтобы связать всё это воедино, служит базовый класс страницы BasePage из BL: public abstract class BasePage<TPresenter, TView>: Page, IView where TPresenter: IPresenter<TView>, new() where TView: IView { // ……… } Будучи параметризованным, этот класс снабжается типом своего конкретного Представления и типом интерфейса Вида, который нужен для создания Представления. Также класс содержит общие для всех страниц методы, что экономит код и в принципе является назначением базового класса. Помимо паттерна проектирования MVP одним из наиболее часто используемых паттернов является Singleton - паттерн, позволяющий иметь не более одного объекта заданного класса. Очень часто ограничения логики требуют явного указания того, что объект единственен в своём роде, как, например, колода карт в карточной игре. Параметризованный класс Singleton из BL позволяет «на лету» делать одиночку из любого класса, не внося в него изменения. Также сборка BL содержит Классы Представлений и интерфейсы Видов для всех страниц сайта и описание унаследованного элемента управления MegaPanel, позволяющего рендерить таблицы с оформленными рисунками (рамками) краями. Диаграмма классов сборки BL (часть классов Представлений опущена). ( Сборка Core содержит по одному интерфейсу на каждый объект модели DAO системы. Все интерфейсы произведены от базового интерфейса IDao, что позволяет экономить на их реализации. Пример интерфейса: public interface IDisciplineDao: IDao<Discipline, int> { } Как можно видеть, интерфейс для получения данных о дисциплинах из базы данных не содержит никаких методов, дополнительных к методам IDao. Однако для логически правильной объектной модели он необходим, к тому же если нам понадобится добавить, например, метод для извлечения только определённых дисциплин по какому-либо критерию, мы легко можем сделать это. Базовый интерфейс IDao даёт доступ к основным методам извлечения объектов из базы и записи в неё безотносительно к конкретному типу объекта. public interface IDao<T, IdT> { T GetById (IdT id, bool shouldLock); T GetFirst(); List<T> GetAll(); List<T> GetAllSorted (params Order[] orders); List<T> GetAllSorted (string propertyName, bool isAsc); List<T> GetByExample (T exampleInstance, params string[] propertiesToExclude); T Save (T entity); T SaveOrUpdate (T entity); void Delete (T entity); void CommitChanges(); } Интерфейс IDaoFactory даёт доступ к методам фабрики классов - ещё один используемый паттерн проектирования, - которые возвращают интерфейс объектов DAO. Ниже приводится диаграмма классов сборки Core. Сборка Data - это сердце управляющей системы NHibernate. Именно здесь расположены классы, отвечающие за установление соединения с базой и его поддержание, здесь же хранятся сами объекты DAO, предназначенные для извлечения данных из БД и за их размещение и изменение. Ниже приведена диаграмма классов сборки Data. Обратите внимание, как здесь органично находят применение интерфейсы из сборки Core. По идее из внешних сборок мы не должны видеть пространства имён и классы сборки Data, обращаясь к ней только через интерфейсы, описанные в Core. Архитектура самого сайта как веб-ориентированного приложения основывается на философии ASP.NET 2.0 (см. главу 2.3) и на описанных в главе 2.1 паттернах проектирования. В корневом каталоге размещаются файлы конфигурации и глобальный файл приложения, страница по умолчанию, служащая только для редиректа к основной структуре приложения, файл карты сайта и загрузчик изображений из базы, реализованный в виде веб-обработчика. Также имеются папки: - UI (User Interface) - папка, содержащая файлы разметки страниц и codebehind, а также css-файл со стилями и мастер-страницу, служащую для единообразного оформления (см. главу 2.3) - Resources - разнообразные ресурсы приложения, как доступные для скачивания.doc и другие файлы, так и изображения, используемые на сайте, а также справка по использования bb-code и конфигуратор bb-code дешифратора. 1.2.4 Алгоритмы работы административной подсистемы В этом разделе рассматривается не взаимодействие с пользователем (см. 1.2.2.), а принципы построения системы, позволяющие сделать её гибкой и настраиваемой. Основным классом, отвечающим за пользовательский интерфейс приложения, является класс EditorFrame, представляющий собой Windows-форму и параметризованный типом конкретного редактора. При создании объекта EditorFrame ему передаётся тип редактора (должен быть производным от базового типа BaseItemEditControl, который в свою очередь унаследован от UserControl), объект которого создаётся в конструкторе и встраивается в окно фрейма. Таким образом, после того как пользователь выберет тип редактируемой таблицы (группы таблиц) он получает сгенерированное окно с нужным редактором. Всё это возможно благодаря единообразию модели NHibernate DAO и системе.NET Reflection, которые вместе позволяют использовать неизвестные заранее классы, определяемые во время выполнения. Таким образом, мы имеем гибкую и простую в расширении систему, что доказывается тем, что она был написана мной для другого проекта и всего за вечер настроена для работы с новой базой, оставалось только написать конкретные редакторы, что, учитывая заложенное с помощью виртуальных методов единообразие, было рутинной задачей. И как всегда принципы повторного использования кода, заложенные в ООП, очень сильно упростили задачу. 1.2.5 Структура базы данных База данных с правильной структурой обеспечивает доступ к обновленным и точным сведениям. Поскольку правильная структура важна для выполнения поставленных задач при работе с базой данных, целесообразно изучить принципы создания баз данных. Это позволит создать базу данных в соответствии с требованиями и с возможностью быстро вносить в нее изменения. В основе процесса создания базы данных лежат определенные принципы. Первый принцип заключается в необходимости исключать повторяющиеся (или лишние) данные, т. к. они занимают место и повышают вероятность возникновения ошибок и неполадок. Второй принцип касается важной роли правильных и полных данных. Если база данных содержит неправильные данные, все отчеты, в которых данные объединяются, будут также содержать неверные сведения. Это может привести к принятию неправильных решений на основе отчетов. Правильная структура базы данных подразумевает: - распределение данных по тематическим таблицам в целях сокращения объема повторяющихся данных; - добавление данных, необходимых для объединения сведений, которые содержатся в таблицах; - возможность поддержания и отслеживания точности и целостности данных, соответствие требованиям к обработке данных. Процесс разработки Процесс разработки базы данных включает следующие шаги. - Определение цели создания базы данных Это позволяет подготовиться к выполнению следующих шагов. - Поиск и организация необходимых данных Следует собирать все данные, которые необходимо сохранить в базе данных - Распределение данных по таблицам Требуется распределить элементы данных по группам или темам. Для каждой темы будет создана таблица. - Преобразование элементов данных в столбцы Требуется определить, какие данные требуется хранить в каждой таблице. Каждый элемент данных будет введен в отдельное поле и станет столбцом таблицы. - Задание первичных ключей Следует выбрать первичные ключи таблиц. Первичный ключ - столбец для однозначного определения каждой записи, по соглашению не должен иметь отношения к данным таблицы и служить только для целей идентификации. Я использовал автоинкреметирующиеся целочисленные значения. - Создание связей между таблицами Следует проанализировать все таблицы и определить, как данные одной таблицы связаны с данными других таблиц. Может быть необходимым добавить в таблицы поля или создать новые таблицы для создания необходимых связей.
Страницы: 1, 2, 3, 4, 5, 6
|