Личная библиотека
FANAT1242
- 223 книги
Это бета-версия LiveLib. Сейчас доступна часть функций, остальные из основной версии будут добавляться постепенно.

Ваша оценкаЖанры
Ваша оценка
Перевод очень хороший.
Был бы отличный, если бы не несколько ошибок.
"Сервер приложений" - это кривой перевод фразы "business rules engine" (движок бизнес-правил), например Drools, который позволяет изменять бизнес-правила без перекомпиляции приложения.
Accrual Schedules лучше было бы перевести не как график начислений, а как планировщик начислений.
Здесь вместо фразы "двойная отправка запроса", следует понимать двойную диспетчеризацию (double dispatch). Этот прием описан в паттерне "Посетитель" из книги "Шаблоны проектирования" Эриха Гаммы и компании.
В оригинале автор пишет: "Fully customizing software for each organization is not practical because, even if each organization could pay for custom software, the organizational structure will likely change frequently". Фраза "fully customizing software" переведена как "полностью настраиваемое приложение", но в таком случае у читателя возникает когнитивный диссонанс, когда автор объясняет причину непрактичности использования такого приложения частым изменением организационной структуры. Ведь универсальные приложения, позволяющие гибко конфигурироваться под каждое изменение организационной структуры (типа "1С: Бухгалтерия"), именно для этого и предназначены. Я думаю, что фраза "fully customizing software for each organization" означает разработку специфичного приложения для каждой организации.
Книга не оправдала ожиданий.
Автор создает видимость глубокомысленных рассуждений, за которыми на самом деле скрываются банальные очевидности.
При этом автор не предлагает читателю каких-то конструктивных методов или алгоритмов для факторизации модели предметной области, а просто советует следовать своей интуиции.
Автор бесконечно повторяет одни и те же мысли разными словами. Проблема в том, что его мысли не предлагают что-то новое, а просто констатируют очевидные вещи.
В итоге автор пишет, что разбиение предметной области на уровни может помочь, а может и навредить, но конкретных критериев, определяющих необходимость стратификации не приводит, а просто говорит - следуйте своей интуиции. Это сводит на нет всю полезность данного опуса.
На протяжении всего повествования автор определяет огромное количество новых терминов, большая часть которых представляют собой либо переименованные чужие идеи, как, например информативные интерфейсы вместо информативных селекторов Кента Бека или фабрики вместо фабричных методов и абстрактных фабрик Эриха Гаммы, либо бесполезные концепции, типа крупномасштабных структур.
Вводя все новые и новые термины, автор пытается придать им материальную значимость, используя примеры из реальной практики. Однако, близость примеров к реальности сыграло с автором злую шутку, примеры не столько подтверждают идеи автора, сколько показывают его непрофессионализм. Сюжет всех историй, рассказанных автором, сводится примерно к одному сценарию.
Если бы автор просто ограничился вводом новой терминологии, то я бы поставил оценку 3. Однако, в процессе описания своего представления об объектно-ориентированном проектировании автор допустил ряд непростительных ошибок, которые привели к снижению оценки до 2 баллов.
Автор навязывает читателю негативное отношение к суррогатным идентификаторам.
Автор вводит читателя в заблуждение относительно невозможности измерения степени внутренней связности и внешней зависимости модулей.
На самом деле, такие метрики существуют и вполне работоспособны, например LCOM (Lack of Cohesion of Methods), Ca (Afferent Coupling), Ce (Efferent Coupling), I (Instability), A (Abstractness), D (Distance from the main sequence).
Автор навязывает читателю ошибочное представление о причинах стремления разработчиков к увеличению внутренней связности в модулях и уменьшению внешней зависимости между модулями.
Причина стремления к уменьшению внешней зависимости между модулями в том, чтобы уменьшить и в идеале вообще исключить потребность в изменении одного модуля, при необходимости внесения изменений в другой модуль, что позволяет сократить стоимость разработки и сопровождения программного обеспечения. Возможность человека удерживать в уме слишком много предметов с этим не связана. Уменьшение внешней зависимости кода между модулями происходит путем объединения этого кода в одном модуле, что автоматически увеличивает внутреннюю связность соответствующего модуля. На понимание кода это мало влияет, да и от неструктурированной "каши" тоже не избавит.
Автор использует читателя для рефлексии своих психологических проблем.
В главе 6 на странице 116 автор заявляет, что расскажет про парадигмы моделирования. Вместо этого автор много ноет про сложности использования объектно-ориентированной базы данных и жалуется про трудности применения движка бизнес-правил.
В главе 10 на странице 231 автор много ноет про сложность понимания побочных эффектов функций и расхваливает контрактное проектирования, как средство уменьшения этой сложности, и утверждения, как способ реализации контрактного проектирования, но не показывает как это сделать. Казалось бы в Java же есть ассерты (assert), и вот они те самые утверждения, но не тут то было: автор опять ноет, что во многих современных языках программирования утверждения не поддерживаются и предлагает использовать вместо них модульные тесты.
Автор вызывает у читателя неадекватное восприятие агрегации.
Автор использует слово "АГРЕГАТ", которое хотя и является производным от слова "агрегация", но совершенно отличается от него по тому смыслу, который вкладывает в него автор. Агрегация описывает слабую связь между сущностями. Жизненные циклы сущностей, связанных отношением агрегации, не зависят друг от друга, в отличие от жизненного цикла объектов в АГРЕГАТЕ, когда удаление корневой сущности означает удаление всех вложенных в него объектов. Такая связь между корневой сущностью АГРЕГАТА и вложенными в него объектами называется композицией.
Автор проявляет некомпетентность при моделировании агрегата в базе данных.
Автор ноет, что база данных позволяет получать подобъекты агрегата не обращаясь к корневому объекту, что естественно сводит на нет все усилия по инкапсуляции бизнес-логики в предметной области перемещая её на уровень запросов и транзакций. Понимает ли автор, что причина этого нытья кроется в несогласованном представлении объекта в модели приложения и в модели базы данных? Недостаточно чтобы объект был агрегатом в приложении, необходимо чтобы он был агрегатом и в базе данных тоже.
В примере "Целостность товарного заказа" главы 6 на странице 128 автор сталкивается с аномалией перекоса записи (write skew) только потому, что он недостаточно точно транслировал Purchase Order из объектной модели в реляционную. В объектной модели автор заявил, что Purchase Order является агрегатом, содержащим объекты Purchase Order Line Item. Это означает, что доступ к объектам Purchase Order Line Item должен осуществляется только через объект Purchase Order. А в реляционной модели автор поместил Purchase Order Line Item в отдельную таблицу, допустив тем самым возможность манипуляций без участия Purchase Order. Если бы автор разместил все объекты Purchase Order Line Item конкретного Purchase Order в одном из столбцов той записи, которая соответствует вышеупомянутому Purchase Order, то он бы получил агрегат в реляционной модели. Это позволило бы автору контролировать соблюдение инварианта Approved Limit, так как объекты Purchase Order Line Item определяли бы состояние объекта Purchase Order не только в объектной модели приложения, но и в реляционной модели базы данных.
Автор создает у читателя ошибочное представление о шаблонах проектирования "Фабричный метод" и "Абстрактная фабрика".
Хотя автор и заявляет, что его ФАБРИКА есть реализация шаблонов "Фабричный метод" и "Абстрактная фабрика". Но как выяснится позже, это совершенно не так.
Для создания экземпляров класса МАНИПУЛЯЦИЯ автор добавляет в этот класс статический метод, который используется просто как обертка над конструктором.
public class HandlingEvent {
public static HandlingEvent newLoading(Cargo с, CarrierMovernent loadedOnto, Date timeStamp) {
HandlingEvent result = new HandlingEvent(c, LOADING_EVENT, timeStamp);
result.setCarrierMovement(loadedOnto);
return result;
}
}
Это не правда, автор не абстрагирует создание экземпляров класса, добавив в него статические методы, которые создают экземпляры этого класса. Чтобы абстрагировать создание объекта нужно использовать абстрактный метод фабрики объектов, а не статический метод этого объекта. Автор просто инкапсулирует логику создания экземпляра класса в статическом методе этого класса, но к шаблону "Фабричный метод" или "Абстрактная фабрика" это действие никакого отношения не имеет.
Автор вкладывает в сознание читателя крайне вредный совет по организации доступа к связанным сущностям, сохраненным в базе данных.
Это вредный совет, потому что обращения по цепочке ассоциаций между персистентными объектами может породить серию запросов к базе данных. Лучше сразу запросить у базы нужную информацию одним запросом, чем неявно делать несколько запросов, двигаясь по ассоциациям. Лучше запросить у базы данных конкретный объект простым запросом, чем делать сложный запрос с несколькими соединениями по внешнему ключу, чтобы, собрав комплексный объект предметной области, затем выкинуть в мусор большую часть загруженных данных, просто потому, что на самом деле нужна была только небольшая их часть.
Автор порождает у читателя пагубное стремление к объединению объектного и реляционного хранилищ в одном интерфейсе.
Такое стремление к унификации наказуемо урезанием возможностей хранилища до наименьшего общего функционала между объектным и реляционным способом хранения информации.
Автор провоцирует читателя выполнять фильтрацию сущностей на стороне приложения.
При описании шаблона СПЕЦИФИКАЦИЯ в главе 9 на странице 213 автор приводит пример кода, в котором он загружает из базы данных все объекты, перебирает их в цикле и применяет на каждом СПЕЦИФИКАЦИЮ, чтобы определить, будет ли он включен в результат.
public Set satisfyingElementsFrom(InvoiceRepository repository) {
Collection pastDue lnvoices = repository.selectWhereDueDateIsBefore(currentDate);
Set delinquentInvoices = new HashSet();
Iterator it = pastDuelnvoices.iterator();
while(it.hasNext()) {
Invoice anInvoice = (Invoice) it.next();
if (this.isSatisfiedBy(anInvoice))
delinquentInvoices.add(anlnvoice);
}
return delinquentInvoices;
}
Это очень вредный пример не только из-за накладных расходов на передачу лишних объектов между базой данных и приложением, которые можно было фильтровать на стороне базы данных, но и потому, что у автора нет ограничений на количество объектов, которые он загружает в память одним запросом. Со временем при росте количества объектов это приведет к переполнению памяти приложения во время выполнения запроса к базе данных. Автор должен был использовать курсор для последовательного перебора записей в таблице или загружать и обрабатывать объекты пакетами, ограничив количество записей в одном пакете и освобождая память после его обработки.


Нужная книга для разработчиков крупных систем с большим количеством бизнес логики. Не стоит думать о ней, как о "справочнике по (ненужному)DDD и папочки". Эванс поднимает темы про грамотное разделение бизнес логики, про важность взаимодействия с закзачиками илюдтми из предметной области, объясняет, что методология DDD и тесное сотрудничество разработчиков с бизнесом, помогает строить системы, которые будут легче и более предсказуемо развиваться.
Ведь именно глубокое понимание процессов и тонкостей бизнес процессов, может помочь посмотреть в будущее, и строить систему, готовую к наиболее вероятным изменениям.
К этой книге я подбиралась года 3. И как в ситуации с "паттерны проектирования" Гаммы (GoF), понадобился опыт, что бы осилить, и она показалась интересной, наталкивающей на размышления. Не все главы показались интересными, но большая часть была прочитана не отрываясь.

Если вы ждете момента, когда изменение в программе будет безупречно обосновано, то вы ждете уже слишком долго.




















Другие издания

