oo design and patterns
DESCRIPTION
A brief talk explaining the benefits of OO design and some important OO design patternsTRANSCRIPT
OO Design and Patterns
Anil Bapat
What is OO Design?
• Software design that is organized around objects, rather than functions
• Design that uses the techniques of – – Abstraction– Encapsulation– Inheritance– Polymorphism
C++ - An OO Programming Language
• Since C++ has explicit support for all the OO mechanisms, it’s called an OO language– Abstraction and Encapsulation (Classes)– Inheritance– Polymorphism (Dynamic binding via virtual
functions)
C++ - A Multi-paradigm language
• The power of C++ is that it supports multiple programming paradigms– OO programming– Structured programming (C style) – Generic Programming (Templates)
• So, a developer could mix and match these techniques as appropriate in the same product
Abstraction
• Focus on relatively stable operations/services rendered by a concept rather than ‘How’ these operations/services are rendered
• Allows one to model software based on high level details, without getting bogged down too early with the nitty-gritty details
• C++ classes provide support for abstraction
Encapsulation
• Encapsulation means data hiding or hiding the implementation details
• A class can just expose the services/operations rendered by it and hide all the implementation details via access control mechanisms (public/private/protected)
• Encapsulation enforces abstraction
Example: Fast path Lookup abstraction
• Define a Lookup abstraction that returns the required data given the key (GRE key/ IP Address)
• Start with a simple implementation of using a lock to access the shared data (AVL tree)
• Change the data structure from an AVL tree to a hash table for faster random access of nodes
• Enhance the lookup implementation to use caching and lock free mechanisms later in the cycle, without impacting the users of this abstraction
Classes
• C++ classes enable abstraction and encapsulation
• Improves cohesion by grouping together data and operations on the data together
• Reduces coupling by hiding implementation details and having software depend only upon operations/services rendered by classes and not on specific implementations
Classes - contd
• Reduces bugs– CTOR/DTOR ensures initialization and cleanup of
data, rather than depend upon the users to do this. Imagine having to call cleanup of a stack variable in each return path
– Copy semantics embedded in the class itself leading to reduced memory leaks and corruptions
– Easier to fix bugs – A missed out deep copy of a struct member, has to be changed in one place, rather than having to search where all this has to be done
– Easy to enforce policies to prevent misuse {Eg: If a string class wants to prevent comparison with a character, it could hide the operator==(char& c)}
Classes (Contd)
• Facilitates code reuse– A date class contains code related to
comparing 2 dates (<,>,== operators), checking for leap year, printing dates (<< operator) etc. If date were a struct we could end up with users of this struct duplicating these code lines at several places
– Classes could further be reused via inheritance or composition by other classes
Inheritance and Polymorphism
• Models the ‘Is-a-kind-of’ relationship between classes
• Enables specialization of existing concepts by reusing existing concepts and ‘Adding’ stuff
• Polymorphism is the enabler of the key concept of OO – ‘OLD code can call NEW code’
• High level policies and Implementations both depend upon stable abstractions, thus yielding flexible software (Dependency Inversion)
• Makes software extensible/modifiable without having to change existing code
Socket Framework
• Abstractions: SocketClient, SocketServer and SocketConnection
• Implementation: select/poll loop• SocketClient and SocketServer are both
factories that create a SocketConnection instance when the socket connection is established
• Inheritance propagates connect/accept functions to all subclasses
Benefits of OO design
• Is more intuitive. The objects we deal with in the real world have both attributes and behavior, just like classes and we keep abstracting things all the time
• Enables rapid prototyping and iterative development of software
• Supports code reuse via classes, inheritance, composition and polymorphism
• Leads to software that can be easily modified or changed (Easy maintenance)
• Allows for late cycle performance enhancements
Key step for OO project success
• Identifying the right abstractions.
• Know the domain very well, so that concepts that are stable could be identified as ‘Abstractions’ and things that could change be encapsulated away behind abstract interfaces (Eg: specific Protocols/Hardware details etc)
Design Patterns
• Commonly used design techniques described in abstract terms so they can be applied to any field
• “Reuse of Knowledge” as opposed to reuse of code
• The “GoF book” introduced the concept and has ever since been the bible on this topic
Some Useful Design Patterns
• Singleton• State• Factory• Publish/Subscribe or Observer• Wrapper facade• Reactor• Proxy• Scoped Locking
Singleton
• Ensure that a class has a single instance
• Provide a global point of access to the single instance of the class
• Double checked locking for Singletons
• Use templates to hold single instance, to reuse code
State
• Avoids long nested switch-cases and makes large state machine code more readable
• Easy to introduce new states in state machines
• Each state object needs to implement only subset of event handlers. Unhandled events fallback to base class handlers
Factory
• If some high level logic depends only upon abstractions, it should not depend upon concretions even for object creation
• Have an abstract interface for object creation and have all logic use this interface for object creation, rather than have if-else logic at all places where an object instance is to be created
• Eg: SocketConnector and SocketAcceptor in the Socket framework?
Publish/Subscribe
• Loose (Abstract) coupling between subjects and observers
• Adding new observers doesn’t need any change in Subject code
• Eg: T1Link (Subject) and Callp/Alarms (Observers). Remove Callp and add ISUP protocol module as observer, add 1 more observer (ISDN protocol module) – No change required in the ‘Subject’ (T1 Link) that notifies all subscribers about events
Wrapper facade
• Provide an higher level interface class to a set of functions/operations that always happen together
• Eg: SocketServer façade – Do the calls – socket(), bind(), listen, and accept() together.
• Hides users from the devilish things like htons on the port, calling these functions in the right order, without missing any call etc
Reactor
• Encapsulates the “select loop”• Could internally incorporate select/poll
without having any impact on users (FDs > 1024 not supported by select)
• Achieves OS abstraction (Can change select to WaitForMultipleObjects of NT)
• Loose coupling between the event de-mux logic (Framework) and the applications that handle the events
Proxy
• Hide the fact that the service is being implemented in a different address space (Eg: RMI, CORBA etc implement this pattern)
• Used to implement stuff like lazy instantiation, Copy on write etc for optimizing creation/copying of costly resources
Scoped Locking
• Automatically release locks whenever the reference to the lock is lost (function return or exception)
• Better way to guard critical sections as it leads to more robust and maintainable code
Push to Talk server design
Example Requirements:
• Support the Push to talk application• Use the ISUP protocol• Use a particular 3rd party Media Card that
supports H.110 interconnect of DS0s, capture of DTMFs etc
• Generate billing records in a file in a specific format
PTT server using Functional Programming
• Consists of the PTT call control logic all using the APIs provided by the ISUP protocol stack, the 3rd party media card and the file system APIs (For billing).
• Smaller footprint code ideal for very small embedded devices
• Difficult to extend or to maintain this code
How requirements change
• We would have to add support for the SIP protocol in addition to ISUP
• We would have to support an RTP media controller in addition to the TDM media controller
• Too much file access for the billing makes the system I/O bound and there’s a requirement to move the billing module to another card
OO design allows us to easily accommodate changes
• All of the PTT call control is coded in terms of “Abstract” interfaces
• We can add SIP and the new media controller, both as new code that conforms to the earlier abstractions, without changing any of the existing code
• We could “Proxy” out the billing module where the “Guts” reside on a different card