{"id":2022,"date":"2019-05-30T09:00:37","date_gmt":"2019-05-30T06:00:37","guid":{"rendered":"http:\/\/demensdeum.com\/blog\/?p=2022"},"modified":"2024-12-16T22:32:37","modified_gmt":"2024-12-16T19:32:37","slug":"chain-of-responsibility-pattern","status":"publish","type":"post","link":"https:\/\/demensdeum.com\/blog\/2019\/05\/30\/chain-of-responsibility-pattern\/","title":{"rendered":"Chain of Responsibilities Pattern"},"content":{"rendered":"<p>Chain of responsibility refers to behavioral design patterns.<\/p>\n<p><a href=\"https:\/\/www.flickr.com\/photos\/122565603@N02\/13689239584\/\" target=\"_blank\" rel=\"noopener\"><img loading=\"lazy\" decoding=\"async\" class=\"alignnone size-full wp-image-2025\" src=\"https:\/\/demensdeum.com\/blog\/wp-content\/uploads\/2019\/05\/13689239584_12c1c20ebc_z1.jpg\" alt=\"\" width=\"427\" height=\"640\" \/><\/a><br \/>\n<a class=\"owner-name truncate no-outline\" title=\"Go to Ganna Dolbieva's photostream\" href=\"https:\/\/www.flickr.com\/photos\/122565603@N02\/\" target=\"_blank\" rel=\"noopener\" data-track=\"attributionNameClick\">Ganna Dolbieva<\/a><\/p>\n<p>The film company Ja-pictures shot a documentary about communist Rastafarians from Liberia called &#8220;Red Dawn of Marley&#8221;. The film is very long (8 hours), interesting, but before sending it to distribution, it turned out that in some countries, frames and phrases from the film may be considered heresy and not give a distribution license. The producers of the film decide to cut out moments containing questionable phrases from the film, manually and automatically. Double checking is necessary so that the distributor&#8217;s representatives are not simply shot in some countries, in case of an error during manual viewing and editing.<br \/>Countries are divided into four groups &#8211; countries without censorship, with moderate, medium and very strict censorship. A decision is made to use neural networks to classify the level of heresy in the review fragment of the film. Very expensive state-of-art neural networks trained for different levels of censorship are purchased for the project, the developer&#8217;s task is to break the film into fragments and pass them along a chain of neural networks, from free to strict, until one of them detects heresy, then the fragment is transferred for manual review for further editing. It is impossible to go through all the neural networks, since too much computing power is spent on their work (we still have to pay for electricity), it is enough to stop at the first one that worked.<br \/>Naive pseudocode implementation:<\/p>\n<div class=\"hcb_wrap\">\n<pre class=\"prism line-numbers lang-unknown\" data-lang=\"unknown\"><code>import StateOfArtCensorshipHLNNClassifiers\n\nprotocol MovieCensorshipClassifier {\n    func shouldBeCensored(movieChunk: MovieChunk) -&gt; Bool\n}\n\nclass CensorshipClassifier: MovieCensorshipClassifier {\n\n    let hnnclassifier: StateOfArtCensorshipHLNNClassifier\n\n    init(_ hnnclassifier: StateOfArtCensorshipHLNNClassifier) {\n        self.hnnclassifier = hnnclassifier\n    }\n    \n    func shouldBeCensored(_ movieChunk: MovieChunk) -&gt; Bool {\n        return hnnclassifier.shouldBeCensored(movieChunk)\n    }\n}\n\nlet lightCensorshipClassifier = CensorshipClassifier(StateOfArtCensorshipHLNNClassifier(\"light\"))\nlet normalCensorshipClassifier = CensorshipClassifier(StateOfArtCensorshipHLNNClassifier(\"normal\"))\nlet hardCensorshipClassifier = CensorshipClassifier(StateOfArtCensorshipHLNNClassifier(\"hard\"))\n\nlet classifiers = [lightCensorshipClassifier, normalCensorshipClassifier, hardCensorshipClassifier]\n\nlet movie = Movie(\"Red Jah rising\")\nfor chunk in movie.chunks {\n    for classifier in classifiers {\n        if classifier.shouldBeCensored(chunk) == true {\n            print(\"Should censor movie chunk: \\(chunk), reported by \\(classifier)\")\n        }\n   }\n}\n<\/code><\/pre>\n<\/div>\n<p>In general, the solution with an array of classifiers is not so bad, However! Let&#8217;s imagine that we cannot create an array, we have the ability to create only one classifier entity, which already determines the type of censorship for a fragment of the film. Such restrictions are possible when developing a library that extends the functionality of the application (plugin).<br \/>Let&#8217;s use the decorator pattern &#8211; add a reference to the next classifier in the chain to the classifier class, and stop the verification process at the first successful classification.<br \/>This way we implement the Chain of Responsibility pattern:<\/p>\n<div class=\"hcb_wrap\">\n<pre class=\"prism line-numbers lang-unknown\" data-lang=\"unknown\"><code>import StateOfArtCensorshipHLNNClassifiers\n\nprotocol MovieCensorshipClassifier {\n    func shouldBeCensored(movieChunk: MovieChunk) -&gt; Bool\n}\n\nclass CensorshipClassifier: MovieCensorshipClassifier {\n\n    let nextClassifier: CensorshipClassifier?\n    let hnnclassifier: StateOfArtCensorshipHLNNClassifier\n\n    init(_ hnnclassifier: StateOfArtCensorshipHLNNClassifier, nextClassifier: CensorshipClassifiers?) {\n            self.nextClassifier = nextClassifier\n            self.hnnclassifier = hnnclassifier\n    }\n    \n    func shouldBeCensored(_ movieChunk: MovieChunk) -&gt; Bool {\n        let result = hnnclassifier.shouldBeCensored(movieChunk)\n        \n        print(\"Should censor movie chunk: \\(movieChunk), reported by \\(self)\")\n        \n        if result == true {\n                return true\n        }\n        else {\n                return nextClassifier?.shouldBeCensored(movieChunk) ?? false\n        }\n    }\n}\n\nlet censorshipClassifier = CensorshipClassifier(StateOfArtCensorshipHLNNClassifier(\"light\"), nextClassifier: CensorshipClassifier(StateOfArtCensorshipHLNNClassifier(\"normal\", nextClassifier: CensorshipClassifier(StateOfArtCensorshipHLNNClassifier(\"hard\")))))\n\nlet movie = Movie(\"Red Jah rising\")\nfor chunk in movie.chunks {\n    censorshipClassifier.shouldBeCensored(chunk)\n}\n<\/code><\/pre>\n<\/div>\n<h3>References<\/h3>\n<p><a href=\"https:\/\/refactoring.guru\/ru\/design-patterns\/chain-of-responsibility\" target=\"_blank\" rel=\"noopener noreferrer\">https:\/\/refactoring.guru\/ru\/ design-patterns\/chain-of-responsibility<\/a><\/p>\n<h3>Source Code<\/h3>\n<p><a href=\"https:\/\/gitlab.com\/demensdeum\/patterns\/\" target=\"_blank\" rel=\"noopener noreferrer\">https:\/\/gitlab.com\/demensdeum\/patterns\/<\/a>< \/p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Chain of responsibility refers to behavioral design patterns. Ganna Dolbieva The film company Ja-pictures shot a documentary about communist Rastafarians from Liberia called &#8220;Red Dawn of Marley&#8221;. The film is very long (8 hours), interesting, but before sending it to distribution, it turned out that in some countries, frames and phrases from the film may<a class=\"more-link\" href=\"https:\/\/demensdeum.com\/blog\/2019\/05\/30\/chain-of-responsibility-pattern\/\">Continue reading <span class=\"screen-reader-text\">&#8220;Chain of Responsibilities Pattern&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[61,52],"tags":[105,95],"class_list":["post-2022","post","type-post","status-publish","format-standard","hentry","category-techie","category-tutorials","tag-chain-of-responsibility","tag-patterns","entry"],"translation":{"provider":"WPGlobus","version":"3.0.2","language":"en","enabled_languages":["en","ru","zh","de","fr","ja","pt","hi"],"languages":{"en":{"title":true,"content":true,"excerpt":false},"ru":{"title":true,"content":true,"excerpt":false},"zh":{"title":true,"content":true,"excerpt":false},"de":{"title":true,"content":true,"excerpt":false},"fr":{"title":true,"content":true,"excerpt":false},"ja":{"title":true,"content":true,"excerpt":false},"pt":{"title":true,"content":true,"excerpt":false},"hi":{"title":false,"content":false,"excerpt":false}}},"jetpack_featured_media_url":"","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/demensdeum.com\/blog\/wp-json\/wp\/v2\/posts\/2022","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/demensdeum.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/demensdeum.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/demensdeum.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/demensdeum.com\/blog\/wp-json\/wp\/v2\/comments?post=2022"}],"version-history":[{"count":18,"href":"https:\/\/demensdeum.com\/blog\/wp-json\/wp\/v2\/posts\/2022\/revisions"}],"predecessor-version":[{"id":3956,"href":"https:\/\/demensdeum.com\/blog\/wp-json\/wp\/v2\/posts\/2022\/revisions\/3956"}],"wp:attachment":[{"href":"https:\/\/demensdeum.com\/blog\/wp-json\/wp\/v2\/media?parent=2022"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/demensdeum.com\/blog\/wp-json\/wp\/v2\/categories?post=2022"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/demensdeum.com\/blog\/wp-json\/wp\/v2\/tags?post=2022"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}