Comments 86
Реквестирую такую же статью про антипаттерны.
Не уверен что тут много чего можно сказать помимо вот этой статьи. Если наберется достаточно материала и будет время — сделаю.
Прекрасный материал! Нет, на самом деле. Конечно нужна ещё оценка не программиста, уже давно использующего часть паттернов, а того, кто только этому учится, но всё же великолепно.
Однозначно в мемориз, спасибо.
Однозначно в мемориз, спасибо.
И оценка программиста не помешает. Некоторые описания не совсем точны, state: у каждого объекта есть состояние, из-за которого объект может менять свое поведение, суть же паттерна в выделение состояния в отдельный объект; chain of responsibility: пример не отражает суть. Stragey: «вы задаете начальные условия, а как себя вести уже решает он сам (сам выбирает стратегию).» вообще то вы сами выбираете алгоритм (стратегию). Другие слишком странные: command: " включать одним выключателем как свет в комнате, так и пылесос." это вообще как возможно в реальной жизни?.. Есть же проще примеры, тот же расчет зарплаты. Decorator: «можно считать декоратором человека с кистью и красной краской. » ?! Лучше уж использовать банальный пример с пиццей и индигриентами. Proxy: это же заместитель, можно было пример с заместителями и использовать :).
упс, " Есть же проще примеры, тот же расчет зарплаты" относилось к Strategy
1. State
Во многих метафорах не говорится о том что выделять в отдельных объект, потому что это уже более предметная область. Так то ведь можно такой state даже в синглтон загнать. Главная цель была именно понять что паттерн делает, а именно меняет состояние объекта.
2. Chain of responsibility
К сожалению не смог найти метафору попроще. Возможно предложите вы — поправлю.
3. Strategy
Возьмите классический пример — валидатор. Вы используете только метод validate, а на основе параметров, вроде ('not_empty') паттерн сам производит действия, но метод который вы используете извне, везде только validate. Так что как и было сказано в описании — задаются лишь параметры, а стратегию (конкретный метод) реализует уже сам паттерн.
4. Command
Возможно некорректно выразился. У вас в пылесосе, по своей сути, точно такой же механизм как в выключателе света — соединитель/разъединитель двух проводков. Имелось ввиду именно это.
Какой именно пример вы имеете ввиду насчет зарплаты? Опять же если есть что-то попроще и понятнее — исправить статью не сложно.
5. Decorator.
А чем лучше пример с пиццей? Просто не совсем могу понять ваш ход мыслей.
6. Proxy
Чем пример с заместителем будет лучше? Полагаю если вы попробуете описать тот же принцип просто применив слово заместитель, то ничего не изменится. Могу конечно ошибаться, жду пример если это не так.
Во многих метафорах не говорится о том что выделять в отдельных объект, потому что это уже более предметная область. Так то ведь можно такой state даже в синглтон загнать. Главная цель была именно понять что паттерн делает, а именно меняет состояние объекта.
2. Chain of responsibility
К сожалению не смог найти метафору попроще. Возможно предложите вы — поправлю.
3. Strategy
Возьмите классический пример — валидатор. Вы используете только метод validate, а на основе параметров, вроде ('not_empty') паттерн сам производит действия, но метод который вы используете извне, везде только validate. Так что как и было сказано в описании — задаются лишь параметры, а стратегию (конкретный метод) реализует уже сам паттерн.
4. Command
Возможно некорректно выразился. У вас в пылесосе, по своей сути, точно такой же механизм как в выключателе света — соединитель/разъединитель двух проводков. Имелось ввиду именно это.
Какой именно пример вы имеете ввиду насчет зарплаты? Опять же если есть что-то попроще и понятнее — исправить статью не сложно.
5. Decorator.
А чем лучше пример с пиццей? Просто не совсем могу понять ваш ход мыслей.
6. Proxy
Чем пример с заместителем будет лучше? Полагаю если вы попробуете описать тот же принцип просто применив слово заместитель, то ничего не изменится. Могу конечно ошибаться, жду пример если это не так.
Попробовал другую метафору для Chain of responsibility, возможно так будет лучше.
Статья хорошая но слишком много текста) Разбавили бы его иллюстрации)
UFO just landed and posted this here
Книга Фримена «Паттерны проектирования» раскрывает тему паттернов на наглядных метафорах, обильно проиллюстрированных.
Советую эту книгу для плавного освоения паттернов.
Книга занимает 11 место в недавно освещенном топе habrahabr.ru/blogs/development/135897/ оригинального голосования stackoverflow.com/questions/1711/what-is-the-single-most-influential-book-every-programmer-should-read
Советую эту книгу для плавного освоения паттернов.
Книга занимает 11 место в недавно освещенном топе habrahabr.ru/blogs/development/135897/ оригинального голосования stackoverflow.com/questions/1711/what-is-the-single-most-influential-book-every-programmer-should-read
Н-р: Паттерн Стратегия img.labirint.ru/images/comments_pic/1112/05labj6l81300976424.jpg
Мне не нравится аналогия про синглтон. Синглтон — это как будто вместо того, чтобы провести в каждую квартиру по телефонному проводу (не рассказывая, куда он идет — на ближайшую телефонную станцию или на персональный спутниковый передатчик) мы говорим каждому жителю: «Что-то нам лень до тебя провод тянуть, пойди сам на ул. Ленина, дом 1, и воткни свой провод там куда-нибудь». И когда, например, станция на улице Ленина перестает справляться с количеством абонентов — у всех возникают проблемы.
Вы ушли в пример параллельного доступа к объекту (Concurrency control). Это совершенно не связано с паттерном синглтона.
Я имел в виду, что клиенты синглтона, помимо знания его интерфейса, знают, что это синглтон, знают, где его взять, и сами решают, когда это сделать. Иногда бывает, что эти знания — лишние для них, и могут обернуться проблемами в будущем.
Даёшь «Математический анализ в картинках»!
en.wikipedia.org/wiki/Service_locator_pattern
Service Locator паттерн.
Представьте, что есть стойка регистрации на несколько конференций. Вы подходите к симпатичным девушкам и говорите, какая конференция вам нужна. В ответ получаете пакет с материалами и указания, как пройти в нужные залы.
Вот Service Locator — это такая конструкция, которая выдает по нужному вам запросу некую сущность, необходимую для решения задачи.
По сути дела, это один из способов инкапсулировать информацию о том, как создавать тот или иной объект, внутрь специального объекта. Очень клевая штука. :)
Service Locator паттерн.
Представьте, что есть стойка регистрации на несколько конференций. Вы подходите к симпатичным девушкам и говорите, какая конференция вам нужна. В ответ получаете пакет с материалами и указания, как пройти в нужные залы.
Вот Service Locator — это такая конструкция, которая выдает по нужному вам запросу некую сущность, необходимую для решения задачи.
По сути дела, это один из способов инкапсулировать информацию о том, как создавать тот или иной объект, внутрь специального объекта. Очень клевая штука. :)
Не совсем пока понял в чем его разница с паттерном Builder?
Объясните пожалуйста, если не сложно.
Объясните пожалуйста, если не сложно.
В моем понимании Builder есть порождающий паттерн,
в то время как Service Locator (как я его обычно реализую) — это синглтон + реестр, который может как порождать новые объекты при обращении к нему, так и возвращать уже инстанцированные.
псевдокод
audioObject = ServiceLocator::instance()->getAudioObject() // тут может быть скрыта фабрика
videoObject = ServiceLocator::instance()->getVideoObject() // а тут может быть некий объект, однажды инстанцированный и затем возвращаемый в той самой инстанции — читай синглтон
и т.д.
в то время как Service Locator (как я его обычно реализую) — это синглтон + реестр, который может как порождать новые объекты при обращении к нему, так и возвращать уже инстанцированные.
псевдокод
audioObject = ServiceLocator::instance()->getAudioObject() // тут может быть скрыта фабрика
videoObject = ServiceLocator::instance()->getVideoObject() // а тут может быть некий объект, однажды инстанцированный и затем возвращаемый в той самой инстанции — читай синглтон
и т.д.
Builder как бы собирает объекты из кусочков, но это объекты одного класса, просто для разных экземпляров задаются разные свойства. Всегда будут пакет, изображение, сок и т. п., просто они могут быть разными, но всё равно это будет пакет с соком.
Service Locator же возвращает разные типы объектов в зависимости от кода инициализации. Пускай задача стоит доставить наш пакет сока, созданный строителем, фабрикой или ещё чем, куда захотел покупатель. Мы спрашиваем у локатора «дай нам службу доставки», и он нам соединяет на со службой доставки по номеру телефона, который директор ему дал (потому чтополучает откат они нам дают скидку как постоянным клиентам), а мы уже просим службу доставить сок по нужному адресу. Сегодня одна служба, а завтра может быть другая. Нам без разница, решает директор и сообщает об этом локатору служб, нам важно знать лишь что они могут доставлять то, что мы им скажем туда, куда скажем, то есть службы реализуют интерфейс «Доставить <предмет> на <адрес>».
По сути локатор служб это реестр, куда заносятся конкретные экземпляры различных служб, нужных приложению. То есть реестр со специфическим назначением. Основное назначение — реализация DI/IoC. Очень близок к паттерну IoC Container, настолько, что их часто путают, по мне так разница в том, что локатор оперирует экземплярами служб, созданных не им, а контейнер сам создаёт при необходимости. Но может ошибаюсь.
Service Locator же возвращает разные типы объектов в зависимости от кода инициализации. Пускай задача стоит доставить наш пакет сока, созданный строителем, фабрикой или ещё чем, куда захотел покупатель. Мы спрашиваем у локатора «дай нам службу доставки», и он нам соединяет на со службой доставки по номеру телефона, который директор ему дал (потому что
По сути локатор служб это реестр, куда заносятся конкретные экземпляры различных служб, нужных приложению. То есть реестр со специфическим назначением. Основное назначение — реализация DI/IoC. Очень близок к паттерну IoC Container, настолько, что их часто путают, по мне так разница в том, что локатор оперирует экземплярами служб, созданных не им, а контейнер сам создаёт при необходимости. Но может ошибаюсь.
Мне тоже не понравилось описание этого паттерна. По сути автор сказал — это фабрика, только где-то в недрах ее происходит собирание реальных объектов из частей.
А «в недрах» нас и не должно интересовать. интересная ссылка
Builder применяется для создания сложных объектов из отдельных частей (обычно родственных, но не обязательно). Фабрика — целого сразу. Пример Buildr-а:
Фабрика:
А «в недрах» нас и не должно интересовать. интересная ссылка
Builder применяется для создания сложных объектов из отдельных частей (обычно родственных, но не обязательно). Фабрика — целого сразу. Пример Buildr-а:
interface ITreeBuilder
{
IEntity CreateSheet();
IEntity CreateTree(IEnumerable<IEntity> children);
IEntity CreateRoot(IEntity part)
}
Фабрика:
itnerface ITreeFactory
{
IEntity CreateTree();
}
На мой взгляд у вас получилась не очень хорошая статья.
Вы излишне многословны, большинство метафор витиеваты и туманы, некоторые же и вовсе не верны, при этом у вас сохраняется зависимость определения одних метафор от других.
И это не фантастический роман, в произведение которого многое можно оставить на откуп фантазии читателя, в таких статьях как эта, иллюстрации ваших слов совсем бы не помешали.
Помимо упомянутой в комментариях выше книге, есть так же статья 1997 года — www.cours.polymtl.ca/inf3700/divers/nonSoftwareExample/patexamples.html, рекомендую.
Вы излишне многословны, большинство метафор витиеваты и туманы, некоторые же и вовсе не верны, при этом у вас сохраняется зависимость определения одних метафор от других.
И это не фантастический роман, в произведение которого многое можно оставить на откуп фантазии читателя, в таких статьях как эта, иллюстрации ваших слов совсем бы не помешали.
Помимо упомянутой в комментариях выше книге, есть так же статья 1997 года — www.cours.polymtl.ca/inf3700/divers/nonSoftwareExample/patexamples.html, рекомендую.
Я всячески приветствую критику, однако всё же она должна быть конструктивной, чтобы не быть голословной.
Если вам есть что предложить/поправить/внести своё — предлагайте, давайте вместе делать материал более качественным и полезным для читателей. На мой взгляд это куда более грамотный подход нежели просто отписаться «у вас всё не так, как думаю я».
Как я уже говорил, это лишь небольшие метафоры, если снабдить это иллюстрациями, добавить разбавить слегка кодом и примерами — то смысл в этой статье теряется напрочь, потому что получится книга, которую указали вот в этом комментарии. Еще раз замечу — это не статья чтобы изучать паттерны, это лишь небольшое ознакомление с тем, что они иногда описывают в реальном мире.
Если вам есть что предложить/поправить/внести своё — предлагайте, давайте вместе делать материал более качественным и полезным для читателей. На мой взгляд это куда более грамотный подход нежели просто отписаться «у вас всё не так, как думаю я».
Как я уже говорил, это лишь небольшие метафоры, если снабдить это иллюстрациями, добавить разбавить слегка кодом и примерами — то смысл в этой статье теряется напрочь, потому что получится книга, которую указали вот в этом комментарии. Еще раз замечу — это не статья чтобы изучать паттерны, это лишь небольшое ознакомление с тем, что они иногда описывают в реальном мире.
UFO just landed and posted this here
А мой опыт говорит, что очень редко бывают методы, которые нужны всем типам объектов, ну разве что конструкторы, но они у всех разные. А если всё же нужны, то эти методы реализуются в базовом классе или определяются абстрактно/в интерфейсах, а затем реализуются в наследниках (сериализация хороший пример).
Один из столпов ООП — инкапуляция, только методы объектов должны знать об их внутренних данных, о том, что в мешке лежит. А как вы предлагаете реализовать ту же сериализацию? Функция, которая принимает произвольный объект, определяет его тип и в куче if'ов или case'ов выбирает как именно этот объект сериализовывать?
Один из столпов ООП — инкапуляция, только методы объектов должны знать об их внутренних данных, о том, что в мешке лежит. А как вы предлагаете реализовать ту же сериализацию? Функция, которая принимает произвольный объект, определяет его тип и в куче if'ов или case'ов выбирает как именно этот объект сериализовывать?
UFO just landed and posted this here
>Я считаю, что достаточно иметь один тип объектов, который имеет все методы.
God-objects? Что делать, если вызывается метод, для которого в данном «мешке» данных нет? NPE?
>— Зачем?
Возможность сменить реализацию, не меняя интерфейс. Невозможность рассогласовать состояние объекта незметно для самого объекта.
>Без всякой кучи if-ов.
Хотелось бы взглянуть. Как гуглить?
God-objects? Что делать, если вызывается метод, для которого в данном «мешке» данных нет? NPE?
>— Зачем?
Возможность сменить реализацию, не меняя интерфейс. Невозможность рассогласовать состояние объекта незметно для самого объекта.
>Без всякой кучи if-ов.
Хотелось бы взглянуть. Как гуглить?
UFO just landed and posted this here
>то же, что и SQL запрос «делает», когда в базе ищут то, чего там нету.
Theris no table...? Понятно…
>Объекты как ассоциативные массивы
Больше вопросов нет…
Theris no table...? Понятно…
>Объекты как ассоциативные массивы
Больше вопросов нет…
UFO just landed and posted this here
Не все свойства объектов надо сериализовывать, циклом по всем свойствам пройтись — перебор. Уж поверьте на слово, пока вы С++ занимались, я с ассоциативными массивами работал, эмулировал с их помощью объекты из C++. Прямо как у вас «все объекты одного типа, но с разным набором данных».
Я понимаю ваш восторг от возможности динамически задавать новые свойства после C++, но вот один из самых популярных языков со слабой динамической типизацией всё больше идёт к сильной статической. Не от хорошей жизни.
Я понимаю ваш восторг от возможности динамически задавать новые свойства после C++, но вот один из самых популярных языков со слабой динамической типизацией всё больше идёт к сильной статической. Не от хорошей жизни.
«А как вы предлагаете реализовать ту же сериализацию?»
Меня этот вопрос, как старого С++ника, то же ставил в тупик. Но пришлось переучиваться… на JS, там это элементарно. Без всякой кучи if-ов.
элементарно? только не говорите о JSON.
«любой часто используемый метод нужен всем объектам»
Это ерунда. Вы говорите, что недопроектированность системы — это норма. Цель декомпозиции системы, как раз в том, чтобы уменьшить связанность отдельных компонентов. Даже методы сериализации нужна только тем, кто ее производит. А определение их необходимо только для сущностей, которые, например передаются по сети.
Если таковых много, значит либо вы строите сереализатор, либо недопроектировали свое решение.
Это ерунда. Вы говорите, что недопроектированность системы — это норма. Цель декомпозиции системы, как раз в том, чтобы уменьшить связанность отдельных компонентов. Даже методы сериализации нужна только тем, кто ее производит. А определение их необходимо только для сущностей, которые, например передаются по сети.
Если таковых много, значит либо вы строите сереализатор, либо недопроектировали свое решение.
UFO just landed and posted this here
>Вот мяукать мячик не может.
А что будет, если написать Мячик->Мяукни?
А что будет, если написать Мячик->Мяукни?
«Это теорема Гёделя о неполноте.»
Мы с вами не идеальных коней в вакууме строим. Наша «формальная арифметика» имеет возможность расширяться с введением новых требований, а потому можно говорить о обязательной «невыводимости», только на несуществующую функциональность. Для всего остального мы должны выдумывать новое «сложение» (или скорректировать старое), при котором функциональность будет непротиворечиво существовать.
Программа не должна 100% верно описывать реальный мир (и 1% не обязателен). Достаточно абстрактной модели, удовлетворяющей условиям, описанным в техзадании. Если в нем нет того, что кошка по вызову деструктора распадается на атомы, значит она может и не распадаться (это ее личное дело, если конечно это не вызовет утечку ресурсов).
Мы с вами не идеальных коней в вакууме строим. Наша «формальная арифметика» имеет возможность расширяться с введением новых требований, а потому можно говорить о обязательной «невыводимости», только на несуществующую функциональность. Для всего остального мы должны выдумывать новое «сложение» (или скорректировать старое), при котором функциональность будет непротиворечиво существовать.
Программа не должна 100% верно описывать реальный мир (и 1% не обязателен). Достаточно абстрактной модели, удовлетворяющей условиям, описанным в техзадании. Если в нем нет того, что кошка по вызову деструктора распадается на атомы, значит она может и не распадаться (это ее личное дело, если конечно это не вызовет утечку ресурсов).
UFO just landed and posted this here
UFO just landed and posted this here
Интерестно, как вы будете складывать огурцы и помидоры. А самое главное, что у вас после этого получится.
Все операции в математике определены на каком-то конкретном типе объектов. Сложение натуральных чисел — для яблок, или помидоров, или сущностей. Помимо натуральных есть комплексные числа, вероятностные величины, вектора и другие математические абстракции.
Конкретная «формальная арифметика» определяет сущности и операции над ними. Не одну и не две, а столько сколько нужно. Так для векторов определено умножение на число, скалярное умножение векторов, векторное умножение векторов. Маразм ясен.
Все операции в математике определены на каком-то конкретном типе объектов. Сложение натуральных чисел — для яблок, или помидоров, или сущностей. Помимо натуральных есть комплексные числа, вероятностные величины, вектора и другие математические абстракции.
Конкретная «формальная арифметика» определяет сущности и операции над ними. Не одну и не две, а столько сколько нужно. Так для векторов определено умножение на число, скалярное умножение векторов, векторное умножение векторов. Маразм ясен.
UFO just landed and posted this here
Огурцы и помидоры можно складывать в свободной абелевой группе, порождённой огурцом и помидором. То, что этого сделать нельзя,- одна из самых популярных в народе вредных эвристик.
UFO just landed and posted this here
UFO just landed and posted this here
Если следовать вашей логике, сохраняя поток «метафор», то в реальной жизни в принципе не нужны коробки разных размеров, можно взять одну коробку одного размера, приделать ей моторчик, колеса и ручку сверху, а потом этой коробкой заменять автомобиль, портфель, грузовик (просто побольше коробок взять) и дом. Ведь универсально же.
Не буду втягиваться диалог корректности этой метафоры, но в данном случае я скорее буду полагаться на опыт большого числа инженеров.
То что ваши задачи позволяли пока вам универсально решать всё при помощи «коробки», еще не значит что вам не встретятся задачи, где ее будет либо недостаточно, либо она будет избыточна.
Не буду втягиваться диалог корректности этой метафоры, но в данном случае я скорее буду полагаться на опыт большого числа инженеров.
То что ваши задачи позволяли пока вам универсально решать всё при помощи «коробки», еще не значит что вам не встретятся задачи, где ее будет либо недостаточно, либо она будет избыточна.
«можно взять одну коробку одного размера, приделать ей моторчик ...»
Главное не забывать при этом говорить «тр-тр-тр...»
Главное не забывать при этом говорить «тр-тр-тр...»
UFO just landed and posted this here
Со своей стороны я могу только пожелать вам успехов в реализации подобного подхода.
Уверен, что если вы изобрели новый прекрасный метод разработки решающий все те проблемы для борьбы с которыми и используют ООП подход, то весь цивилизованный и разумный мир последует за вами.
Уверен, что если вы изобрели новый прекрасный метод разработки решающий все те проблемы для борьбы с которыми и используют ООП подход, то весь цивилизованный и разумный мир последует за вами.
Откуда функция сериализации знает какие свойства объекта надо сериализировать, а какие нет? Сериализация, например, соединения с БД для передачи по сети или сохранения на диск бессмысленна и, скорее всего, приведёт к ошибке при попытке сохранить десриализованный объект в базе. Он-то будет думать, что у него есть соединение с БД, а том, что он на другой хост попал или прошло полгода как соединение закрылось он и не догадается.
UFO just landed and posted this here
UFO just landed and posted this here
UFO just landed and posted this here
А методы надо писать таким образом, что бы они работали с любым типом объектов (портфелей), SQL же работает, правда он может вернуть пустое множество, но всегда находит в портфеле не гнилые красные фасолины.
ответить
sql отвечает на вопрос ЧТО, а не на вопрос КАК
UFO just landed and posted this here
Правильно, «что делать?», а «как делать» он сам выбирает.
реляционные языки — языки программирования, оперирующие с данными как со множествами, применяя к ним основные операции теории множеств.
типичным примером является SQL. SQL основывается на теории исчисления кортежей, которое является в свою очередь направлением реляционного исчисления, а в основой оного лежит теория предикатов первого уровня.
все-таки вы не сможете с помощью них покрывать многие аспекты алгоритмического программирования.
типичным примером является SQL. SQL основывается на теории исчисления кортежей, которое является в свою очередь направлением реляционного исчисления, а в основой оного лежит теория предикатов первого уровня.
все-таки вы не сможете с помощью них покрывать многие аспекты алгоритмического программирования.
Браво!
Устал читать.
Вообще статья хорошая, но вот с метафорами беда…
По поводу «Стратегии» вы написали: Как устроена сама «стратегия» и какие алгоритмы внутри нее вам собственно знать и требуется.
Вы здесь частицу «не» не пропустили? «знать и не требуется».
Если ошибки нет, то поспорю с вами.
Вы здесь частицу «не» не пропустили? «знать и не требуется».
Если ошибки нет, то поспорю с вами.
Sign up to leave a comment.
Паттерны ООП в метафорах