Actions

Behaviors: Difference between revisions

No edit summary
mNo edit summary
 
Line 1: Line 1:
Services must usually contain a variable number of features. Coding all these features in the ITBCAFCall subclasses might become hard to maintain has the number of features increase. Behaviors provide a way to implement these features in separate classes which are attached to a call at runtime. Basically a behavior traps all events for a call’s legs so it can act on the events and optionally forward them to the rest of the behavior chain. This chain is constructed at the initialization of the call as seen in the next section so that every call can have a different chain (therefore different features).
{{DISPLAYTITLE:Behaviors}}
Services usually contain a variable number of features. Coding all these features in the ITBCAFCall subclasses may become hard to maintain as the number of features increase. Behaviors provide a way to implement these features in separate classes, which are attached to a call at runtime. Basically, a behavior traps all events for a call’s legs so it can act on the events and optionally forward them to the rest of the behavior chain. This chain is constructed at the initialization of the call as seen in the next section so that every call can have a different chain (therefore different features).


Here are examples of features that make good behaviors:
Here are examples of features that make good behaviors:
Line 10: Line 11:
*Your 'bright ideas'...
*Your 'bright ideas'...


The decorator pattern is used by behaviors to provide this level of flexibility; behaviors decorate the default ITBCAFCall subclasses doings. A specific behavior can be used on any ITBCAFCall subclasses, as long as they are compatible in their doings e.g. Using a generic "Follow Me" behavior might not work as intended on a prepaid call).
The decorator pattern is used by behaviors to provide this level of flexibility; behaviors decorate the default ITBCAFCall subclasses. A specific behavior can be used on any ITBCAFCall subclasses, as long as they are compatible with the feature. For example, using a generic "Follow Me" behavior might not work as intended on a prepaid call.


Additionally, protocol-specific behaviors can be created to remove any protocol-aware code in the base classes. These behaviors can then be dynamically added to calls depending on their protocol.
Additionally, protocol-specific behaviors can be created to remove any protocol-aware code in the base classes. These behaviors can then be dynamically added to calls depending on their protocol.


Behaviors could be implemented through simple inheritance but this approach is somewhat less flexible. Indeed, a class for each combination of features would be required; so the classes needed for the example below would be:
Behaviors can be implemented through simple inheritance but this approach is somewhat less flexible. Indeed, a class for each combination of features would be required; so the classes needed for the example below would be:
 
*CMyCall
*CMyCall
*CMyCallRingbackTone
*CMyCallRingbackTone
*CMyVoiceMailFallback
*CMyVoiceMailFallback
*CMyCallRingbackToneVoiceMailFallback
*CMyCallRingbackToneVoiceMailFallback
*CMyVoiceMailFallbackCallRingbackTone (makes no sense in this case but it could make sense for some behaviors) Since the number of classes would be an exponetial of the number of features, we deemed this not acceptable and used decoration instead.
*CMyVoiceMailFallbackCallRingbackTone (This does not make sense in this case but it could make sense for some behaviors.) Since the number of classes would be an exponential of the number of features, we deemed this not acceptable and used decoration instead.




== Usage ==
== Usage ==
Behaviors must be subclasses of CTBCAFCallBehavior which delegates all events to it’s parent by default. The new behavior must implement the event handlers only for the events it needs and must decide whether or not to delegate the event (capturing the event or letting others use it). The CTBCAFCallBehaviorRbt, CTBCAFCallBehaviorVoiceMail, CTBCAFCallBehaviorFollowMe, CTBCAFCallBehaviorFaxRelay classes are good examples of various kinds of simple behaviors.
Behaviors must be subclasses of CTBCAFCallBehavior, which delegates all events to it’s parent by default. The new behavior must implement the event handlers only for the events it needs and must decide whether or not to delegate the event (capturing the event or letting others use it). The CTBCAFCallBehaviorRbt, CTBCAFCallBehaviorVoiceMail, CTBCAFCallBehaviorFollowMe, CTBCAFCallBehaviorFaxRelay classes are good examples of various kinds of simple behaviors.


The following code demonstrates how to decorate a call with ringback tone and voicemail fallback behaviors:
The following code demonstrates how to decorate a call with ringback tone and voicemail fallback behaviors:
Line 34: Line 36:


== Caveats ==
== Caveats ==
Behaviors should be careful with the state of the call since the may be used on any type of call. For example a check should be made to be sure a leg exists before using it. This should prevent crashes in case of invalid usage of the behavior.
Behaviors should be careful with the state of the call since they may be used on any type of call. For example, a check should be made to be sure a call leg exists before using it. This would prevent crashes in case of an invalid use of a behavior.





Latest revision as of 09:56, 20 July 2022

Services usually contain a variable number of features. Coding all these features in the ITBCAFCall subclasses may become hard to maintain as the number of features increase. Behaviors provide a way to implement these features in separate classes, which are attached to a call at runtime. Basically, a behavior traps all events for a call’s legs so it can act on the events and optionally forward them to the rest of the behavior chain. This chain is constructed at the initialization of the call as seen in the next section so that every call can have a different chain (therefore different features).

Here are examples of features that make good behaviors:

The decorator pattern is used by behaviors to provide this level of flexibility; behaviors decorate the default ITBCAFCall subclasses. A specific behavior can be used on any ITBCAFCall subclasses, as long as they are compatible with the feature. For example, using a generic "Follow Me" behavior might not work as intended on a prepaid call.

Additionally, protocol-specific behaviors can be created to remove any protocol-aware code in the base classes. These behaviors can then be dynamically added to calls depending on their protocol.

Behaviors can be implemented through simple inheritance but this approach is somewhat less flexible. Indeed, a class for each combination of features would be required; so the classes needed for the example below would be:

  • CMyCall
  • CMyCallRingbackTone
  • CMyVoiceMailFallback
  • CMyCallRingbackToneVoiceMailFallback
  • CMyVoiceMailFallbackCallRingbackTone (This does not make sense in this case but it could make sense for some behaviors.) Since the number of classes would be an exponential of the number of features, we deemed this not acceptable and used decoration instead.


Usage

Behaviors must be subclasses of CTBCAFCallBehavior, which delegates all events to it’s parent by default. The new behavior must implement the event handlers only for the events it needs and must decide whether or not to delegate the event (capturing the event or letting others use it). The CTBCAFCallBehaviorRbt, CTBCAFCallBehaviorVoiceMail, CTBCAFCallBehaviorFollowMe, CTBCAFCallBehaviorFaxRelay classes are good examples of various kinds of simple behaviors.

The following code demonstrates how to decorate a call with ringback tone and voicemail fallback behaviors:

 {
   pCall = tbnew CMyCall(...);
   pRbtCall = tbnew CMyCallBehaviorRbt( pCall );
   pVoiceMailRbtCall = tbnew CMyCallBehaviorVoiceMailFallback( pRbtCall );
 }

Caveats

Behaviors should be careful with the state of the call since they may be used on any type of call. For example, a check should be made to be sure a call leg exists before using it. This would prevent crashes in case of an invalid use of a behavior.



Return to the Toolpack User Guide