Chapter 13 -- Event Service

[Previous] [Next]

Chapter 13

Objects interact with one another through the interfaces they support. For example, if object A wants to request a service from object B, it must invoke an interface method implemented in object B. Standard invocations require object B to be available at the time of the request; if it isn't, an error is raised. Method invocations are usually synchronous: that is, object A will have to wait for object B to finish processing the request before continuing.

Interfaces permit polymorphic behavior, allowing different class objects that support the same interface to be referenced by a client application at run time. The interfaces themselves are static, however, so the roles and relationships among objects are statically defined in terms of the interfaces they support. For example, in the following code, Client App Module 1 defines an InvokeBark method that expects an object that supports the ICanine interface. Client App Module 2 calls the InvokeBark method and passes it a GermanShepherd object. This approach is dynamic in that the InvokeBark method can accept any class of object that supports the ICanine interface, not just a GermanShepherd object. Through this one invocation, different classes of objects would produce different behavior for the same ICanine.Bark method call. This approach is static in that the InvokeBark method expects the interface ICanine. If the GermanShepherd object doesn't support the ICanine interface, the Microsoft Visual Basic compiler will raise a "Type Mismatch" error. If no object is passed, the Visual Basic compiler will raise an error pertaining to an attempt to use a null object reference.

 ' Client App Module 1 Public Sub InvokeBark(Dog As ICanine) Dog.Bark End Sub ' Client App Module 2 Dim myDog As GermanShepherd Set myDog = New GermanShepherd Call InvokeBark(myDog) 

Static roles and relationships compel you to assemble your software system in a specific way. This requirement inherently forces dependencies between components, which can result in a monolithic object-based system. One way to minimize dependency is to make your interfaces as generic as possible. An example on the extreme end would be the equivalent of the Microsoft Windows SendMessage API. If you define an interface method that takes a Long as the first parameter to indicate the action to perform, followed by a varying set of parameters (ParamArray) for inputs and outputs as shown in the following code, this single interface could literally be used by all classes of objects to fulfill any role and by a designer to establish any type of relationship.

 ' All-purpose interface class module Public Sub Invoke(Action As Long, ParamArray Params()) End Sub 

However, this freedom eliminates the benefit of self-describing interfaces that are intuitive for the programmer developing the system. Another drawback is that the compiler can do only minimal compile-time strong type checking. As a result, the onus of enforcing a contract between the object requesting a service (client) and the object providing the service (server) moves out of the compiler and into the objects' implementations. The client and the server must agree on parameter inputs and outputs for successful collaboration. Taking this approach is obviously too drastic. The Event Service design pattern described in this chapter is a better alternative because it allows you to design a system in which a client requesting a service is decoupled from the server providing it. You can therefore establish dynamic roles and relationships without sacrificing the benefits of static interfaces.



Microsoft Visual Basic Design Patterns
Microsoft Visual Basic Design Patterns (Microsoft Professional Series)
ISBN: B00006L567
EAN: N/A
Year: 2000
Pages: 148

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net