E81 CSE 532S: Advanced Multi-Paradigm Software Development
Wrapper Façade Pattern
Chris Gill, Ryan Cooper, Gene Tien
Department of Computer Science and Engineering
Washington University, St. Louis
cdgill@cse.wustl.edu
Continued Reading Assignment
• C++NPv1 Chapter 3
– Optional: POSA 2 pp. 47-74
Wrapper Facade
• Encapsulates
ACE_IPC_SAP functions and data
• Adapts existing
ACE_SOCK ACE_SPIPE
procedural APIs
• Offers better
interfaces
–Concise, maintainable
ACE_SOCK_Stream ACE_SOCK_Dgram
–Robust, portable
–Cohesive,
object-oriented
Wrapper Façade Intent: Why?
• To protect the application programmer from worrying
about platform-specific API’s
• To simplify use of the API’s (less tedious/error-prone)
• To do this while paying only a small performance cost
• Other related patterns have different intents
– Façade
– Decorator
– Bridge
– Adapter
Wrapper Façade Context: When?
• When extensibility can be achieved at a
suitably low cost (vs. direct use of API)
• When extensibility is more important
than performance improvements
– Other design patterns can give even more
significant flexibility improvements, but the
performance costs often increase as well
– E.g., the Extension Interface pattern
Wrapper Façade Context: Where?
ACE_INLINE ACE_thread_t
ACE_OS::thr_self (void)
{
• Most commonly
// ACE_OS_TRACE ("ACE_OS::thr_self");
#if defined (ACE_HAS_THREADS)
used with
# if defined (ACE_HAS_PTHREADS)
// Note, don't use "::" here since the
networking,
// following call is often a macro.
ACE_OSCALL_RETURN (pthread_self (), int, -1);
threading, and
# elif defined (ACE_HAS_STHREADS)
ACE_OSCALL_RETURN (::thr_self (), int, -1);
other low-level
# elif defined (ACE_HAS_WTHREADS)
return ::GetCurrentThreadId ();
APIs
# elif defined (ACE_PSOS)
// there does not appear to be a way to get
// a task's name other than at creation
return 0;
# elif defined (VXWORKS)
return ::taskName (::taskIdSelf ());
# endif /* ACE_HAS_STHREADS */
#else
return 1; // Might as well make it the first thread ;-)
#endif /* ACE_HAS_THREADS */
}
Wrapper Façade Implementation:
How? (from POSA2)
1. Identify cohesive abstractions and
relationships among low level APIs
E.g., “Every IPC SAP has a handle and every
socket is an IPC SAP, but not every IPC SAP is
a socket.”
Wrapper Façade Implementation, cont.
2. Cluster cohesive groups of functions into
wrapper façade classes and methods
2.1 - Create cohesive classes
2.2 - Coalesce multiple individual functions
into a single method (e.g., bind/listen)
2.3 - Automate creation and destruction
2.4 - Select level of indirection
2.5 - Determine where to encapsulate
platform-specifics
Wrapper Façade Implementation, cont.
3. Consider allowing selective access to some
implementation details, e.g.,
ACE_IPC_SAP::get_handle() is a
“controlled violation of encapsulation.”
4. Develop error handling (language support for
features such as exceptions may matter)
5. Define related helper classes
Example – Thread Management
• Thread_Mutex, Thread_Condition, Thread_Manager
• Automatic creation, initialization and destruction
• Extensible – templates parameterized by mutex types
Common Problems and Issues
• Exceptions
– Language support
– Different ways of handling
– Resource management (e.g., memory leaks in
C++)
– Overhead
• Loss of functionality
• Poor cross-language support
• Performance costs relative to application needs
For Discussion
• What problem is addressed by the
Wrapper Façade pattern?
• Compare and contrast socket
programming code with and without
ACE.
• How can wrapper façade increase type
safety? At the same time, how can it
increase type compatibility?