90 likes | 104 Views
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. pthread_create (thread, attr, start_routine, arg);
E N D
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
pthread_create (thread, attr, start_routine, arg); pthread)_exit (status); pthread_cancel (thread); … Wrapper Facade thread thread (); thread (function, args); ~thread(); join(); … Combines related functions/data (OO, generic) Used to adapt existing procedural APIs Offers better interfaces Concise, maintainable, portable, cohesive, type safe
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) { // ACE_OS_TRACE ("ACE_OS::thr_self"); #if defined (ACE_HAS_THREADS) # if defined (ACE_HAS_PTHREADS) // Note, don't use "::" here since the // following call is often a macro. ACE_OSCALL_RETURN (pthread_self (), int, -1); # elif defined (ACE_HAS_STHREADS) ACE_OSCALL_RETURN (::thr_self (), int, -1); # elif defined (ACE_HAS_WTHREADS) return ::GetCurrentThreadId (); # 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 */ } • Most commonly used with networking, threading, and other low-level APIs
Wrapper Façade Implementation: How? (from POSA2) • 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., thread::native_handle_type tnht = t1.native_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, associated types, etc.
Common Problems and Issues • Exceptions • Language support • Different ways of handling • Resource management (e.g., C++ memory leaks) • Overhead • Loss of functionality • Poor cross-language support • Performance costs relative to application needs