Chain-of-responsibility pattern

In object-oriented design, the chain-of-responsibility pattern is a behavioral design pattern consisting of a source of command objects and a series of processing objects.[1] Each processing object contains logic that defines the types of command objects that it can handle; the rest are passed to the next processing object in the chain. A mechanism also exists for adding new processing objects to the end of this chain.

In a variation of the standard chain-of-responsibility model, some handlers may act as dispatchers, capable of sending commands out in a variety of directions, forming a tree of responsibility. In some cases, this can occur recursively, with processing objects calling higher-up processing objects with commands that attempt to solve some smaller part of the problem; in this case recursion continues until the command is processed, or the entire tree has been explored. An XML interpreter might work in this manner.

This pattern promotes the idea of loose coupling.

The chain-of-responsibility pattern is structurally nearly identical to the decorator pattern, the difference being that for the decorator, all classes handle the request, while for the chain of responsibility, exactly one of the classes in the chain handles the request. This is a strict definition of the Responsibility concept in the GoF book. However, many implementations (such as loggers below, or UI event handling, or servlet filters in Java, etc.) allow several elements in the chain to take responsibility.

Overview

The Chain of Responsibility[2] design pattern is one of the twenty-three well-known GoF design patterns that describe common solutions to recurring design problems when designing flexible and reusable object-oriented software, that is, objects that are easier to implement, change, test, and reuse.

What problems can the Chain of Responsibility design pattern solve?

  • Coupling the sender of a request to its receiver should be avoided.
  • It should be possible that more than one receiver can handle a request.

Implementing a request directly within the class that sends the request is inflexible because it couples the class to a particular receiver and makes it impossible to support multiple receivers.[3]

What solution does the Chain of Responsibility design pattern describe?

  • Define a chain of receiver objects having the responsibility, depending on run-time conditions, to either handle a request or forward it to the next receiver on the chain (if any).

This enables us to send a request to a chain of receivers without having to know which one handles the request. The request gets passed along the chain until a receiver handles the request. The sender of a request is no longer coupled to a particular receiver.

See also the UML class and sequence diagram below.

Structure

UML class and sequence diagram

A sample UML class and sequence diagram for the Chain of Responsibility design pattern.[4]

In the above UML class diagram, the Sender class doesn't refer to a particular receiver class directly. Instead, Sender refers to the Handler interface for handling a request (handler.handleRequest()), which makes the Sender independent of which receiver handles the request. The Receiver1, Receiver2, and Receiver3 classes implement the Handler interface by either handling or forwarding a request (depending on run-time conditions).
The UML sequence diagram shows the run-time interactions: In this example, the Sender object calls handleRequest() on the receiver1 object (of type Handler). The receiver1 forwards the request to receiver2, which in turn forwards the request to receiver3, which handles (performs) the request.

Example

This C++11 implementation is based on the pre C++98 implementation in the book.[5]

#include <iostream>
#include <memory>

typedef int Topic;
constexpr Topic NO_HELP_TOPIC = -1;

// defines an interface for handling requests.
class HelpHandler { // Handler
public:
  HelpHandler(HelpHandler* h = nullptr, Topic t = NO_HELP_TOPIC)
    : successor(h), topic(t) {}
  virtual bool hasHelp() {
    return topic != NO_HELP_TOPIC;
  }
  virtual void setHandler(HelpHandler*, Topic) {}
  virtual void handleHelp() {
      std::cout << "HelpHandler::handleHelp\n";
      // (optional) implements the successor link.
      if (successor != nullptr) {
          successor->handleHelp();
      }
  }
  virtual ~HelpHandler() = default;
  HelpHandler(const HelpHandler&) = delete; // rule of three
  HelpHandler& operator=(const HelpHandler&) = delete;
private:
  HelpHandler* successor;
  Topic topic;
};


class Widget : public HelpHandler {
public:
  Widget(const Widget&) = delete; // rule of three
  Widget& operator=(const Widget&) = delete;
protected:
  Widget(Widget* w, Topic t = NO_HELP_TOPIC) 
    : HelpHandler(w, t), parent(nullptr) {
    parent = w;
  }
private:
  Widget* parent;
};

// handles requests it is responsible for.
class Button : public Widget { // ConcreteHandler
public:
  Button(std::shared_ptr<Widget> h, Topic t = NO_HELP_TOPIC) : Widget(h.get(), t) {}
  virtual void handleHelp() {
    // if the ConcreteHandler can handle the request, it does so; otherwise it forwards the request to its successor.
    std::cout << "Button::handleHelp\n";
    if (hasHelp()) {
      // handles requests it is responsible for.
    } else {      
      // can access its successor.
      HelpHandler::handleHelp();
    }
  }
};

