Архитектура корпоративных программных приложений - файл n1.doc
приобрестиАрхитектура корпоративных программных приложенийскачать (3538.7 kb.)
Доступные файлы (1):
n1.doc

Архитектура корпоративных программных приложений
ИСПРАВЛЕННОЕ ИЗДАНИЕ
Мартин Фаулер
при участии
Москва • Санкт-Петербург • Киев
2006
Дейвида Раиса, Мэттыо Фоммела, Эдварда Хайета, Роберта Ми и Рэнди Стаффорда
УДК 681.3.07
Ф28 ББК 32.973.26-018.2.75
Издательский дом "Вильяме'
По общим вопросам обращайтесь в Издательский дом "Вильяме" по
адресу: info@williamspublishing.com, http://www.williamspublishing.com 115419, Москва, а/я 783; 03150, Киев, а/я 152
Фаулер, Мартин.
Ф28 Архитектура корпоративных программных приложений.: Пер.
с англ. —
М.: Издательский дом "Вильяме", 2006. — 544 с.: ил. — Парал. тит. англ.
ISBN 5-8459-0579-6 (рус.)
Создание компьютерных систем — дело далеко не простое. По мере того как возрастает их сложность, процессы конструирования соответствующего программного обеспечения становятся все более трудоемкими, причем затраты труда растут экспоненциально. Как и в любой профессии, прогресс в программировании достигается исключительно путем обучения, причем не только на ошибках, но и на удачах — как своих, так и чужих. Книга дает ответы на трудные вопросы, с которыми приходится сталкиваться всем разработчикам корпоративных систем. Автор, известный специалист в области объектно-ориентированного программирования, заметил, что с развитием технологий базовые принципы проектирования и решения общих проблем остаются неизменными, и выделил более 40 наиболее употребительных подходов, оформив их в виде типовых решений. Результат перед вами — незаменимое руководство по архитектуре программных систем для любой корпоративной платформы. Это своеобразное учебное пособие поможет вам не только усвоить информацию, но и передать полученные знания окружающим значительно быстрее и эффективнее, чем это удавалось автору. Книга предназначена для программистов, проектировщиков и архитекторов, которые занимаются созданием корпоративных приложений и стремятся повысить качество принимаемых стратегических решений.
ББК 32.973.26-018.2.75 Все названия программных продуктов являются зарегистрированными торговыми марками соответствующих фирм.
Никакая часть настоящего издания ни в каких целях не может быть воспроизведена в какой бы то ни было форме и какими бы то ни было средствами, будь то электронные или механические, включая фотокопирование и запись на магнитный носитель, если на это нет письменного разрешения издательства Pearson Education, Inc.
Authorized translation from the English language edition published by Pearson Education, Inc., Copyright © 2003 All rights reserved. No part of this book may be reproduced or transmitted in any form or by any means, electronic or mechanical, including photocopying, recording or by any information storage retrieval system, without permission from the Publisher.
Russian language edition published by Williams Publishing House according to the Agreement with R&I Enterprises International, Copyright © 2006
!srn olf ml?1 ,
(РУС-\ ° И^ьский дом "Вильяме", 2006
ISBN 0-321-12742-0 (англ.) ©
Peaison Educationj Inc ,
2003 Оглавление Предисловие 17
Введение 27
Часть I. Обзор 41
Глава 1. "Расслоение" системы 43
Глава 2. Организация бизнес-логики 51
Глава 3. Объектные модели и реляционные базы данных 59
Глава 4. Представление данных в Web 81
Глава 5. Управление параллельными заданиями 87
Глава 6. Сеансы и состояния 105
Глава 7. Стратегии распределенных вычислений 111
Глава 8. Общая картина 119
Часть П.
Типовые решения 131
Глава 9. Представление бизнес-логики 133
Глава 10. Архитектурные типовые решения источников данных 167
Глава 11. Объектно-реляционные типовые решения,
предназначенные для моделирования поведения 205
Глава 12. Объектно-реляционные типовые решения,
предназначенные для моделирования структуры 237
Глава 13. Типовые решения объектно-реляционного отображения
с использованием метаданных 325
Глава 14. Типовые решения, предназначенные
для представления данных в Web 347
Глава 15. Типовые решения распределенной обработки данных 405
Глава 16. Типовые решения для обработки задач автономного параллелизма 433
Глава 17. Типовые решения для хранения состояния сеанса 473
Глава 18. Базовые типовые решения 483
Список основных источников информации 527
Предметный указатель 532
Содержание Предисловие Введение
Часть I. Обзор
41 Глава 1. "Расслоение" системы 43
Развитие модели слоев в корпоративных профаммных приложениях 44
Три основных слоя 46
Где должны функционировать слои 48
Глава 2. Организация бизнес-логики 51
Выбор типового решения 55
Уровень служб 56
Глава 3. Объектные модели и реляционные базы данных 59
Архитектурные решения 59
Функциональные проблемы 64
Считывание данных 66
Взаимное отображение объектов и реляционных структур 67
Отображение связей 67
Наследование 71
Реализация отображения 73
Двойное отображение 74
Использование метаданных 75
Соединение с базой данных 76
Другие проблемы 78
Дополнительные источники информации 79
Глава 4. Представление данных в Web 81
Типовые решения представлений 84
Типовые решения входных контроллеров 86
Дополнительные источники информации 86
Содержание 7
Глава 5. Управление параллельными заданиями 87
Проблемы параллелизма 88
Контексты выполнения 89
Изолированность и устойчивость данных 91
Стратегии блокирования 91
Предотвращение возможности несогласованного чтения данных 93
Разрешение взаимоблокировок 94
Транзакции 95
ACID: свойства транзакций 96
Ресурсы транзакций 96
Уровни изоляции 97
Системные транзакции и бизнес-транзакции 99
Типовые решения задачи обеспечения автономного параллелизма 101
Параллельные операции и серверы приложений 102
Дополнительные источники информации 104
Глава 6. Сеансы и состояния 105
В чем преимущество отсутствия "состояния" 105
Состояние сеанса 107
Способы сохранения состояния сеанса 108
Глава 7. Стратегии распределенных вычислений 111
Соблазны модели распределенных объектов 111
Интерфейсы локального и удаленного вызова 112
Когда без распределения не обойтись 114
Сужение границ распределения 115
Интерфейсы распределения 116
Глава 8. Общая картина 119
Предметная область 120
Источник данных 121
Источник данных для сценария транзакции 121
Источник данных для модуля таблицы 122
Источник данных для модели предметной области 122
Слой представления 123
Платформы и инструменты 124
JavanJ2EE 124
.NET 125
Хранимые процедуры 126
Web-службы 126
Другие модели слоев 127
8 Содержание
Часть II. Типовые решения
Глава 9. Представление бизнес-логики
133
Сценарий транзакции (Transaction Script) _
Принцип действия
Назначение "
Задача определения зачтенного дохода
Пример: определение зачтенного дохода (Java)
Модель предметной области (Domain Model)
Принцип действия
Назначение '
4->
Дополнительные источники информации '43
Пример: определение зачтенного дохода (Java) 144
Модуль таблицы (Table Module) 148
Принцип действия 149
Назначение 151
Пример: определение зачтенного дохода (С#) 152
Слой служб (Service Layer) 156
Принцип действия 157
Разновидности "бизнес-логики" 157
Варианты реализации 157
Быть или не быть удаленному доступу 158
Определение необходимых служб и операций 158
Назначение 160
Дополнительные источники информации 160
Пример: определение зачтенного дохода (Java) 161
Глава 10. Архитектурные типовые решения источников данных 167
Шлюз таблицы данных (Table Data Gateway) 167
Принцип действия 167
Назначение 168
Дополнительные источники информации 169
Пример: класс PersonGateway (C#) 170
Пример: использование объектов ADO.NET DataSet (C#) 172
Шлюз записи данных (Row Data Gateway) 175
Принцип действия 175
Назначение 176
Пример: запись о сотруднике (Java) 178
Пример: использование диспетчера данных для объекта домена (Java) 181
Активная запись (Active Record) 182т
Принцип действия 182
Назначение 184
Пример: простой класс Person (Java)
184 Преобразователь данных (Data Mapper) 187
Принцип действия 187
Обращение к методам поиска 190
Содержание 9
Отображение данных на поля объектов домена 191
Отображения на основе метаданных 192
Назначение 192
Пример: простой преобразователь данных (Java) 193
Пример: отделение методов поиска (Java) 198
Пример: создание пустого объекта (Java) 201
Глава П. Объектно-реляционные типовые решения, предназначенные для моделирования поведения 205
Единица работы (Unit of Work) 205
Принцип действия 206
Назначение 211
Пример: регистрация посредством изменяемого объекта (Java) 212
Коллекция объектов (Identity Map) 216
Принцип действия 216
Выбор ключей 217
Явная или универсальная? 217
Сколько нужно коллекций? 217
Куда их поместить? 218
Назначение 219
Пример: методы для работы с коллекцией объектов (Java) 219
Загрузка по требованию (Lazy Load) 220
Принцип действия 221
Назначение 223
Пример: инициализация по требованию (Java) 224
Пример: виртуальный прокси-объект (Java) 224
Пример: использование диспетчера значения (Java) 226
Пример: использование фиктивных объектов (С#) 227
Глава 12. Объектно-реляционные типовые решения, предназначенные для моделирования структуры 237
Поле идентификации (Identity Field) 237
Принцип действия 237
Выбор ключа 238
Представление поля идентификации в объекте 239
Вычисление нового значения ключа 240
Назначение 242
Дополнительные источники информации 243
Пример: числовой ключ (С#) 243
Пример: использование таблицы ключей (Java) 244
Пример: использование составного ключа (Java) 246
Класс ключа 246
Чтение 249
Вставка 252
Обновление и удаление 256
Отображение внешних ключей (Foreign Key Mapping) 258
Принцип действия 258
Назначение 261
10 Содержание
Пример: однозначная ссылка (Java) 262
Пример: многотабличный поиск (Java) 265
Пример: коллекция ссылок (С#) 266
Отображение с помощью таблицы ассоциаций
(Association Table Mapping) 269
Принцип действия 270
Назначение 270
Пример: служащие и профессиональные качества (С#) 271
Пример: использование SQL для непосредственного обращения
к базе данных (Java) 274
Пример: загрузка сведений о нескольких служащих посредством
одного запроса (Java) 278
Отображение зависимых объектов
(Dependent Mapping) 283
Принцип действия 283
Назначение 285
Пример: альбомы и композиции (Java) 285
Внедренное значение (Embedded Value) 288
Принцип действия 289
Назначение 289
Дополнительные источники информации 290
Пример: простой объект-значение (Java) 290
Сериализованный крупный объект
(Serialized LOB) 292
Принцип действия 292
Назначение 294
Пример: сериализация иерархии отделов
в формат XML (Java) 294
Наследование с одной таблицей (Single
Table Inheritance) 297
Принцип действия 298
Назначение 298
Пример: общая таблица игроков (С#) 299
Загрузка объекта из базы данных 301
Обновление объекта 303
Вставка объекта 303
Удаление объекта 304
Наследование с таблицами для
каждого класса (Class Table Inheritance) 305
Принцип действия 305
Назначение 306
Дополнительные источники
информации 307
Пример: семейство игроков (С#) 307
Загрузка объекта 307
Обновление объекта 310
Вставка объекта 311
Удаление объекта 312
Наследование с таблицами для
каждого конкретного класса (Concrete Table Inheritance) 313
Принцип действия 314
Назначение 315
Содержание 11
Пример: конкретные классы игроков (С#) 316
Загрузка объекта из базы данных 318
Обновление объекта 320
Вставка объекта 320
Удаление объекта 321
Преобразователи наследования (Inheritance Mappers) 322
Принцип действия . 323
Назначение 324
Глава 13. Типовые решения объектно-реляционного отображения с использованием метаданных 325
Отображение метаданных (Metadata Mapping) 325
Принцип действия 326
Назначение 327
Пример: использование метаданных и метода отражения (Java) 328
Хранение метаданных 328
Поиск по идентификатору 330
Запись в базу данных 332
Извлечение множества объектов 334
Объект запроса (Query Object) 335
Принцип действия 336
Назначение 337
Дополнительные источники информации 337
Пример: простой объект запроса (Java) 337
Хранилище (Repository) 341
Принцип действия 342
Назначение 343
Дополнительные источники информации 344
Пример: поиск подчиненных заданного сотрудника (Java) 344
Пример: выбор стратегий хранилища (Java) 345
Глава 14. Типовые решения, предназначенные для представления данных в Web 347
Модель-представление—контроллер (Model View Controller) 347
Принцип действия 348
Назначение 350
Контроллер страниц (Page Controller) 350
Принцип действия 351
Назначение 352
Пример: простое отображение с помощью контроллера-сервлета
и представления JSP (Java) 352
Пример: использование страницы JSP в качестве обработчика запросов (Java) 355
Пример: обработка запросов страницей сервера с применением
механизма разделения кода и представления (С#) 358
Контроллер запросов (Front Controller) 362
Принцип действия 362
Назначение 364
12 Содержание
Дополнительные источники информации 364
Пример: простое отображение (Java) 365
Представление по шаблону (Template View) 368
Принцип действия 369
Вставка маркеров 369
Вспомогательный объект 370
Условное отображение 370
Итерация 371
Обработка страницы 372
Использование сценариев 372
Назначение 372
Пример: использование страницы JSP в качестве представления
с вынесением контроллера в отдельный объект (Java) 373
Пример: страница сервера ASP.NET (С#) 375
Представление с преобразованием (Transform View) 379
Принцип действия 379
Назначение 380
Пример: простое преобразование (Java) 381
Двухэтапное представление (Two Step View) 383
Принцип действия 383
Назначение 385
Пример: двухэтапное применение XSLT (XSLT) 390
Пример: страницы JSP и пользовательские дескрипторы (Java) 393
Контроллер приложения (Application Controller) 397
Принцип действия 398
Назначение 400
Дополнительные источники информации 400
Пример: модель состояний контроллера приложения (Java) 400
Глава 15. Типовые решения распределенной обработки данных 405
Интерфейс удаленного доступа (Remote Facade) 405
Принцип действия 406
Интерфейс удаленного доступа и типовое решение интерфейс сеанса
(Session Facade) 409
Слой служб 409
Назначение 410
Пример: использование компонента сеанса Java
в качестве интерфейса удаленного доступа
(Java) 410
Пример: Web-служба (С#) 414
Объект переноса данных (Data Transfer Object) 419
Принцип действия 419
Сериализация объекта переноса данных 421
Сборка объекта переноса данных из объектов домена 423
Назначение 424
Дополнительные источники информации 424
Пример: передача информации об альбомах (Java) 425
Пример: сериализация с использованием XML (Java) 429
Содержание 13
Глава 16. Типовые решения для обработки задач автономного параллелизма 433
Оптимистическая автономная блокировка (Optimistic Offline Lock) 434
Принцип действия 435
Назначение 439
Пример: слой домена с преобразователями данных (Java) 439
Пессимистическая автономная блокировка (Pessimistic Offline Lock) 445
Принцип действия 446
Назначение 450
Пример: простой диспетчер блокировки (Java) 450
Блокировка с низкой степенью детализации (Coarse-Grained Lock) 457
Принцип действия 457
Назначение 460
Пример: обшая оптимистическая автономная блокировка (Java) 460
Пример: обшая пессимистическая автономная блокировка (Java) 466
Пример: оптимистическая автономная блокировка корневого элемента (Java) 467
Неявная блокировка (Implicit Lock) 468
Принцип действия 469
Назначение 470
Пример: неявная пессимистическая автономная блокировка (Java) 470
Глава 17. Типовые решения для хранения состояния сеанса 473
Сохранение состояния сеанса на стороне клиента (Client Session State) 473
Принцип действия 473
Назначение 474
Сохранение состояния сеанса на стороне сервера (Server Session State) 475
Принцип действия 475
Назначение 478
Сохранение состояния сеанса в базе данных (Database Session State) 479
Принцип действия 479
Назначение 481
Глава 18. Базовые типовые решения 483
Шлюз (Gateway) 483
Принцип действия 484
Назначение 484
Пример: создание шлюза к службе отправки сообщений (Java) 485
Преобразователь (Mapper) 489
Принцип действия 490
Назначение 490
Супертип слоя (Layer Supertype) 491
Принцип действия 491
Назначение 491
Пример: объект домена (Java) 491
Отделенный интерфейс (Separated Interface) 492
Принцип действия 493
Назначение 494
14 Содержание
Реестр (Registry) 495
Принцип действия 495
Назначение 497
Пример: реестр с единственным экземпляром (Java) 498
Пример: реестр, уникальный в пределах потока (Java) 499
Объект-значение (Value Object) 500
Принцип действия 501
Назначение 502
Совпадение названий 502
Деньги (Money) 502
Принцип действия 503
Назначение 506
Пример: класс Money (Java) 506
Частный случай (Special Case) 511
Принцип действия 512
Назначение 512
Дополнительные источники информации 512
Пример: объект NullEmployee (C#) 513
Дополнительный модуль (Plugin) 514
Принцип действия 514
Назначение 515
Пример: генератор идентификаторов (Java) 516
Фиктивная служба (Service Stub) 519
Принцип действия 519
Назначение 520
Пример: служба определения величины налога (Java) 521
Множество записей (Record Set) 523
Принцип действия 524
Явный интерфейс 524
Назначение 526
Список основных источников информации 527
Предметный указатель 532
Предисловие Весной 1999 года меня пригласили в Чикаго для консультаций по одному из проектов, осуществляемых силами ThoughtWorks — небольшой, но быстро развивавшейся компании, которая занималась разработкой программного обеспечения. Проект был достаточно амбициозен: речь шла о создании корпоративного лизингового приложения уровня сервера, которое должно было охватывать все аспекты проблем имущественного найма, возникающих после заключения договора: рассылку счетов, изменение условий аренды, предъявление санкций нанимателю, не внесшему плату в установленный срок, досрочное возвращение имущества и т.п. Все это могло бы звучать не так уж плохо, если не задумываться над тем, сколь разнообразны и сложны формы соглашений аренды. "Логика" бизнеса редко бывает последовательна и стройна, так как создается деловыми людьми для ситуаций, в которых какой-нибудь мелкий случайный фактор способен обусловить огромные различия в качестве сделки — от полного краха до неоспоримой победы.
Это как раз те вещи, которые интересовали меня прежде и не перестают волновать поныне: как прийти к системе объектов, способной упростить восприятие конкретной сложной проблемы. Я действительно убежден, что основное преимущество объектной парадигмы как раз и состоит в облегчении понимания запутанной логики. Разработка хорошей
модели предметной области (Domain Model, 140)1 для изощренной проблемы реального бизнеса весьма трудна, но ее решение приносит громадное удовлетворение.
Модель предметной области — это, однако, еще не все. Нашу модель следовало отобразить в базе данных. Как и во многих других случаях, мы использовали реляционную СУБД. Необходимо было снабдить решение пользовательским интерфейсом, обеспечить поддержку удаленных приложений и интеграцию со сторонними пакетами — и все это с привлечением новой технологии под названием J2EE, с которой никто не умел обращаться.
Несмотря на все трудности, мы обладали большим преимуществом— обширным опытом. Я длительное время проделывал аналогичные вещи с помощью C++, Smalltalk и CORBA. Многие члены команды ThoughtWorks в свое время серьезно поднаторели в Forte. В наших головах уже вертелись основные архитектурные идеи, оставалось только выплеснуть их на холст J2EE. (Теперь, по прошествии трех лет, я могу констатировать, что проект не блистал совершенством, но проверку временем выдержал очень хорошо.)
Для разрешения именно таких ситуаций и была задумана эта книга. На протяжении долгого времени мне доводилось иметь дело с массой корпоративных профаммных приложений. Эти проекты часто основывались на сходных идеях, эффективность которых
'

Таким образом обозначается ссылка на страницу книги, где описано указанное типовое решение.
18 Предисловие
была доказана при решении сложных проблем, связанных с управлением на уровне предприятия. В книге делается попытка представить подобные проектные подходы в виде
типовых решений (patterns). Книга состоит из двух частей. Первая содержит несколько ознакомительных глав с описанием ряда важных тем, имеющих отношение к сфере проектирования корпоративных приложений. Здесь бегло формулируются различные проблемы и варианты их решения. Все подробности и нюансы вынесены в главы второй части. Эту информацию уместно трактовать как справочную, и я не настаиваю на том, чтобы вы штудировали ее от начала до конца. На вашем месте я поступил бы так: детально ознакомился с материалом первой части для максимально полного понимания предмета и обратился к тем главам или типовым решениям из второй части, близкое знакомство с которыми действительно необходимо. Поэтому книгу можно воспринимать как краткий учебник (часть I), дополненный более увесистым руководством (часть II).
Итак, наше издание посвящено проектированию корпоративных программных приложений. Подобные приложения предполагают необходимость отображения, обработки и сохранения больших массивов (сложных) данных, а также реализации моделей бизнес-процессов, манипулирующих этими данными. Примерами могут служить системы бронирования билетов, финансовые приложения, пакеты программ торгового учета и т.п. Корпоративные приложения имеют ряд особенностей, связанных с подходами к решению возникающих проблем: они существенным образом отличаются от встроенных систем, систем управления, телекоммуникационных приложений, программных продуктов для персональных компьютеров и т.д. Поэтому, если вы специализируетесь в каких-либо "иных" направлениях, не связанных с корпоративными системами, эта книга, вероятно, не для вас (хотя, может быть, вам просто хочется "вкусить" нового?). За общей информацией об архитектуре программного обеспечения рекомендую обратиться к работе [33].
Проектирование корпоративных приложений сопряжено со слишком большим числом проблем архитектурного толка, и книга, боюсь, не сможет дать исчерпывающих ответов на все. Я поклонник итеративного подхода к созданию программного обеспечения. А сердцем концепции итеративной разработки является положение о том, что пользователю следует показывать первые, пусть не полные, результаты, если в них есть хоть толика здравого смысла. Хотя между написанием программ и книг существуют, мягко говоря, заметные различия, мне хотелось бы думать, что эта — далеко не всеобъемлющая — книга все-таки окажется своего рода конспектом полезных и поучительных советов. В ней освещаются следующие темы:
"расслоение" приложения по уровням;
структурирование логики предметной области;
разработка пользовательского Web-интерфейса;
связывание модулей, размещаемых в памяти (в частности, объектов), с реляцион
ной базой данных;
принципы распределения программных компонентов и данных.
Список тем, которых мы
не будем касаться, разумеется, гораздо обширнее.
Помимо всего остального, я предполагал обсудить вопросы проверки структуры, обмена сообщениями, асинхронных коммуникаций, безопасности, обработки ошибок, кластеризации, интеграции приложений, структурирования интерфейсов "толстых" клиентов
Предисловие 19
и прочее. Но ввиду ограничений на объем, отсутствия времени и нехватки оформившихся идей мне это не удалось. Остается надеяться, что в недалеком будущем какие-либо типовые решения в этих областях все-таки появятся. Возможно, когда-нибудь выйдет второй том книги, который вберет в себя все новое, или кто-то другой возьмет на себя труд заполнить эти и другие пробелы.
Среди всего перечисленного наиболее важной и сложной является проблема поддержки системы асинхронных коммуникаций, основанной на сообщениях. Особо острую форму она принимает при необходимости интефации многих приложений (да и вариант системы коммуникаций для отдельно взятого приложения также "подарком" не назовешь).
В намерения автора
не входила ориентация на какую бы то ни было конкретную про-фаммную платформу. Рассматриваемые типовые решения прошли первое испытание в конце 1980-х и начале 1990-х годов, когда я работал с C++, Smalltalk и CORBA. В конце 1990-х я начал интенсивно использовать Java и обнаружил, что те же подходы оказались приемлемыми при реализации и ранних гибридных систем Java/CORBA, и более поздних проектов на основе стандарта J2EE. Недавно я стал присматриваться к платформе Microsoft .NET и пришел к заключению, что решения вновь вполне применимы. Мои коллеги по ThoughtWorks подтвердили аналогичные выводы в отношении Forte. Я не собираюсь утверждать, что то же справедливо для
всех платформ, современных и будущих, используемых для развертывания корпоративных приложений, но до сих пор дело обстояло именно так.
Описание большинства типовых решений сопровождается примерами кода. Выбор языка профаммирования обусловлен только вероятными предпочтениями читателей. Java в этом смысле выглядит наиболее привлекательно. Всякий, кто знаком с С или C++, разберется и в Java; кроме того, Java намного проще, нежели C++. Практически любой профаммист, использующий C++, способен воспринимать Java-код, но не наоборот. Я стойкий приверженец объектной парадигмы, поэтому речь могла идти только об одном из объектно-ориентированных языков. Итак, примеры написаны преимущественно на языке Java. Период работы над книгой совпал с этапом становления среды .NET и системы профаммирования С#, которая, по моему мнению, обладает многими свойствами, присущими Java. Поэтому я реализовал некоторые примеры и на С#, впрочем, с определенным риском, поскольку у разработчиков еще нет достаточного опыта взаимодействия с платформой .NET, так что идиомы ее использования, как говорится, не созрели. Оба выбранных мною языка наследуют черты С, поэтому если вы владеете одним, то сможете воспринимать — хотя бы поверхностно — и код, написанный на другом. Моей задачей было найти такой язык, который удобен для большинства разработчиков, даже если он не является их основным инструментом. (Приношу свои извинения всем, кому нравится Smalltalk, Delphi, Visual Basic, Perl, Python, Ruby, COBOL и т.д. Я знаю: вы хотите сказать, что есть языки получше, чем Java или С#. Полностью с вами согласен!)
Примеры, приведенные в книге, преследуют цель объяснить и проиллюстрировать основные идеи, лежащие в основе типовых решений. Их не нужно трактовать как окончательные результаты; если вы намерены воспользоваться ими в реальных ситуациях, вам придется проделать определенную работу. Типовые решения — удачная отправная точка, а не пункт назначения.
20 Предисловие
Д

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