[ComponentDesignPatterns | CategoryPattern] Please see the following link for the most updated version of the ThirdPartyBinding pattern: http://jerry.cs.uiuc.edu/~plop/plop99/proceedings/Eskelin1/ComponentInteractionPatterns.pdf This is the PLoP'99 version of this pattern. ----- ''Old version in canonical form included below.'' '''Also Known As''' Software integrated circuit, third-party connect, dependency injection '''Problem''' How can you reduce a component's dependence on the environment in which it is executed? '''Context''' Components execute within some environment that contains other components and support services. '''Forces''' * If a component acts as a client of other components it needs to be "bound" to those components services before it can make use of them. * Maintenance of a system involves modifying bindings between components, so maintenance is easier if bindings are easy to modify. * If a component performs binding actions itself those bindings are hidden within its implementation and it becomes implicitly dependent on the components to which it is bound. Therefore: * The component becomes harder to reuse. * The system becomes harder to maintain. '''Solution''' Always have a third party create bindings between components. '''Resulting Context''' The dependencies between components are visible at a higher level, making it easier to maintain the system. It is easier to reuse components, because they don't have implicit dependencies on other components in their environment. Because interactions between components are made explicit, it is easier to model and reason about the behavior of the system in terms of the behavior of the components. It is impossible to remove all implicit dependencies. Components are always dependent on their ComponentFramework that defines the AbstractInteractions between them. Before the binding has been established by the third party, components must deal with a non-functioning binding. Rather than riddling your code with if (myBinding != NULL) { myBinding->doThis(); } you can simply subclass the interface with a NullObject. '''Known Uses''' JavaBeans are connected together by the application in which they are used. However, they have an implicit dependency on the Java AWT (if they are visual components), classes in the java.beans package and other Java APIs. Microsoft's DirectShow media API implements stream filters as COM objects that expose one or more "pins" through which media frames flow. Frames are passed into a filter through input pins and out of a filter through output pins. Filter graphs are created to perform stream processing and rendering by instantiating components and connecting the output pins of up-stream filters to the input pins of down-stream filters. Many ArchitectureDescriptionLanguage''''s describe system architectures in terms of only instantiated components and provide/require/use relationships between those components. '''Example''' A real-time market data component and distributed management component are bound together by a third party in a project developed in-house at a large global investment bank. That third party is currently MicrosoftExcel, but could be any other user of the components. '''Related Patterns''' If component bindings must be modified at run time, it might be easier to use a ComponentBus that allows components to communicate without being explicitly bound to each other. ThirdPartyBinding is then used to bind each component to the bus. ----- I think ThirdPartyBinding and Component Bus are two different alternatives that allow you to achieve the same thing: connect components in a way that is most friendly to your requirements. We do these things in the first place because sometimes it's important to not couple components, reducing complexity by organizing dependencies. With ThirdPartyBinding, you centralize component relationships at the third party connecting all the components together. It contains runtime dependencies on all other components (although this can be dynamic as well). However, with a ComponentBus, you have many components depend on the one component providing the bus through one or more interfaces. Each component must be implemented to conform to the interaction protocols defined by it. --PhilipEskelin ----- I disagree, ThirdPartyBinding and ComponentBus are not alternatives that solve the same problem (hmmm... I see that the problem statement for each is the same I'll have to comment there as well...). ThirdPartyBinding is a mechanism by which two components can interact without a priori knowledge of each others existence (of course the third party has to know about both). ComponentBus solves the problem of N-way component communication by reducing the N by N interconnects to N (each component connected once to the bus). ThirdPartyBinding to a ComponentBus is a powerful combination that allows a component during design time to be bound to a more sophisticated communication context. But from the components viewpoint the process is the same as for a 1-1 connection. ThirdPartyBinding and ComponentBus have a dependency on the definition of an abstract protocol as the basis for communication, but then again, what good OO solution doesn't? :-^) Seriously thought I think this might follow directly from RobertMartin's DependencyInversionPrinciple. --MikeKrajnak ''Components are dependent on their ComponentFramework that defines the AbstractInteractions by which they communicate (I have updated the pattern to emphasise this point). The DependencyInversionPrinciple identifies one need for AbstractInteractions: the need to reduce the "brittleness" of a system. However, a main advantage that ComponentBasedDevelopment gets from AbstractInteractions is that they enable one to compose independently implemented components and be sure that they will work together.'' ''Maybe follows directly is too strong, although I see a strong correlation between not brittle and independent'' ----- ThirdPartyBinding is not limited to one-to-one communication. For example, method invocation is many-to-one communication: many clients can call the same method of the same component. Event dissemination is one-to-many communication: many listeners can register for the same event. Using a combination of the two, one can set up many-to-many communication. However, it is a right hassle to create and, especially, to modify many-to-many communication if it is set up by ThirdPartyBinding. That is where a ComponentBus is useful: the routing of communication between components is encapsulated in the bus and so components do not need to be explicitly bound to each other and can be easily added to and removed from the bus. I don't actually think ThirdPartyBinding and ComponentBus are alternatives. In fact, components should be attached to a ComponentBus by ThirdPartyBinding, so I guess that ComponentBus ''uses'' ThirdPartyBinding. ''Thanks. This is what I was trying to get at with my rambling about 1-1 and N-N and combining ThirdPartyBinding and ComponentBus, your summary is a lot clearer.'' (I have modified the Related Patterns section to reflect this.) ''Thanks'' "hmmm... I see that the problem statement for each is the same I'll have to comment there as well...". The ''context'' of each pattern is different! --NatPryce In my writing I tend to have lightweight component buses, essentially small tuple spaces in the most object neutral versions. This allows the entire addition and subtraction of components to occur in an anonymous yet secure fashion. Connection of components is by third-party moderated negotiation and is direct i.e. its a one-time connection overhead. As a microarchitecture I kinda like it :). Does such a thing have a name? RichardHenderson ----