{"id":886,"date":"2010-07-09T18:20:09","date_gmt":"2010-07-09T17:20:09","guid":{"rendered":"http:\/\/www.minddriven.de\/?p=886"},"modified":"2010-07-11T09:53:30","modified_gmt":"2010-07-11T08:53:30","slug":"event-based-components","status":"publish","type":"post","link":"https:\/\/www.minddriven.de\/index.php\/technology\/development\/event-based-components","title":{"rendered":"Some thoughts on Event-Based Components"},"content":{"rendered":"<p>The German software engineer <a href=\"http:\/\/ralfw.de\/\">Ralf Westphal<\/a> currently spreads some knowledge about an alternative model for programming components and especially communication between them. Due to their nature they are called <strong>Event-Based Components<\/strong>. After some discussion with colleagues at <a href=\"http:\/\/www.sdx-ag.de\">SDX<\/a> I want to share some of my thoughts on that with you (of course for further discussion as well).<br \/>\nThe aim of Event-Based Components (EBC) is to create software components that are <em>really<\/em> composable without specific topological dependencies. You can compare EBCs with elements in electronic circuits. But first things first&#8230;<\/p>\n<h3>Interface-Based Components style<\/h3>\n<p>Normally we&#8217;re developing components in .NET as IBCs: <strong>Interface-Based Components<\/strong>. That means client classes have topological and functional dependencies to interfaces (or directly to other classes), which provide some sort of functionality. Well developed, such a dependency could be resolved with a Dependency Injection container like StructureMap:<\/p>\n<pre class=\"brush:csharp\">class Program\r\n{\r\n    static void Main(string[] args)\r\n    {\r\n        \/\/ Bind (here: StructureMap)\r\n        ObjectFactory.Initialize(x =&gt;\r\n        {\r\n            x.For&lt;IBusinessClient&gt;().Use&lt;BusinessClient&gt;();\r\n            x.For&lt;IDataAccessComponent&gt;().Use&lt;DataAccessComponent&gt;();\r\n        });\r\n\r\n        \/\/ Resolve and Run\r\n        IBusinessClient client = ObjectFactory.GetInstance&lt;IBusinessClient&gt;();\r\n        client.BusinessOperation(0);\r\n    }\r\n}\r\n\r\ninterface IBusinessClient\r\n{\r\n    void BusinessOperation(int personId);\r\n}\r\n\r\nclass BusinessClient : IBusinessClient\r\n{\r\n    private readonly IDataAccessComponent _dataAccessComponent;\r\n\r\n    public BusinessClient(IDataAccessComponent dataAccessComponent)\r\n    {\r\n        _dataAccessComponent = dataAccessComponent;\r\n    }\r\n\r\n    public void BusinessOperation(int personId)\r\n    {\r\n        Person p = _dataAccessComponent.GetPerson(personId);\r\n        \/\/ do something ...\r\n    }\r\n}\r\n\r\ninterface IDataAccessComponent\r\n{\r\n    Person GetPerson(int id);\r\n}\r\n\r\nclass DataAccessComponent : IDataAccessComponent\r\n{\r\n    public Person GetPerson(int id)\r\n    {\r\n        return  \/\/ ...some person...\r\n    }\r\n}<\/pre>\n<p>That&#8217;s pretty standard so far, isn&#8217;t it? In Ralf&#8217;s opinion this programming style lacks real <em>composability<\/em> of the components. Due to the <strong>topological dependency<\/strong> the clients is bound to a specific interface and no <em>arbitrary<\/em> component can perform the functionality. Instead a component has to implement the specific interface. You&#8217;re not able to use components which <em>could<\/em> provide the functionality, but don&#8217;t implement the interface&#8230;<\/p>\n<h3>Event-Based Components style<\/h3>\n<p>Ralf suggests <strong>Event-Based Components<\/strong> to the rescue. Components in this programming style can be compared to components in electronic circuits. Methods act as <em>input pins<\/em> of a component and can be called by other components. Events\/delegates act as <em>output pins<\/em> and establish a connection to other components that should be used by the component or to provide calculation results. The output pins can be bound to any arbitrary method that meet the signature. Thus the dependency is still functional, but <em>not topological<\/em> any more.<br \/>\nThe example above in EBC style could look as follows:<\/p>\n<pre class=\"brush:csharp\">class Program\r\n{\r\n    static void Main(string[] args)\r\n    {\r\n        \/\/ Build\r\n        var client = new BusinessClient();\r\n        var dataAccess = new DataAccessComponent();\r\n\r\n        \/\/ Bind\r\n        client.GetPerson = dataAccess.GetPerson;\r\n\r\n        \/\/ Run\r\n        client.BusinessOperation(0);\r\n    }\r\n}\r\n\r\nclass BusinessClient\r\n{\r\n    public Func&lt;int, Person&gt; GetPerson { get; set; }\r\n\r\n    public void BusinessOperation(int personId)\r\n    {\r\n        Person p = GetPerson(personId);\r\n        \/\/ do something ...\r\n    }\r\n}\r\n\r\nclass DataAccessComponent\r\n{\r\n    public Person GetPerson(int id)\r\n    {\r\n        return  \/\/ ... some person ...\r\n    }\r\n}<\/pre>\n<p>This example shows the components <code>BusinessClient<\/code> and <code>DataAccessComponent<\/code> interacting as EBCs in a very simple form by using the <code>Func&lt;T&gt;<\/code> delegate type and thus enabling <em>symmetric<\/em> communication. Ralf encourages the use of standard input\/output pins as <code>Action&lt;object&gt;<\/code>, which leads to <em>asymmetric<\/em> communication, because the <code>DataAccessComponent<\/code> would need to declare an output pin for providing the <code>Person<\/code> as result of <code>GetPerson()<\/code>. For the sake of simplicity I haven&#8217;t followed this principle here.<\/p>\n<p>So the example uses a <code>Func&lt;T&gt;<\/code> delegate and no event. But you can still think of it as Event-Based Component, just because events are nothing more than multicast delegates. I could have used events instead of the simple delegate as well, but I&#8217;m quite fine, because I don&#8217;t need the functionality of multiple subscribers here.<\/p>\n<p>As you can see from the example, just like IBCs the EBCs have some kind of initial <em>Bootstrapper<\/em> phase. This is the time when the components are composed. The output pins of a component&#8217;s client (<code>BusinessClient<\/code> in this example) are connected with the input pins of the component itself (here: <code>DataAccessComponent<\/code>).<\/p>\n<h3>Benefits<\/h3>\n<p>When I first saw EBCs I thought: &#8222;Dude, this is damn cool, isn&#8217;t it?&#8220;. Indeed this kind of programming style first feels strange and alternate and thus for me it&#8217;s really interesting. But are there some <em>real<\/em> benefits as well?<\/p>\n<p>I think one big benefit of EBCs is their <strong>composability<\/strong>. A client hasn&#8217;t to know the interface of a component from which he wants to use some functionality. A component on the other side is not forced to implement an interface to provide some functionality, but it&#8217;s still retaining loose coupling. Even without interfaces the components are still independent from each other and have great <strong>testability<\/strong>.<\/p>\n<p>Other benefits I see are the <strong>exchangeability<\/strong> and the <strong>topological independence<\/strong>. Components are not bound to a specific topological context in form of interfaces and thus are independent from topological changes on the interfaces. You can exchange the components easily by replacing the binding section with any other setup phase and can binding other methods to them. Especially your components are not forced to use (or implement) some kind of interface from which they will perhaps use just one single functionality&#8230;<\/p>\n<p>Last but not least I see a very easy way to <strong>intercept calls<\/strong> and adding functionality without changing the components themselves. If you use events as output pins you can add some more event handlers in the binding phase. Thus you can easily integrate Logging, Tracing etc. into your applications. Of course you can achieve this with IBCs as well, I just say that EBCs are suiting very well for those requirements.<\/p>\n<h3>Drawbacks<\/h3>\n<p>Besides those benefits in my opinion there are some significant drawbacks as well.<\/p>\n<p>First of all is the additional <strong>complexity<\/strong> which comes with EBCs. <strong>Composing<\/strong> EBCs can become complex, at least in projects of significant size. Due to binding methods and events together on the fine instead of interfaces on the coarse, there have to be much more binding statements. In fact you can think of an event&#8217;s signature as a <em>one-method interface<\/em> that has to be fulfilled from components. Furthermore (again especially in projects of a reasonable size) you will loose <strong>intelligibility<\/strong> and\u00a0 <strong>overview<\/strong> over your system and the component interaction. Any arbitrary component can provide a functionality and there is no way to navigate between layers and components as clients and suppliers of functionality. Explicit interfaces are much more comprehensive than such &#8222;implicit&#8220; specifications.\u00a0 Perhaps in the future there will be tools that simplify composition between EBCs and navigation through EBCs, but until there&#8217;s such a tool I consider this as serious drawback.<\/p>\n<p>Another drawback of EBCs is the loss of <strong>interfaces as formal contract<\/strong> of coherent functionality. Of course you can define interfaces and let your components implement them, but while clients are not compelled to use them they loose much of their value. Interfaces force components to implement a certain set of functionality completely and make this set explicit. Clients have to refer this contract explicitly. Explicit contracts lead to <a href=\"http:\/\/domaindrivendesign.org\/node\/113\">intention revealing<\/a> and this is a good thing!<\/p>\n<h3>Conclusion<\/h3>\n<p>So in my opinion EBCs have benefits as well as shortcomings. I think they are worth investigating and knowing them, but at the moment I don&#8217;t see that they will establish well and become a replacement for IBCs. First there is the higher complexity, which could perhaps be solved by tools and some sort of &#8222;DI container&#8220; for EBCs in the future. But second, being explicit and define formal contracts through explicit interfaces is no bad thing. Of course it&#8217;s not cheap as well, but I don&#8217;t see that this justifies the application of EBCs on the small scale. On the big scale there are other solutions like BizTalk, NServiceBus etc. to achieve the goal of pluggable components which have features like scalability as well. So perhaps there are delimited scenarios for using EBCs (like component topologies that change often), but I would not suggest to use them in general.<\/p>\n<p><a href=\"http:\/\/www.dotnetkicks.com\/kick\/?url=http%3a%2f%2fwww.minddriven.de%2f%3fp%3d886\"><img decoding=\"async\" src=\"http:\/\/www.dotnetkicks.com\/Services\/Images\/KickItImageGenerator.ashx?url=http%3a%2f%2fwww.minddriven.de%2f%3fp%3d886\" border=\"0\" alt=\"kick it on DotNetKicks.com\" \/><\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>The German software engineer Ralf Westphal currently spreads some knowledge about an alternative model for programming components and especially communication between them. Due to their nature they are called Event-Based Components. After some discussion with colleagues at SDX I want to share some of my thoughts on that with you (of course for further discussion &hellip; <a href=\"https:\/\/www.minddriven.de\/index.php\/technology\/development\/event-based-components\" class=\"more-link\"><span class=\"screen-reader-text\">Some thoughts on Event-Based Components<\/span> weiterlesen<\/a><\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[10,203],"tags":[260,262,181,261],"class_list":["post-886","post","type-post","status-publish","format-standard","hentry","category-development","category-software-design","tag-di","tag-event-based-programming","tag-events","tag-interfaces"],"_links":{"self":[{"href":"https:\/\/www.minddriven.de\/index.php\/wp-json\/wp\/v2\/posts\/886","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.minddriven.de\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.minddriven.de\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.minddriven.de\/index.php\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/www.minddriven.de\/index.php\/wp-json\/wp\/v2\/comments?post=886"}],"version-history":[{"count":29,"href":"https:\/\/www.minddriven.de\/index.php\/wp-json\/wp\/v2\/posts\/886\/revisions"}],"predecessor-version":[{"id":962,"href":"https:\/\/www.minddriven.de\/index.php\/wp-json\/wp\/v2\/posts\/886\/revisions\/962"}],"wp:attachment":[{"href":"https:\/\/www.minddriven.de\/index.php\/wp-json\/wp\/v2\/media?parent=886"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.minddriven.de\/index.php\/wp-json\/wp\/v2\/categories?post=886"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.minddriven.de\/index.php\/wp-json\/wp\/v2\/tags?post=886"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}