Comments 24
Не понял толком отличия forwarder'а и прочих, поэтому повторил как понял.
Опять же неясно, зачем нужны forwarder'ы, если основная идея в цепочности.
У меня при возврате
Опять же неясно, зачем нужны forwarder'ы, если основная идея в цепочности.
У меня при возврате
Just v
сообщение идёт дальше по цепочке, при возврате Nothing
цепочка прерывается. А route
нужен, чтобы ответвить сообщение в другую цепочку.module Event (
) where
import Prelude hiding (id, (.))
import Control.Category
data Node a b = Node (a -> IO (Maybe b))
instance Category Node where
id = Node $ return . Just
(Node g) . (Node f) = Node $ \v -> do
f v >>= maybe (return Nothing) g
endnode :: (a -> IO ()) -> Node a ()
node :: (a -> IO ()) -> Node a a
run :: Node a b -> a -> IO (Maybe b)
run_ :: Node a b -> a -> IO ()
endnode f = Node $ \v -> f v >> return Nothing
node f = Node $ \v -> f v >> return (Just v)
run (Node f) v = f v
run_ (Node f) v = f v >> return ()
server = endnode putStrLn
route to = node $ run_ to
forward to = node $ run_ to
network to = node $ run_ to
test = run test' "correct" where
logmsg = node $ \s -> putStrLn ("log: " ++ s)
test' = logmsg >>> test'' >>> server
test'' = route (network fw2) where
fw2 = forward fw1
fw1 = forward serv
serv = server
+4
хаскелл-джедай..? :)
А вы, собственно, что именно куском кода-то сказать хотели?
А вы, собственно, что именно куском кода-то сказать хотели?
+3
Интересный паттерн. Спасибо за пищу для мозга. Но не очень-то наглядный пример, особенно для людей не знающих C++. Комментариев в коде нет, что особенно напрягает. Т.е. суть ясна, а реализация — нет.
+3
да-да.
было бы гораздо круче использовать что-нибудь более абстрактно-понятное.
а начинаешь залипать в код, вместо осмысливания идеи.
было бы гораздо круче использовать что-нибудь более абстрактно-понятное.
а начинаешь залипать в код, вместо осмысливания идеи.
0
Хорошо. А что вы хотите видеть в примерах?
Абстрактный класс Handler, два наследника Handler1, Handler2, сообщение Message которое обрабатывается одним из обработчиков — handle(Message message)? Это ровно четыре строчки кода и скукота. Я пытаюсь дать читатели интересный и сложный пример, поняв который он лучше осознает/запомнит материал.
Абстрактный класс Handler, два наследника Handler1, Handler2, сообщение Message которое обрабатывается одним из обработчиков — handle(Message message)? Это ровно четыре строчки кода и скукота. Я пытаюсь дать читатели интересный и сложный пример, поняв который он лучше осознает/запомнит материал.
-1
Да, C# или Java, например
+1
Хорошее и достаточно детальное описанное применения паттерна (комментариев правда маловато, как выше верно заметили). «Бандитский» пример менеджера справки из книги гораздо более абстрактный — пришлось два раза перечитывать, чтобы понять структуру распределения обязанностей между объектами.
Я тоже не так давно применил этот паттерн в разработке одного приложения с использованием SCSF. У меня ситуация была следующая: есть список Workspace вложенных друг в друга. ShellWorkspace с кнопкой Back и Next и Print, в него встраивается RootWorkspace c кнопками категорий. А при нажатии на одну их кнопок категорий в RootWorkspace встраивался ContentWorkspace. Обработку навигации я делегировал специальному менеджеру-сервису а вот обработку кнопки Print реализовал с помощью паттерна Chain of Responsibility. Т.е. команду мог обрабатывать только конкретный ContentWorkspace. Поэтому все вышележашие просто реализовывали так:
И последний в списке экземпляр конкретного ContentView:
Я тоже не так давно применил этот паттерн в разработке одного приложения с использованием SCSF. У меня ситуация была следующая: есть список Workspace вложенных друг в друга. ShellWorkspace с кнопкой Back и Next и Print, в него встраивается RootWorkspace c кнопками категорий. А при нажатии на одну их кнопок категорий в RootWorkspace встраивался ContentWorkspace. Обработку навигации я делегировал специальному менеджеру-сервису а вот обработку кнопки Print реализовал с помощью паттерна Chain of Responsibility. Т.е. команду мог обрабатывать только конкретный ContentWorkspace. Поэтому все вышележашие просто реализовывали так:
public bool Print()
{
IContentView view = this.Workspace as IContentView;
return view != null ? view.Print() : false;
}
И последний в списке экземпляр конкретного ContentView:
public bool Print()
{
bool result = false;
// Printing code...
return result;
}
+1
И разместите пожалуйста в этой статье ссылку на книгу, или оригинального описания этого паттерна. А то непосвященные будут читать и думать, что это вы придумали этот паттерн :) Нехорошо это — на святое замахиваетесь :)
0
Наверное на этом можно заканчивать комментарии.
ISBN 978-5-469-01136-1
всем советую, книга имеет ограничение по возрасту (читать от 3-х лет + одного большого проекта, переписанного второй раз). ;-)
ISBN 978-5-469-01136-1
всем советую, книга имеет ограничение по возрасту (читать от 3-х лет + одного большого проекта, переписанного второй раз). ;-)
+1
интересно, спасибо. Только вместо диаграммы классов было бы интереснее увидеть диаграмму деятельности
0
А поясните, пожалуйста, почему
RequestHandler(RequestHandler *successor): successor(successor) { }
Насколько я понимаю, тут вызов конструктора этемента successor, но ведь у нас есть только указатель на него (который получаем в сончтруированном виде), не надо ли вместо него написать
RequestHandler(RequestHandler *successor) { this.successor = successor}
RequestHandler(RequestHandler *successor): successor(successor) { }
Насколько я понимаю, тут вызов конструктора этемента successor, но ведь у нас есть только указатель на него (который получаем в сончтруированном виде), не надо ли вместо него написать
RequestHandler(RequestHandler *successor) { this.successor = successor}
-1
Стремление внедрять шаблоны это хорошо, главное понимать их правильно ( не как большинство понимает MVC).
Так вот:
«Возможен еще вариант обработки и последующей передачи. „
Это не “возможен» — это главный мотив использовать этот шаблон. Если у вас нет необходимости совместной обработки несколькими обработчиками приходящего сообщения — то его применение проигрывает простому Map [Тип сообщения] -> [Экземпляр класса с интерфейсом обработчика] как по понятности/количеству кода, так и по скорости работы (обычно не так важно)
Так вот:
«Возможен еще вариант обработки и последующей передачи. „
Это не “возможен» — это главный мотив использовать этот шаблон. Если у вас нет необходимости совместной обработки несколькими обработчиками приходящего сообщения — то его применение проигрывает простому Map [Тип сообщения] -> [Экземпляр класса с интерфейсом обработчика] как по понятности/количеству кода, так и по скорости работы (обычно не так важно)
+1
Спасибо за статью.
Хороший пример использования — фрейморк Netty (Java), обработка запроса и ответа.
Хороший пример использования — фрейморк Netty (Java), обработка запроса и ответа.
0
Sign up to leave a comment.
Паттерн проектирования «Цепочка обязанностей» / «Chain of Responsibility»