{"id":6135,"date":"2025-11-10T13:45:21","date_gmt":"2025-11-10T12:45:21","guid":{"rendered":"https:\/\/gdksoftware.com\/?post_type=knowledge&#038;p=6135"},"modified":"2025-11-10T13:45:21","modified_gmt":"2025-11-10T12:45:21","slug":"eventbus-pattern","status":"publish","type":"knowledge","link":"https:\/\/gdksoftware.com\/nl\/kennisbank\/eventbus-pattern","title":{"rendered":"EventBus pattern"},"content":{"rendered":"<h2>Introductie<\/h2>\n<p>Tijdens de ontwikkeling van Codolex merkten we dat het verbinden van verschillende formulieren en componenten via callback events zorgde voor sterk gekoppelde code. Een voorbeeld: wanneer een gebruiker een project opslaat, moeten meerdere onderdelen van de applicatie reageren. De lijst met recente items moet worden bijgewerkt, de backup manager moet in actie komen en de analytics tracker moet de gebeurtenis vastleggen. Met overal callback events werd dit al snel moeilijk onderhoudbaar. Om dit probleem op te lossen, hebben we het EventBus pattern ge\u00efmplementeerd.<\/p>\n<p>De EventBus biedt een centrale plek om events te distribueren. Wanneer een proces een event naar de EventBus stuurt, distribueert deze het automatisch naar alle componenten die zich hebben geabonneerd op dat eventtype. Dit is een implementatie van het <a href=\"https:\/\/refactoring.guru\/design-patterns\/observer\">Observer pattern<\/a> gecombineerd met het <a href=\"https:\/\/refactoring.guru\/design-patterns\/mediator\">Mediator pattern<\/a> om code te ontkoppelen.<\/p>\n<h3>Implementation<\/h3>\n<p>Bij het versturen van events moeten we kunnen identificeren om wat voor soort event het gaat. We gebruiken hiervoor een enumeratie om het eventtype te herkennen. De waarden zijn afhankelijk van je specifieke implementatie.<\/p>\n<div style=\"background: #ffffff; overflow: auto; width: auto; border: solid gray; border-width: .1em .1em .1em .8em; padding: .2em .6em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #888;\">{$SCOPEDENUMS ON}<\/span>\r\n<span style=\"color: #888;\">\/\/ Indicates which event is fired<\/span>\r\nTEventType <span style=\"color: #333;\">=<\/span> (<span style=\"color: #080; font-weight: bold;\">New<\/span><span style=\"color: #333;\">,<\/span> Update<span style=\"color: #333;\">,<\/span> Open<span style=\"color: #333;\">,<\/span> <span style=\"color: #007020;\">Close<\/span><span style=\"color: #333;\">,<\/span> Cancel<span style=\"color: #333;\">,<\/span> Validation)<span style=\"color: #333;\">;<\/span>\r\nTEventTypes <span style=\"color: #333;\">=<\/span> <span style=\"color: #080; font-weight: bold;\">set<\/span> <span style=\"color: #080; font-weight: bold;\">of<\/span> TEventType<span style=\"color: #333;\">;<\/span>\r\n<span style=\"color: #888;\">{$SCOPEDENUMS OFF}<\/span>\r\n<\/pre>\n<\/div>\n<p>Vervolgens defini\u00ebren we de EventBus. We defini\u00ebren deze als generic, zodat we bij het gebruik direct met de juiste types werken. De EventBus heeft een procedure nodig waarmee observers zich kunnen abonneren en een procedure waarmee een event kan worden afgevuurd.<\/p>\n<div style=\"background: #ffffff; overflow: auto; width: auto; border: solid gray; border-width: .1em .1em .1em .8em; padding: .2em .6em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #888;\">\/\/ Procedure definition to receive events<\/span>\r\nTEventAction<span style=\"color: #333;\">&lt;<\/span>I<span style=\"color: #333;\">:<\/span> ISerializableObject<span style=\"color: #333;\">&gt;<\/span> <span style=\"color: #333;\">=<\/span> \r\n       reference <span style=\"color: #080; font-weight: bold;\">to<\/span> <span style=\"color: #080; font-weight: bold;\">procedure<\/span>(<span style=\"color: #080; font-weight: bold;\">const<\/span> EventType<span style=\"color: #333;\">:<\/span> TEventType<span style=\"color: #333;\">;<\/span> <span style=\"color: #080; font-weight: bold;\">const<\/span> Data<span style=\"color: #333;\">:<\/span> I)<span style=\"color: #333;\">;<\/span>\r\n\r\n<span style=\"color: #888;\">\/\/ Procedure to unsubscribe<\/span>\r\nTUnsubscribeEvent <span style=\"color: #333;\">=<\/span> reference <span style=\"color: #080; font-weight: bold;\">to<\/span> <span style=\"color: #080; font-weight: bold;\">procedure<\/span><span style=\"color: #333;\">;<\/span>\r\n\r\n<span style=\"color: #888;\">\/\/ Base (generic) event bus interface<\/span>\r\n<span style=\"color: #06b; font-weight: bold;\">IEventBus<\/span><span style=\"color: #333;\">&lt;<\/span>I<span style=\"color: #333;\">:<\/span> ISerializableObject<span style=\"color: #333;\">&gt;<\/span> <span style=\"color: #333;\">=<\/span> <span style=\"color: #080; font-weight: bold;\">interface<\/span>\r\n\r\n  <span style=\"color: #080; font-weight: bold;\">function<\/span> <span style=\"color: #06b; font-weight: bold;\">Subscribe<\/span>(<span style=\"color: #080; font-weight: bold;\">const<\/span> OnEvent<span style=\"color: #333;\">:<\/span> TEventAction<span style=\"color: #333;\">&lt;<\/span>I<span style=\"color: #333;\">&gt;<\/span>)<span style=\"color: #333;\">:<\/span> TUnsubscribeEvent<span style=\"color: #333;\">;<\/span> overload<span style=\"color: #333;\">;<\/span>\r\n  <span style=\"color: #888;\">\/\/ Overloaded variant to register filtered subscriptions<\/span>\r\n  <span style=\"color: #080; font-weight: bold;\">function<\/span> <span style=\"color: #06b; font-weight: bold;\">Subscribe<\/span>(<span style=\"color: #080; font-weight: bold;\">const<\/span> OnEvent<span style=\"color: #333;\">:<\/span> TEventAction<span style=\"color: #333;\">&lt;<\/span>I<span style=\"color: #333;\">&gt;;<\/span> \r\n                     <span style=\"color: #080; font-weight: bold;\">const<\/span> Filter<span style=\"color: #333;\">:<\/span> TEventTypes)<span style=\"color: #333;\">:<\/span> TUnsubscribeEvent<span style=\"color: #333;\">;<\/span> overload<span style=\"color: #333;\">;<\/span>\r\n\r\n  <span style=\"color: #080; font-weight: bold;\">procedure<\/span> <span style=\"color: #06b; font-weight: bold;\">Post<\/span>(<span style=\"color: #080; font-weight: bold;\">const<\/span> EventType<span style=\"color: #333;\">:<\/span> TEventType<span style=\"color: #333;\">;<\/span> <span style=\"color: #080; font-weight: bold;\">const<\/span> Data<span style=\"color: #333;\">:<\/span> I)<span style=\"color: #333;\">;<\/span>\r\n<span style=\"color: #080; font-weight: bold;\">end<\/span><span style=\"color: #333;\">;<\/span>\r\n<\/pre>\n<\/div>\n<p>Met de basis van de EventBus gedefinieerd, kunnen we event buses maken voor specifieke types:<\/p>\n<div style=\"background: #ffffff; overflow: auto; width: auto; border: solid gray; border-width: .1em .1em .1em .8em; padding: .2em .6em;\">\n<pre style=\"margin: 0; line-height: 125%;\">  <span style=\"color: #888;\">\/\/ Specific interfaces for different types of event buses<\/span>\r\n  IProjectEventBus <span style=\"color: #333;\">=<\/span> <span style=\"color: #080; font-weight: bold;\">interface<\/span>(IEventBus<span style=\"color: #333;\">&lt;<\/span>IProject<span style=\"color: #333;\">&gt;<\/span>)\r\n  <span style=\"color: #080; font-weight: bold;\">end<\/span><span style=\"color: #333;\">;<\/span>\r\n\r\n  IDataEntityEventBus <span style=\"color: #333;\">=<\/span> <span style=\"color: #080; font-weight: bold;\">interface<\/span>(IEventBus<span style=\"color: #333;\">&lt;<\/span>IDataEntity<span style=\"color: #333;\">&gt;<\/span>)\r\n  <span style=\"color: #080; font-weight: bold;\">end<\/span><span style=\"color: #333;\">;<\/span>\r\n\r\n  IFlowEventBus <span style=\"color: #333;\">=<\/span> <span style=\"color: #080; font-weight: bold;\">interface<\/span>(IEventBus<span style=\"color: #333;\">&lt;<\/span>IFlow<span style=\"color: #333;\">&gt;<\/span>)\r\n  <span style=\"color: #080; font-weight: bold;\">end<\/span><span style=\"color: #333;\">;<\/span>\r\n<\/pre>\n<\/div>\n<h3>De master event bus<\/h3>\n<p>We willen een eenvoudige en transparante manier om de event bus structuur te gebruiken. Om dit te bereiken, gebruiken we een master event bus die een collectie van event buses bevat. Door deze master bus een singleton te maken in je applicatie, is er een uniforme manier om toegang te krijgen tot alle onderliggende event buses.<\/p>\n<div style=\"background: #ffffff; overflow: auto; width: auto; border: solid gray; border-width: .1em .1em .1em .8em; padding: .2em .6em;\">\n<pre style=\"margin: 0; line-height: 125%;\">  <span style=\"color: #888;\">\/\/ Master event bus to expose the available types of event buses (should be a singleton)<\/span>\r\n  IMasterEventBus <span style=\"color: #333;\">=<\/span> <span style=\"color: #080; font-weight: bold;\">interface<\/span>\r\n    <span style=\"color: #080; font-weight: bold;\">function<\/span> <span style=\"color: #06b; font-weight: bold;\">Project<\/span><span style=\"color: #333;\">:<\/span> IProjectEventBus<span style=\"color: #333;\">;<\/span>\r\n    <span style=\"color: #080; font-weight: bold;\">function<\/span> <span style=\"color: #06b; font-weight: bold;\">Flow<\/span><span style=\"color: #333;\">:<\/span> IFlowEventBus<span style=\"color: #333;\">;<\/span>\r\n    <span style=\"color: #080; font-weight: bold;\">function<\/span> <span style=\"color: #06b; font-weight: bold;\">DataEntity<\/span><span style=\"color: #333;\">:<\/span> IDataEntityEventBus<span style=\"color: #333;\">;<\/span>\r\n  <span style=\"color: #080; font-weight: bold;\">end<\/span><span style=\"color: #333;\">;<\/span>\r\n<\/pre>\n<\/div>\n<h3>Abonnementen beheren<\/h3>\n<p>Wanneer iemand zich abonneert op een event bus, geeft de procedure een <strong>TUnsubscribeEvent<\/strong> terug die gebruikt kan worden om het abonnement op te zeggen. Als je je abonneert op meerdere event buses, wil je deze allemaal in \u00e9\u00e9n keer kunnen opruimen. Hiervoor defini\u00ebren we een aparte interface die de unsubscribe events bijhoudt en opruimt via een enkele functie (of wanneer het object automatisch wordt vernietigd).<\/p>\n<div style=\"background: #ffffff; overflow: auto; width: auto; border: solid gray; border-width: .1em .1em .1em .8em; padding: .2em .6em;\">\n<pre style=\"margin: 0; line-height: 125%;\">  <span style=\"color: #888;\">\/\/ Interface to store unsubscribe events and unsubscribe all at once<\/span>\r\n  IUnsubscriber <span style=\"color: #333;\">=<\/span> <span style=\"color: #080; font-weight: bold;\">interface<\/span>(IList<span style=\"color: #333;\">&lt;<\/span>TUnsubscribeEvent<span style=\"color: #333;\">&gt;<\/span>)\r\n    <span style=\"color: #080; font-weight: bold;\">procedure<\/span> <span style=\"color: #06b; font-weight: bold;\">Unsubscribe<\/span><span style=\"color: #333;\">;<\/span>\r\n  <span style=\"color: #080; font-weight: bold;\">end<\/span><span style=\"color: #333;\">;<\/span>\r\n<\/pre>\n<\/div>\n<h3>Voorbeeld gebruik<\/h3>\n<p>Nu we alles op zijn plaats hebben, werkt het in de praktijk als volgt:<\/p>\n<div style=\"background: #ffffff; overflow: auto; width: auto; border: solid gray; border-width: .1em .1em .1em .8em; padding: .2em .6em;\">\n<pre style=\"margin: 0; line-height: 125%;\"><span style=\"color: #888;\">\/\/ Somewhere in the constructor: declare the unsubscriber<\/span>\r\nFUnsubscriber <span style=\"color: #333;\">:=<\/span> GlobalContainer<span style=\"color: #333;\">.<\/span>Resolve<span style=\"color: #333;\">&lt;<\/span>IUnsubscriber<span style=\"color: #333;\">&gt;;<\/span>\r\n\r\n<span style=\"color: #888;\">\/\/ Declare and get the master event bus<\/span>\r\n<span style=\"color: #080; font-weight: bold;\">var<\/span> EventBus <span style=\"color: #333;\">:=<\/span> GlobalContainer<span style=\"color: #333;\">.<\/span>Resolve<span style=\"color: #333;\">&lt;<\/span>IMasterEventBus<span style=\"color: #333;\">&gt;;<\/span>\r\n\r\n<span style=\"color: #888;\">\/\/ Subscribe for specific flow events<\/span>\r\n<span style=\"color: #080; font-weight: bold;\">var<\/span> UnsubscribeFlow <span style=\"color: #333;\">:=<\/span> EventBus<span style=\"color: #333;\">.<\/span>Flow<span style=\"color: #333;\">.<\/span>Subscribe(\r\n                        <span style=\"color: #080; font-weight: bold;\">procedure<\/span>(<span style=\"color: #080; font-weight: bold;\">const<\/span> EventType<span style=\"color: #333;\">:<\/span> TEventType<span style=\"color: #333;\">;<\/span> <span style=\"color: #080; font-weight: bold;\">const<\/span> Data<span style=\"color: #333;\">:<\/span> IFlow)\r\n                        <span style=\"color: #080; font-weight: bold;\">begin<\/span>\r\n                          <span style=\"color: #888;\">\/\/ Handle the flow event<\/span>\r\n                        <span style=\"color: #080; font-weight: bold;\">end<\/span><span style=\"color: #333;\">,<\/span>\r\n                        [TEventType<span style=\"color: #333;\">.<\/span>Open<span style=\"color: #333;\">,<\/span> TEventType<span style=\"color: #333;\">.<\/span>Close])<span style=\"color: #333;\">;<\/span>\r\n\r\nFUnsubscriber<span style=\"color: #333;\">.<\/span>Add(UnsubscribeFlow)<span style=\"color: #333;\">;<\/span>\r\n\r\n<span style=\"color: #888;\">\/\/ Subscribe for all project events<\/span>\r\nFUnsubscriber<span style=\"color: #333;\">.<\/span>Add(\r\n  EventBus<span style=\"color: #333;\">.<\/span>Project<span style=\"color: #333;\">.<\/span>Subscribe(\r\n    <span style=\"color: #080; font-weight: bold;\">procedure<\/span>(<span style=\"color: #080; font-weight: bold;\">const<\/span> EventType<span style=\"color: #333;\">:<\/span> TEventType<span style=\"color: #333;\">;<\/span> <span style=\"color: #080; font-weight: bold;\">const<\/span> Data<span style=\"color: #333;\">:<\/span> IProject)\r\n    <span style=\"color: #080; font-weight: bold;\">begin<\/span>\r\n      <span style=\"color: #888;\">\/\/ Handle the project event<\/span>\r\n    <span style=\"color: #080; font-weight: bold;\">end<\/span>))<span style=\"color: #333;\">;<\/span>\r\n\r\n<span style=\"color: #888;\">\/\/ Post an event about a data entity<\/span>\r\n<span style=\"color: #080; font-weight: bold;\">var<\/span> MyDataEntity<span style=\"color: #333;\">:<\/span> IDataEntity<span style=\"color: #333;\">;<\/span>\r\nEventBus<span style=\"color: #333;\">.<\/span>DataEntity<span style=\"color: #333;\">.<\/span>Post(TEventType<span style=\"color: #333;\">.<\/span>Update<span style=\"color: #333;\">,<\/span> MyDataEntity)<span style=\"color: #333;\">;<\/span>\r\n\r\n<span style=\"color: #888;\">\/\/ Somewhere in the destructor: clean up all subscriptions<\/span>\r\nFUnsubscriber<span style=\"color: #333;\">.<\/span>Unsubscribe<span style=\"color: #333;\">;<\/span>\r\n<\/pre>\n<\/div>\n<p>De filter parameter gebruikt de set-syntax van Delphi om aan te geven welke eventtypes je wilt ontvangen. In het bovenstaande voorbeeld abonneren we ons alleen op <code class=\"\" data-line=\"\">Open<\/code> en <code class=\"\" data-line=\"\">Close<\/code> events voor flows, terwijl we ons voor projecten abonneren op alle eventtypes.<\/p>\n<h3>Voordelen in de praktijk<\/h3>\n<p>Het EventBus pattern heeft ons geholpen om Codolex onderhoudbaar te houden naarmate het groeit. Voordat we dit pattern implementeerden, hadden we callback events verspreid door de hele codebase. Het toevoegen van een nieuwe feature die moest reageren op projectwijzigingen betekende dat we meerdere bestanden moesten aanpassen en alle verbindingen handmatig moesten bijhouden.<\/p>\n<p>Met de EventBus is het toevoegen van nieuwe functionaliteit eenvoudig. Toen we bijvoorbeeld analytics tracking toevoegden, abonneerden we ons simpelweg op de relevante events zonder bestaande code aan te raken. Hetzelfde gold toen we de backup manager en de lijst met recente items implementeerden. Elk component registreert zijn interesse in specifieke events en behandelt deze onafhankelijk.<\/p>\n<p>Deze aanpak maakt testen ook eenvoudiger. We kunnen componenten ge\u00efsoleerd testen en verifi\u00ebren dat ze de juiste events posten, zonder dat de hele applicatiestructuur aanwezig hoeft te zijn.<\/p>\n<h3>Belangrijke overwegingen<\/h3>\n<p>Hoewel het EventBus pattern krachtig is, zijn er een aantal zaken om rekening mee te houden:<\/p>\n<ul>\n<li><strong>Memory management:<\/strong> Zorg er altijd voor dat je het abonnement opzegt wanneer je component wordt vernietigd. Het gebruik van de <code class=\"\" data-line=\"\">IUnsubscriber<\/code> interface met interface reference counting regelt dit automatisch.<\/li>\n<li><strong>Thread safety:<\/strong> Deze implementatie is ontworpen voor single-threaded gebruik. Als je events vanuit meerdere threads moet posten, moet je synchronisatiemechanismen toevoegen.<\/li>\n<li><strong>Error handling:<\/strong> Als een subscriber een exception genereert tijdens het verwerken van een event, kan dit voorkomen dat andere subscribers het event ontvangen. Overweeg try-except blokken toe te voegen in de EventBus implementatie als dit een zorg is voor je applicatie.<\/li>\n<\/ul>\n<h3>Meer leren over Delphi patterns<\/h3>\n<p>Bij GDK Software passen we moderne design patterns zoals de EventBus toe in al onze Delphi-projecten. Dit helpt ons de codekwaliteit te behouden en maakt het gemakkelijker om nieuwe features toe te voegen naarmate applicaties groeien. Wil je meer leren over het schrijven van schone, onderhoudbare Delphi-code? Bekijk onze artikelen over <a href=\"https:\/\/gdksoftware.com\/nl\/kennisbank\/solid-principles-in-delphi-1-het-single-responsibility-principle\">SOLID principles in Delphi<\/a> en <a href=\"https:\/\/gdksoftware.com\/knowledgebase\/dependency-injection-in-delphi\">Dependency Injection in Delphi<\/a>.<\/p>\n<p>Werk je met legacy Delphi-applicaties die moeilijk te onderhouden zijn? Wij kunnen helpen. <a href=\"https:\/\/gdksoftware.com\/contact\">Contact ons<\/a> om te bespreken hoe we je Delphi codebase kunnen moderniseren.<\/p>\n","protected":false},"featured_media":0,"parent":0,"template":"","class_list":["post-6135","knowledge","type-knowledge","status-publish","hentry","knowledge-category-delphi","knowledge-category-software-ontwikkeling"],"acf":{"author":413,"type_hero":"compact","hero_image":6129,"hero_image_position":"","hero_title":"EventBus pattern","hero_content":"","hero_link":"","hero_show_h1":false},"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v26.8 (Yoast SEO v27.5) - https:\/\/yoast.com\/product\/yoast-seo-premium-wordpress\/ -->\n<title>EventBus pattern - GDK Software<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/gdksoftware.com\/nl\/kennisbank\/eventbus-pattern\" \/>\n<meta property=\"og:locale\" content=\"nl_NL\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"EventBus pattern\" \/>\n<meta property=\"og:description\" content=\"Introductie Tijdens de ontwikkeling van Codolex merkten we dat het verbinden van verschillende formulieren en componenten via callback events zorgde voor sterk gekoppelde code. Een voorbeeld: wanneer een gebruiker een project opslaat, moeten meerdere onderdelen van de applicatie reageren. De lijst met recente items moet worden bijgewerkt, de backup manager moet in actie komen en [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/gdksoftware.com\/nl\/kennisbank\/eventbus-pattern\" \/>\n<meta property=\"og:site_name\" content=\"GDK Software\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Geschatte leestijd\" \/>\n\t<meta name=\"twitter:data1\" content=\"4 minuten\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/gdksoftware.com\\\/nl\\\/kennisbank\\\/eventbus-pattern\",\"url\":\"https:\\\/\\\/gdksoftware.com\\\/nl\\\/kennisbank\\\/eventbus-pattern\",\"name\":\"EventBus pattern - GDK Software\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/gdksoftware.com\\\/nl#website\"},\"datePublished\":\"2025-11-10T12:45:21+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/gdksoftware.com\\\/nl\\\/kennisbank\\\/eventbus-pattern#breadcrumb\"},\"inLanguage\":\"nl-NL\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/gdksoftware.com\\\/nl\\\/kennisbank\\\/eventbus-pattern\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/gdksoftware.com\\\/nl\\\/kennisbank\\\/eventbus-pattern#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/gdksoftware.com\\\/nl\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Knowledgebase\",\"item\":\"https:\\\/\\\/gdksoftware.com\\\/nl\\\/kennisbank\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Delphi\",\"item\":\"https:\\\/\\\/gdksoftware.com\\\/nl\\\/kennisbank-categorie\\\/delphi\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"EventBus pattern\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/gdksoftware.com\\\/nl#website\",\"url\":\"https:\\\/\\\/gdksoftware.com\\\/nl\",\"name\":\"GDK Software\",\"description\":\"Zet de stip op je horizon\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/gdksoftware.com\\\/nl?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"nl-NL\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"EventBus pattern - GDK Software","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/gdksoftware.com\/nl\/kennisbank\/eventbus-pattern","og_locale":"nl_NL","og_type":"article","og_title":"EventBus pattern","og_description":"Introductie Tijdens de ontwikkeling van Codolex merkten we dat het verbinden van verschillende formulieren en componenten via callback events zorgde voor sterk gekoppelde code. Een voorbeeld: wanneer een gebruiker een project opslaat, moeten meerdere onderdelen van de applicatie reageren. De lijst met recente items moet worden bijgewerkt, de backup manager moet in actie komen en [&hellip;]","og_url":"https:\/\/gdksoftware.com\/nl\/kennisbank\/eventbus-pattern","og_site_name":"GDK Software","twitter_card":"summary_large_image","twitter_misc":{"Geschatte leestijd":"4 minuten"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/gdksoftware.com\/nl\/kennisbank\/eventbus-pattern","url":"https:\/\/gdksoftware.com\/nl\/kennisbank\/eventbus-pattern","name":"EventBus pattern - GDK Software","isPartOf":{"@id":"https:\/\/gdksoftware.com\/nl#website"},"datePublished":"2025-11-10T12:45:21+00:00","breadcrumb":{"@id":"https:\/\/gdksoftware.com\/nl\/kennisbank\/eventbus-pattern#breadcrumb"},"inLanguage":"nl-NL","potentialAction":[{"@type":"ReadAction","target":["https:\/\/gdksoftware.com\/nl\/kennisbank\/eventbus-pattern"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/gdksoftware.com\/nl\/kennisbank\/eventbus-pattern#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/gdksoftware.com\/nl"},{"@type":"ListItem","position":2,"name":"Knowledgebase","item":"https:\/\/gdksoftware.com\/nl\/kennisbank"},{"@type":"ListItem","position":3,"name":"Delphi","item":"https:\/\/gdksoftware.com\/nl\/kennisbank-categorie\/delphi"},{"@type":"ListItem","position":4,"name":"EventBus pattern"}]},{"@type":"WebSite","@id":"https:\/\/gdksoftware.com\/nl#website","url":"https:\/\/gdksoftware.com\/nl","name":"GDK Software","description":"Zet de stip op je horizon","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/gdksoftware.com\/nl?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"nl-NL"}]}},"_links":{"self":[{"href":"https:\/\/gdksoftware.com\/nl\/wp-json\/wp\/v2\/knowledge\/6135","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/gdksoftware.com\/nl\/wp-json\/wp\/v2\/knowledge"}],"about":[{"href":"https:\/\/gdksoftware.com\/nl\/wp-json\/wp\/v2\/types\/knowledge"}],"acf:post":[{"embeddable":true,"href":"https:\/\/gdksoftware.com\/nl\/wp-json\/wp\/v2\/team\/413"}],"wp:attachment":[{"href":"https:\/\/gdksoftware.com\/nl\/wp-json\/wp\/v2\/media?parent=6135"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}