class Dialog : public Widget { // ConcreteHandler
public:
  Dialog(std::shared_ptr<HelpHandler> h, Topic t = NO_HELP_TOPIC) : Widget(nullptr) {
    setHandler(h.get(), t);
  }
  virtual void handleHelp() {
    std::cout << "Dialog::handleHelp\n";
    // Widget operations that Dialog overrides...
    if(hasHelp()) {
      // offer help on the dialog
    } else {
      HelpHandler::handleHelp();
    }
  }
};

class Application : public HelpHandler {
public:
  Application(Topic t) : HelpHandler(nullptr, t) {}
  virtual void handleHelp() {
    std::cout << "Application::handleHelp\n";
    // show a list of help topics
  }
};

int main() {
  constexpr Topic PRINT_TOPIC = 1;
  constexpr Topic PAPER_ORIENTATION_TOPIC = 2;
  constexpr Topic APPLICATION_TOPIC = 3;
  // The smart pointers prevent memory leaks.
  std::shared_ptr<Application> application = std::make_shared<Application>(APPLICATION_TOPIC);
  std::shared_ptr<Dialog> dialog = std::make_shared<Dialog>(application, PRINT_TOPIC);
  std::shared_ptr<Button> button = std::make_shared<Button>(dialog, PAPER_ORIENTATION_TOPIC);

  button->handleHelp();
}

Implementations

Cocoa and Cocoa Touch

The Cocoa and Cocoa Touch frameworks, used for OS X and iOS applications respectively, actively use the chain-of-responsibility pattern for handling events. Objects that participate in the chain are called responder objects, inheriting from the NSResponder (OS X)/UIResponder (iOS) class. All view objects (NSView/UIView), view controller objects (NSViewController/UIViewController), window objects (NSWindow/UIWindow), and the application object (NSApplication/UIApplication) are responder objects.

Typically, when a view receives an event which it can't handle, it dispatches it to its superview until it reaches the view controller or window object. If the window can't handle the event, the event is dispatched to the application object, which is the last object in the chain. For example:

  • On OS X, moving a textured window with the mouse can be done from any location (not just the title bar), unless on that location there's a view which handles dragging events, like slider controls. If no such view (or superview) is there, dragging events are sent up the chain to the window which does handle the dragging event.
  • On iOS, it's typical to handle view events in the view controller which manages the view hierarchy, instead of subclassing the view itself. Since a view controller lies in the responder chain after all of its managed subviews, it can intercept any view events and handle them.

See also

References

  1. ^ "Chain of Responsibility Design Pattern". Archived from the original on 2018-02-27. Retrieved 2013-11-08.
  2. ^ Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides (1994). Design Patterns: Elements of Reusable Object-Oriented Software. Addison Wesley. pp. 223ff. ISBN 0-201-63361-2.{{cite book}}: CS1 maint: multiple names: authors list (link)
  3. ^ "The Chain of Responsibility design pattern - Problem, Solution, and Applicability". w3sDesign.com. Retrieved 2017-08-12.
  4. ^ "The Chain of Responsibility design pattern - Structure and Collaboration". w3sDesign.com. Retrieved 2017-08-12.
  5. ^ Erich Gamma (1994). Design Patterns: Elements of Reusable Object-Oriented Software. Addison Wesley. pp. 189 ff. ISBN 0-201-63361-2.

Read other articles:

Sebuah prasasti makam yang menggambarkan sebuah keluarga Romawi kuno Kode Rumah Tangga Perjanjian Baru (Haustafeln), juga dikenal sebagai Kode Domestik Perjanjian Baru, terdiri dari perintah-perintah dalam tulisan-tulisan Perjanjian Varu dari para rasul Petrus dan Paulus untuk para pasangan umat Kristen dalam struktur masyarakat domestik dan sipil berbeda. Fokus utama dari kode rumah tangga adalah pada suami-istri, orang tua-anak, dan majikan-budak. Dua pasal utama yang menjelaskan hubungan d...

Cet article ou cette section fait référence à des sources qui ne semblent pas présenter la fiabilité et/ou l'indépendance requises. Vous pouvez aider, soit en recherchant des sources de meilleure qualité pour étayer les informations concernées, soit en attribuant clairement ces informations aux sources qui semblent insuffisantes, ce qui permet de mettre en garde le lecteur sur l'origine de l'information. Voir la page de discussion pour plus de détails. Les pays de Bretagne sont des ...

St. Antonius in Tenholt St. Antonius mit Seitenschiff Antoniusfigur über dem Eingang Die Kirche St. Antonius ist die römisch-katholische Filialkirche des Ortsteils Tenholt der Stadt Erkelenz im Kreis Heinsberg (Nordrhein-Westfalen). Die Kirche ist unter Nummer 282 in die Liste der Baudenkmäler in Erkelenz eingetragen. Inhaltsverzeichnis 1 Geschichte 2 Ausstattung 3 Glocken 4 Weblinks 5 Einzelnachweise Geschichte Eine Kapelle in Tenholt wurde im 17. Jahrhundert errichtet. Ob es vorher berei...

