Shortcut to seniority
Home
Go to main page
Section level: Junior
A journey into the programming realm
Section level: Intermediate
The point of no return
Section level: Senior
Leaping into the unknown
                    Go to main page
A journey into the programming realm
The point of no return
Leaping into the unknown
Design patterns refer to patterns that are a general solution for common problems in software design.
The observer pattern (similar to Publish-Subscribe, but this one acts at the class level, not at component level) is a software design pattern, in which an object, called the subject:
                                            Example 1
                                            
                                                struct IListener {      
                                                virtual void onUpdate() = 0;    
                                                };    
                                                    
                                                struct IObserver {    
                                                virtual void attach(IListener* listener) = 0;    
                                                virtual void detach(IListener* listener) = 0;    
                                                virtual void notifyListeners() = 0;    
                                                };    
                                                    
                                                class CObserver: public IObserver {    
                                                public:    
                                                void attach(IListener* listener) {    
                                                    mListeners.push_back(listener);    
                                                }    
                                                void notifyListeners() {    
                                                    for (IListener* listener : mListeners) {    
                                                        listener->onUpdate();    
                                                    }    
                                                }    
                                                private:    
                                                vector <IListener*> mListeners;    
                                                };    
                                            
                                        
                                        Example 2
                                            
                                                class Subject {    
                                                public:    
                                                struct Observer    
                                                {    
                                                    virtual void onNotify() = 0;    
                                                };    
                                                Subject(Observer& observer) : _observer(observer) {}    
                                                void notify() {    
                                                    _observer.onNotify();    
                                                }    
                                                private:    
                                                Observer& _observer;    
                                                };    
                                                    
                                                
                                                    
                                                class Notifier : public Subject::Observer {    
                                                public:    
                                                Notifier();    
                                                ~Notifier();    
                                                virtual void onNotify() override {}    
                                                }; 
                                            
                                        
                                    The template method is a software design pattern that is defined through two components:
                                            
                                            
                                                class ITemplateMethod    
                                                {    
                                                public:    
                                                    void start()     
                                                    {    
                                                        init();    
                                                        prepare();    
                                                        compute();    
                                                        filter();    
                                                        display();    
                                                    }    
                                                protected:    
                                                    virtual void compute() = 0;    
                                                    virtual void filter() = 0;    
                                                private:    
                                                    void init() { }    
                                                    void prepare() { }    
                                                    void display() { }    
                                                };    
                                                    
                                                class CTemplateImpl : public ITemplateMethod    
                                                {    
                                                    virtual void computeData() override {}    
                                                    virtual void filterData() override {}    
                                                };    
                                            
                                        
                                    The State pattern is a behavioral design pattern that implements a state machine in an object-oriented way.
Each individual state is implemented as a derived class of the state pattern interface, and implements the transitions by invoking the methods defined by the interface.
                                        
                                            
                                            
                                                class IState {  
                                                public:  
                                                    virtual bool open(void)   = 0;  
                                                    virtual bool close(void)  = 0;  
                                                    virtual bool exec(void)   = 0;  
                                                };  
                                                
                                                class CStateImpl {  
                                                public:  
                                                    void setState(IState *state) { mStatePtr = state; }  
                                                
                                                    bool open(void)  { return mStatePtr->open();  }  
                                                    bool close(void) { return mStatePtr->close(); }  
                                                    bool exec(void)  { return mStatePtr->exec();  }  
                                                private:  
                                                    IState *mStatePtr;  
                                                };  
                                                
                                                class CActiveState : public IState {  
                                                public:  
                                                    virtual bool open(void) override {  
                                                        // in active state, cannot open..  
                                                        return false;  
                                                    }  
                                                    virtual bool close(void) override {  
                                                        // in active state, closing..  
                                                        return true;  
                                                    }  
                                                    virtual bool exec(void) override {  
                                                        // in active state, executing..  
                                                        return true;  
                                                    }  
                                                };  
                                                
                                                class CInactiveState : public IState {  
                                                public:  
                                                    virtual bool open(void) override {  
                                                        // in inactive state, opening..  
                                                        return true;   
                                                    }  
                                                    virtual bool close(void) override {  
                                                        // in inactive state, cannot close..  
                                                        return false;  
                                                    }  
                                                    virtual bool exec(void) override  {  
                                                        // in inactive state, we cannot execute..  
                                                        return false;  
                                                    }  
                                                };  
                                            
                                        
                                    The adapter pattern is used when we need two make two incompatible interface to work together. It does so by converting the interface of one class into an interface that is expected by the clients. In other words, we will have a class that inherits from both interfaces, and the calls from the external interfaces are adjusted so we can either provide further functionality of the old interface, or to delegate the call to them instead.
                                            
                                            
                                                // Desired interface  
                                                class Rectangle  
                                                {  
                                                public:  
                                                    virtual void draw() = 0;  
                                                };  
                                                
                                                using Coordinate = int;  
                                                using Dimension = int;  
                                                
                                                // Legacy component  
                                                class LegacyRectangle  
                                                {  
                                                public:  
                                                    LegacyRectangle(Coordinate x1, Coordinate y1, Coordinate x2, Coordinate y2)  
                                                    {  
                                                        x1_ = x1;  
                                                        y1_ = y1;  
                                                        x2_ = x2;  
                                                        y2_ = y2;  
                                                    }         
                                                    void oldDraw() { }  
                                                private:  
                                                    Coordinate x1_;  
                                                    Coordinate y1_;  
                                                    Coordinate x2_;  
                                                    Coordinate y2_;  
                                                };  
                                                
                                                // Adapter wrapper  
                                                class RectangleAdapter: public Rectangle, private LegacyRectangle  
                                                {  
                                                public:  
                                                    RectangleAdapter(Coordinate x, Coordinate y, Dimension w, Dimension h)  
                                                    : LegacyRectangle(x, y, x + w, y + h)  
                                                    {  
                                                    }  
                                                    virtual void draw()  
                                                    {  
                                                        oldDraw();  
                                                    }  
                                                };  
                                            
                                        
                                    Every class should have a single responsibility, and that responsibility should be entirely encapsulated by the class.