Если я правильно понимаю вашу задачу, то мне кажется что у фасада просто должен быть метод наподобе этого:
String[] getFIO();
клиент должен получить готовый список из 10 строк с Ф.И.О. людей…
А формироваться этот список должен внутри доменной модели, котороя знает как наиболее оптимальным образом вытащить эти данные из базы или еще откуда. В крайнем случае этот список может формировать фасад… но вообще это опасная дорожка по направлению к тому что фасад начнет реализовывать бизнесс-логику. Просто в вашем примере только база и фасад и мне пока не очень понятно где там находится бизнесс-логика
Простите, не очень понятен вопрос. Там прямо под картинкой цитата Фаулера «на самом деле Вид и Контроллер могут быть связанными друг с другом непосредственно. Однако, разработчики в основном не используют эту связь»
А если интерисует «физический смысл», то это когда во время работы приложения одни виды сменяют другие (открываются, закрываются) и считается что всем этим ансамблем управляет контроллер
Простите, не очень понятен вопрос. Там прямо под картинкой цитата Фаулера «на самом деле Вид и Контроллер могут быть связанными друг с другом непосредственно. Однако, разработчики в основном не используют эту связь»
А если интерисует «физический смысл», то это когда во время работы приложения одни виды сменяют другие (открываются, закрываются) и считается что всем этим ансамблем управляет контроллер
если совсем кратко то как раз в том что пытались применять MVC, где M — данные а C — логика всего на свете. И контроллер постепенно втягивал в себя все больше и больше кода… в нем на самом деле перемешивалась бизнес логика и логика визуализации данных. И его поддержание превратилось в ад. Причем в этом аду приходилось все время «копаться» потому что программа была живая, с ней работали и давали ценную обратную связь где и что нужно поменять и доработать, какие новые фичи прикрутить. Тут хотелось бы новых программистов нанять но никак потому как Контроллер был центром и вся программа через него была завязана в узел… любое изменение отражалось почти на всем. То есть было нереально выделить отдельные независимые модули которые можно было бы раскидать по нескольким программистам. И пришел момент когда стало понятно что все… оно не способно дальше меняться. Нужно все переписывать нафиг. И вот тогда фасады (не в теории а на практике) и прочие техники для уменьшения связанности стали действительно откровением и волшебной «палочной»
Спасибо… Вы прям из моего подсознания вытащили… у меня тоже всегда было ощущение что нужно разделять понимание MVC и умение работать с тем или иным фреймворком. Только у меня не получалось это так четко сформулировать…
Прошу прощения за запоздалый ответ. Нахожусь в другом часовом поясе и тут только наступило утро.
Целью статьи вовсе не являлось сказать что «original MVC» единственно правильный. Именно поэтому вначале дан обзор и приведены почти все основные схемы и варианты. Каждый может выбрать что ему больше подходит…
Лично для меня было очень полезно узнать с чего «все начиналось». Мне хотелось показать что исходный MVC с одной стороны был намного сложнее и богаче чем большинство упрощенных схем, которые нам обычно преподносятся в качестве MVC, а с другой — он довольно прост, логичен и буквально «выводится» из архитектурных принципов. Поэтому понимая суть можно его граммотно варьировать и адаптировать под свои нужды. Например у нас тоже не используется шаблон Наблюдатель просто потому что синхронизация приложения идет по таймеру. Но от этого MVC не перестает быть MVC.
Вопросы связанные с проектированием базы данных и логики приложения… Дело в том что тут двоякая ситуация. По большому счету база+логика это та самая доменная модель. И MVC не дает и не может дать вам ответ как лучше проектировать доменную модель. Он лишь говорит как организовать взаимодействие этой самой модели с пользовательским интерфейсом (лучше через фасад). Поэтому когда вам говорят что вы не так спроектировали потому что MVC… то это конечно же не правда. Но!!! к мнению и советам коллег стоит очень внимательно прислушаться потому как именно Вебщики постоянно сталкиваются с проектированием базы и сервера, знают что там за засады и какие решения лучше применять. Так что предложение вынести веб в в отдельную тему оно очень даже разумно.
А вот по поводу проектирования пользовательского интерфейса MVC есть что сказать. Конечно же интерфейс вовсе не обязан быть тупым, и современный веб наглядное этому подверждение. Главный вопрос — как же сделать его умным и при этом не смешивать логику GUI с графическими компонентами? Собственно об этом и будет вторая часть
ЗЫ на самом деле всем спасибо за терпимость. мне казалось что в столь «религиозной» теме за нетрадиционность подхода меня сразу закидают камнями
“Самой трудной проектной задачей является нахождение наиболее адекватной декомпозиции системы на иерархически выстроенные модули, с минимизацией функций и дублирования кода” (Никлаус Вирт).
Когда мы начинали проект нам тоже казалось что «архитектор» не нужен. Это очень распотраненное мнение, что думать дорого — надо делать… как-нибудь, главное чтобы заработало. Первый вариант мы именно так и сделали. А как только вышли на рынок, то оказалось, что тут надо изменить, там слегка переделать и вот тут мы почти угадали но клиентам нужно слегка по другому, а главное стало понятно куда и как нужно продукт развивать… И если бы граммотная архитектура была заложена с самого начала, все эти доработки и измениния стоили бы нам «три копейки». Но наша программа, хоть и работала, совершенно не была предназначена для изменений — в одном месте тронешь, а в 10 начинает разваливаться.
В результате, вместо того, чтобы вести продажи и активно захватывать рынок, мы боролись с собственным «мамонтом». И были вынуждены фактически все переписать (выброшенные деньги, выброшенный год жизни и очень тяжелой работы, потерянные клиенты и возможности). И все то, что когда то нам тоже казалось банальным — качественное разбиение на модули, интерфейсы, минимизация связей между ними… то основное что в дальнейшем собственно и позволяет относительно безболезненно изменять и расширять программу — стало восприниматься совсем по другому. Современный софт это уже не только некая функционалость, но и в огромной степени способность эту функциональность быстро менять и достраивать.
Будем честными создание хорошей архитектуры — это отдельная, непростая задача, требующая усилий и квалификации. Гибкий код это, как правило, более сложный код, который использует гораздо больше абстракций и решает задачи в максимально общем виде (чем собственно и достигается то, что он подходит для очень широкого спектра различных частных случаев). Такой код сложнее писать и сложнее понимать. Он использует не наиболее простые решения, а нередко очень даже сложные но наиболее масштабируемые и адаптируемые (кто не верит посмотрите например как происходит отрисовка простейшей кнопки в JavaSwing. Вообще когда начинаешь смотреть исходники опен сорс проектов, то термин “простой” это последнее что приходит на ум).
Поэтому, если бы у нас была возможность, то «архитектора» сейчас мы наняли бы в первую очередь. К сожалению хорошие архитекторы нужны всем, кто считает свои деньги, поэтому они и стоят космических денег. Так что пока мы осваиваем эту профессию самостоятельно, о чем честно и сказано в начале статьи.
Но с другой стороны, я понимаю, что для многих все написанное тут это «очередная статья ни о чем». Они правы. Тут сложная ситуация. Понятно, что код выкладывать нереально, а детский пример из трех классов ничего не объяснит. Я постараюсь в следующей статье сделать некий предельно упрощенный «макет» одной из наших программ, на котором продемонстрировать «построение табуретки».
А пока высказывание Сергея Белоусова, которое лучше всего демонстрирует то, что мне бы хотелось выразить «Самое сложное для людей — думать… У любой задачи может быть более разумное, продуманное решение, а не первое попавшееся. Люди в компании, которая занимается разработкой новых свойств продукта или платформы, должны все время думать. Задумываться о том, как то, что они делают сейчас, будет работать через много лет, как будет сопрягаться с другими вещами. Это мучительный процесс. Всегда проще не думать.»
Вчера была опубликована еще одна «архитектурная» статья и в ней даны интересные ссылки как раз по микросервисам. Мне, к сожалению, пока мало что есть сказать на эту тему, но благодарю вас, за то что вы ее затронули. Дело в том, что микросервисы идеально демонстрируют пару моментов, которые мне кажутся очень важными и хотелось бы подчеркнуть.
1) Иерархичность декомпозиции. Про нее везде пишут, но она проходит мимо сознания. Тут какой-то психологический блок. Благодаря ООП мы привыкли думать и проектировать сразу на уровне классов/объектов. А это слишком мелкая декомпозиция. Необходимость создания архитектуры вроде бы подталкивает нас к тому чтобы систему вначале разбить на модули, но полученные в результате первичной декомпозиции крупные модули — «бизнес-логика»,«представление», «база данных» на практике оказываются слишком крупными. Хотя и Мартин Фаулер и Макконел только их и относят к архитектуре. Фаулер в самом начале своей книги «Архитектура корпоративных программных приложений» так и пишет, что с термином архитектура связывают “разделение системы на наиболее крупные составные части”. Макконел же прямо дает алгоритм — делим систему на модули/пакеты, а пакеты сразу же делим на классы.
В результате такая простая и очевидная мысль, что большие первичные модули тоже нужно делить не на классы, а на подмодули, она как-то не приходит в голову. И вот как раз этот то разрыв между слишком крупными первичными модулями и слишком маленькими объектами и устраняет “архитектура микросервисов”. Архитектура микросервисов заставляет реализовать как минимум два уровня декомпозиции и, к примеру, модуль «бизнес логики» разделить на подмодули — «управление заказами», «управление клиентами», «платежи» и тд. Он помогает нам перейти от “думания объектами” к более эффективному “думанию и проектированию небольшими модулями-подсистемами” (то есть микросервисами)
2) Масштабируемость приложения за счет того, что любой модуль может быть запущен в любом количестве экземпляров. Это тоже вроде бы очевидная, но не всегда приходящая в нужный момент в голову, идея-техника, дающая возможность адаптировать систему под самые различные нагрузки, которая в «микросервисах» также очень хорошо выделена, сформулирована и “на блюдечке” доносится до нашего сознания. Она так и называется — «масштабирование за счет клонирования»
Возможно будет полезна следующая грубая, но наглядная аналогия. Представте, что есть система, состоящая из множества деталей соединенных проводами, и вам эту систему нужно разрезать/разделить на модули. Принцип “High/Strong Cohesion, Loose/Low Coupling” просто означает, что «резать» нужно там, где мало проводов. Так, чтобы максимальная концентрация проводов оказалась внутри модулей, а между модулями проводов было бы как можно меньше
Вы правильно заметили, что термины «Cвязность» и « Зацепление» часто вызывают путаницу. Связано это с неоднозначностью перевода. Дело в том что английские термины «Cohesion» и «Coupling» близки по смыслу и оба могут быть переведены, как связность/сцепление/зацепление. Соответственно, в зависимости от перевода, можно увидеть, что должна быть «низкая связанность и высокое зацепление» и наоборот — «высокая связность и низкое зацепление». Суть же заключается не в разнице между «связанностью» и «зацеплением», а в том где эти самые связность/зацепление должны быть максимальны и минимальны.
Максимальны связность/зацепление должны быть внутри модуля (класса), что означает сфокусированность модуля на своей функции и то что все его части сплоченно работают на одну задачу. А минимальны связность/зацепление должны быть между модулями, что означает независимость модулей.
Чтобы избежать неоднозначности, лучше всего, конечно, пользоваться английскими терминами: High/Strong Cohesion inside, Loose/Low Coupling between.
А вот что пишет сам Макконел в оригинале:
«Strong Cohesion. Cohesion refers to how closely all the routines in a class or all the code in a routine support a central purpose—how focused the class is.»
«Loose coupling means designing so that you hold connections among different parts of a program to a minimum.»
String[] getFIO();
клиент должен получить готовый список из 10 строк с Ф.И.О. людей…
А формироваться этот список должен внутри доменной модели, котороя знает как наиболее оптимальным образом вытащить эти данные из базы или еще откуда. В крайнем случае этот список может формировать фасад… но вообще это опасная дорожка по направлению к тому что фасад начнет реализовывать бизнесс-логику. Просто в вашем примере только база и фасад и мне пока не очень понятно где там находится бизнесс-логика
А если интерисует «физический смысл», то это когда во время работы приложения одни виды сменяют другие (открываются, закрываются) и считается что всем этим ансамблем управляет контроллер
А если интерисует «физический смысл», то это когда во время работы приложения одни виды сменяют другие (открываются, закрываются) и считается что всем этим ансамблем управляет контроллер
Целью статьи вовсе не являлось сказать что «original MVC» единственно правильный. Именно поэтому вначале дан обзор и приведены почти все основные схемы и варианты. Каждый может выбрать что ему больше подходит…
Лично для меня было очень полезно узнать с чего «все начиналось». Мне хотелось показать что исходный MVC с одной стороны был намного сложнее и богаче чем большинство упрощенных схем, которые нам обычно преподносятся в качестве MVC, а с другой — он довольно прост, логичен и буквально «выводится» из архитектурных принципов. Поэтому понимая суть можно его граммотно варьировать и адаптировать под свои нужды. Например у нас тоже не используется шаблон Наблюдатель просто потому что синхронизация приложения идет по таймеру. Но от этого MVC не перестает быть MVC.
Вопросы связанные с проектированием базы данных и логики приложения… Дело в том что тут двоякая ситуация. По большому счету база+логика это та самая доменная модель. И MVC не дает и не может дать вам ответ как лучше проектировать доменную модель. Он лишь говорит как организовать взаимодействие этой самой модели с пользовательским интерфейсом (лучше через фасад). Поэтому когда вам говорят что вы не так спроектировали потому что MVC… то это конечно же не правда. Но!!! к мнению и советам коллег стоит очень внимательно прислушаться потому как именно Вебщики постоянно сталкиваются с проектированием базы и сервера, знают что там за засады и какие решения лучше применять. Так что предложение вынести веб в в отдельную тему оно очень даже разумно.
А вот по поводу проектирования пользовательского интерфейса MVC есть что сказать. Конечно же интерфейс вовсе не обязан быть тупым, и современный веб наглядное этому подверждение. Главный вопрос — как же сделать его умным и при этом не смешивать логику GUI с графическими компонентами? Собственно об этом и будет вторая часть
ЗЫ на самом деле всем спасибо за терпимость. мне казалось что в столь «религиозной» теме за нетрадиционность подхода меня сразу закидают камнями
Когда мы начинали проект нам тоже казалось что «архитектор» не нужен. Это очень распотраненное мнение, что думать дорого — надо делать… как-нибудь, главное чтобы заработало. Первый вариант мы именно так и сделали. А как только вышли на рынок, то оказалось, что тут надо изменить, там слегка переделать и вот тут мы почти угадали но клиентам нужно слегка по другому, а главное стало понятно куда и как нужно продукт развивать… И если бы граммотная архитектура была заложена с самого начала, все эти доработки и измениния стоили бы нам «три копейки». Но наша программа, хоть и работала, совершенно не была предназначена для изменений — в одном месте тронешь, а в 10 начинает разваливаться.
В результате, вместо того, чтобы вести продажи и активно захватывать рынок, мы боролись с собственным «мамонтом». И были вынуждены фактически все переписать (выброшенные деньги, выброшенный год жизни и очень тяжелой работы, потерянные клиенты и возможности). И все то, что когда то нам тоже казалось банальным — качественное разбиение на модули, интерфейсы, минимизация связей между ними… то основное что в дальнейшем собственно и позволяет относительно безболезненно изменять и расширять программу — стало восприниматься совсем по другому. Современный софт это уже не только некая функционалость, но и в огромной степени способность эту функциональность быстро менять и достраивать.
Будем честными создание хорошей архитектуры — это отдельная, непростая задача, требующая усилий и квалификации. Гибкий код это, как правило, более сложный код, который использует гораздо больше абстракций и решает задачи в максимально общем виде (чем собственно и достигается то, что он подходит для очень широкого спектра различных частных случаев). Такой код сложнее писать и сложнее понимать. Он использует не наиболее простые решения, а нередко очень даже сложные но наиболее масштабируемые и адаптируемые (кто не верит посмотрите например как происходит отрисовка простейшей кнопки в JavaSwing. Вообще когда начинаешь смотреть исходники опен сорс проектов, то термин “простой” это последнее что приходит на ум).
Поэтому, если бы у нас была возможность, то «архитектора» сейчас мы наняли бы в первую очередь. К сожалению хорошие архитекторы нужны всем, кто считает свои деньги, поэтому они и стоят космических денег. Так что пока мы осваиваем эту профессию самостоятельно, о чем честно и сказано в начале статьи.
Но с другой стороны, я понимаю, что для многих все написанное тут это «очередная статья ни о чем». Они правы. Тут сложная ситуация. Понятно, что код выкладывать нереально, а детский пример из трех классов ничего не объяснит. Я постараюсь в следующей статье сделать некий предельно упрощенный «макет» одной из наших программ, на котором продемонстрировать «построение табуретки».
А пока высказывание Сергея Белоусова, которое лучше всего демонстрирует то, что мне бы хотелось выразить «Самое сложное для людей — думать… У любой задачи может быть более разумное, продуманное решение, а не первое попавшееся. Люди в компании, которая занимается разработкой новых свойств продукта или платформы, должны все время думать. Задумываться о том, как то, что они делают сейчас, будет работать через много лет, как будет сопрягаться с другими вещами. Это мучительный процесс. Всегда проще не думать.»
1) Иерархичность декомпозиции. Про нее везде пишут, но она проходит мимо сознания. Тут какой-то психологический блок. Благодаря ООП мы привыкли думать и проектировать сразу на уровне классов/объектов. А это слишком мелкая декомпозиция. Необходимость создания архитектуры вроде бы подталкивает нас к тому чтобы систему вначале разбить на модули, но полученные в результате первичной декомпозиции крупные модули — «бизнес-логика», «представление», «база данных» на практике оказываются слишком крупными. Хотя и Мартин Фаулер и Макконел только их и относят к архитектуре. Фаулер в самом начале своей книги «Архитектура корпоративных программных приложений» так и пишет, что с термином архитектура связывают “разделение системы на наиболее крупные составные части”. Макконел же прямо дает алгоритм — делим систему на модули/пакеты, а пакеты сразу же делим на классы.
В результате такая простая и очевидная мысль, что большие первичные модули тоже нужно делить не на классы, а на подмодули, она как-то не приходит в голову. И вот как раз этот то разрыв между слишком крупными первичными модулями и слишком маленькими объектами и устраняет “архитектура микросервисов”. Архитектура микросервисов заставляет реализовать как минимум два уровня декомпозиции и, к примеру, модуль «бизнес логики» разделить на подмодули — «управление заказами», «управление клиентами», «платежи» и тд. Он помогает нам перейти от “думания объектами” к более эффективному “думанию и проектированию небольшими модулями-подсистемами” (то есть микросервисами)
2) Масштабируемость приложения за счет того, что любой модуль может быть запущен в любом количестве экземпляров. Это тоже вроде бы очевидная, но не всегда приходящая в нужный момент в голову, идея-техника, дающая возможность адаптировать систему под самые различные нагрузки, которая в «микросервисах» также очень хорошо выделена, сформулирована и “на блюдечке” доносится до нашего сознания. Она так и называется — «масштабирование за счет клонирования»
Максимальны связность/зацепление должны быть внутри модуля (класса), что означает сфокусированность модуля на своей функции и то что все его части сплоченно работают на одну задачу. А минимальны связность/зацепление должны быть между модулями, что означает независимость модулей.
Чтобы избежать неоднозначности, лучше всего, конечно, пользоваться английскими терминами: High/Strong Cohesion inside, Loose/Low Coupling between.
А вот что пишет сам Макконел в оригинале:
«Strong Cohesion. Cohesion refers to how closely all the routines in a class or all the code in a routine support a central purpose—how focused the class is.»
«Loose coupling means designing so that you hold connections among different parts of a program to a minimum.»