Pub on Oxford Street, London The Tottenham redirects here. For the football club, see Tottenham Hotspur F.C.For other uses, see Flying horses (disambiguation). The Flying Horse, 2015 The Flying Horse is a Grade II* listed public house at 6 Oxford Street, Marylebone in the City of Westminster.[1] It was built in the 19th century,[1] and is the last remaining pub on Oxford Street.[2] The pub is on the Campaign for Real Ale's National Inventory of Historic Pub Interiors.&...

Lisa GastoniGastoni dalam Come Play with Me (1968)Lahir28 Juli 1935 (umur 88)Alassio, Liguria, ItaliaPekerjaanAktrisTahun aktif1954–sekarang Lisa Gastoni (lahir 28 Juli 1935) adalah seorang aktris film Italia. Filmografi pilihan They Who Dare (1954) Doctor in the House (1954) Josephine and Men (1955) Man of the Moment (1955) The Baby and the Battleship (1956) Three Men in a Boat (1956) Second Fiddle (1957) Blue Murder at St Trinian's (1957) Man from Tangier (1957) Face in the Nigh...

International cricket tour Afghan cricket team in Bangladesh in 2021–22    Bangladesh AfghanistanDates 23 February – 5 March 2022Captains Tamim Iqbal (ODIs)Mahmudullah (T20Is) Hashmatullah Shahidi (ODIs)Mohammad Nabi (T20Is)One Day International seriesResults Bangladesh won the 3-match series 2–1Most runs Litton Das (223) Rahmat Shah (133)Most wickets Shakib Al Hasan (5) Fazalhaq Farooqi (6)Player of the series Litton Das (Ban)Twenty20 International seriesResults 2-match ...

Perang Inggris-Maratha KetigaBagian dari Peperangan Inggris-MarathaTanggalNovember 1817 – Februari 1818LokasiMaharashtra dan wilayah sekitarnyaHasil Kemenangan besar BritaniaBerakhirnya Kemaharajaan MarathaPihak terlibat Kemaharajaan Maratha Peshwa Baji Rao II Malharrao Holkar III Mudhoji II Bhonsle Daulatrao Shinde Various Pindaris Imperium Britania East India CompanyTokoh dan pemimpin Bapu Gokhale (Jenderal Peshwa Baji Rao II) Appa Saheb Bhonsle Malharrao Holkar III Francis Rawdon-Hasting...

سبوتنك 1 نموذج سبوتنك-1 في المتحف الوطني للقوات الجوية الأمريكية المشغل مكتب التصميم التجريبي-1 المصنع إنرجيا  الدورات المكتملة 1440   تاريخ الإطلاق 4 أكتوبر 1957 مركبة الإطلاق إر-7 موقع الإطلاق منصة جاجارين تاريخ الانحلال 4 يناير 1958  الوزن 83.6 كلجم نصف المحور الرئيسي 6955.2 كي

Radio station in NoordwijkArrow Classic RockNoordwijkBroadcast areaNetherlandsFrequencyOnly on Dutch cables. Available worldwide through internetProgrammingFormatRock music (1960s-today)OwnershipOwnerMedia Management & Projects BVGerro VonkHistoryFirst air date1996LinksWebcastWebstreamWebsiteArrow.nl/ Arrow Classic Rock is a Dutch radio station, that plays classic rock and some modern rock. Arrow Classic Rock broadcasts on FM and is also receivable via cable, all nationwide. Owned by Ad O...

Artikel ini bukan mengenai Arena Kota Meksiko. Arena MéxicoLa Catedral de la Lucha LibreKatedral Lucha LibreNama lamaArena Modelo (1910–1950)Lokasi189 Calle Dr. Lavista, Colonia Doctores, Kota Meksiko, 06720Koordinat19°25′29″N 99°9′7″W / 19.42472°N 99.15194°W / 19.42472; -99.15194Koordinat: 19°25′29″N 99°9′7″W / 19.42472°N 99.15194°W / 19.42472; -99.15194PemilikConsejo Mundial de Lucha Libre (CMLL)Kapasitas16,500 (Gula...

Chess variant played on a 10x8 board abcdefghij 8877665544332211abcdefghij Janus Chess initial position. The januses (knight+bishop compounds) start on the b- and i-files. Janus Chess is a chess variant invented in 1978 by Werner Schöndorf[1] from Bildstock, Germany. It is played on a 10×8 board and features a fairy chess piece, the janus, with the combined moves of a bishop and a knight. The janus piece is named after the Roman god Janus because this god was usually depicted with t...

Form of coastal defence Not to be confused with Breakwater (structure), Mole (architecture), or Revetment. This article's tone or style may not reflect the encyclopedic tone used on Wikipedia. See Wikipedia's guide to writing better articles for suggestions. (July 2019) (Learn how and when to remove this template message) An example of a modern seawall in Ventnor on the Isle of Wight, England People socializing and walking at the Malecón, Havana Seawall at Urangan, Queensland A seawall (or s...

George Jones discographyJones performing at Harrah's Metropolis in Metropolis, Illinois in June 2002Music videos21Singles182As a solo artist136As a collaborative artist31As a featured artist8Promotional singles7Other charted songs14 The singles discography of American country artist, George Jones, contains 182 singles. Of the total, 136 were released with Jones as the solo artist. In addition, 31 were issued with Jones being part of a collaboration (not counting his duets with Tammy Wynette)....

Japanese TV series or program Ultraman GingaGenre Tokusatsu Superhero Sci-Fi Action/Adventure Kaiju Kyodai Hero Created byTsuburaya ProductionsWritten by Keiichi Hasegawa Akira Tanizaki Kenichi Araki Masanao Akahoshi Junichiro Ashiki Directed by Yuichi Abe Tomoo Haraguchi Kengo Kaji Yoshikazu Ishii Yusuke Murakami Starring Takuya Negishi Mio Miyatake Mizuki Ohno Kirara Takuya Kusakawa Opening themeLegend of Galaxy ~Ginga no Hasha~ by Toshihiko Takamizawa and Mamoru MiyanoComposerTakao Ko...

Television channel Polsat FilmCountryPolandBroadcast areaPolandProgrammingLanguage(s)PolishPicture format16:9 576i (SDTV) 16:9 1080i (HDTV)OwnershipOwnerTelewizja PolsatSister channelsPolsat Film 2HistoryLaunchedOctober 2, 2009LinksWebsitewww.polsatfilm.plAvailabilityTerrestrialPolish digitalTV Mobilna - MUX 4 (pay) Polsat Film is a Polish television channel which broadcasts movies. Polsat received a license to broadcast on March 17, 2009, under the name Polsat Kino. It started broadcasting o...

Đường sắt, hay vận tải đường sắt, là loại hình vận chuyển/vận tải hành khách và hàng hóa bằng phương tiện có bánh được thiết kế để chạy trên loại đường đặc biệt là đường ray (đường rầy).Giao thông hàng hóa bằng đường sắt ở Việt Nam Đường ray bao gồm hai thanh thép chạy song song đặt cố định xuống nền là các thanh chịu lực bằng gỗ, bê tông hay sắt thép (gọi chung l...

JokerPoster rilis teatrikalSutradara Shirish Kunder Produser Farah Khan Akshay Kumar Ditulis oleh Shirish Kunder PemeranAkshay KumarSonakshi SinhaMinisha LambaShreyas TalpadePenata musikG. V. Prakash KumarGaurav DagaonkarSinematograferSudeep ChatterjeePenyuntingShirish KunderPerusahaanproduksiThree's CompanyDistributorHari Om EntertainmentUTV Motion PicturesTanggal rilis 31 Agustus 2012 (2012-08-31)[1] Durasi103 menit[2]Negara India Bahasa Hindi Anggaran₹450 juta ...

Peta Indonesia Raya, termasuk Indonesia, Malaysia, Singapura, Brunei, dan Timor Leste. Indonesia Raya adalah konsep politik yang bertujuan untuk mempersatukan bangsa Indonesia atau bangsa Melayu yang terpisah dalam wilayah koloni Britania Raya di Semenanjung Malaya dan Borneo Utara (wilayah yang kini membentuk negara Malaysia, Singapura, dan Brunei), dengan Hindia Belanda (kini Indonesia), serta wilayah koloni Portugis di Timor Leste menjadi suatu bangsa besar dan berdaulat.[1] Melayu...

Canadian TV series This article is an orphan, as no other articles link to it. Please introduce links to this page from related articles; try the Find link tool for suggestions. (April 2023) Paris ParisGenreComedyCreated byDominic Desjardins, Rayne ZukermanWritten byDominic Desjardins, Rayne ZukermanDirected byDominic DesjardinsStarringBenoît Mauffette, Maxim RoyMusic byAntoine GrattonCountry of originCanadaOriginal languagesFrenchEnglishNo. of seasons2No. of episodes26ProductionProducerRayn...

Binary star in the constellation Andromeda Theta Andromedae Location of θ Andromedae (circled) Observation dataEpoch J2000      Equinox J2000 Constellation Andromeda Right ascension 00h 17m 05.50236s[1] Declination +38° 40′ 53.8886″[1] Apparent magnitude (V) 4.61[2] Characteristics Evolutionary stage main sequence[3] Spectral type A2 V[4] U−B color index +0.05[2]...