Powered by Blogger.

Recent Comments

Archive for January 2022

Chain of Responsibility

 

Chain of Responsibility:

Scenario: Design the software for a system that approves purchasing requests. The approval authority depends on the dollar amount of the purchase. The approval authority for a given dollar amount could change at any time and the system should be flexible enough to handle this situation.

                  Solution: PurchaseRequest objects forward the approval request to a PurchaseApproval object. Depending on the dollar amount, the PurchaseApproval object may approve the request or forward it on to the next approving authority in the chain. The approval authority at any level in the chain can be easily modified without affecting the original PurchaseRequest object. => Chain of Responsibility pattern.

 Intent:

Avoid coupling the sender of a request to its receiver by giving more than

one object a chance to handle the request. Chain the receiving objects and

pass the request along the chain until an object handles it.

 Applicability

Use Chain of Responsibility:

Ø  When more than one object may handle a request and the actual handler is not know in advance

Ø  When requests follow a “handle or forward” model - that is, some requests can be handled where they are generated while others must be forwarded to another object to be handled

 Advantages:

Ø  Reduced coupling between the sender of a request and the receiver – the sender and receiver have no explicit knowledge of each other

Ø  The chain of handlers can be modified dynamically

DisAdvantages:

Receipt is not guaranteed - a request could fall off the end of the chain without being handled

Structure:

The derived classes know how to satisfy Client requests. If the “current” object is not available or sufficient, then it delegates to the base class, which delegates to the “next” object, and the circle of life continues.



Multiple handlers could contribute to the handling of each request. The request can be passed down the entire length of the chain, with the last link being careful not to delegate to a “null next”.

Code Flow:

  1. The base class maintains a “next” pointer.
  2. Each derived class implements its contribution for handling the request.
  3. If the request needs to be “passed on”, then the derived class “calls back” to the base class, which delegates to the “next” pointer.
  4. The client (or some third party) creates and links the chain (which may include a link from the last node to the root node).
  5. The client “launches and leaves” each request with the root of the chain.
  6. Recursive delegation produces the illusion of magic.

 

#include <iostream>

using namespace std;

 

enum ErrorStates { ANALYZE=0,FIX,VERIFY,CLOSE };

 

 

class ErrorReport {

 

private:

       ErrorStates state;

 

public:

       ErrorReport(ErrorStates state)

       {

              this->state = state;

       }

       ErrorStates GetState()

       {

              return state;

       }

       void setState(ErrorStates state)

       {

              this->state= state;

       }

};

 

class Error {

protected:

       ErrorStates state;

       Error *next;

 

public:

       //Constructor

       Error(ErrorStates astate){state = astate;}

 

       //set the successor

       void setnext(Error *n) {

              this->next = n;

       }

 

       //pure virtual function to be implemented by concrete classes

       virtual void ProcessError(ErrorReport &Err) = 0;

};

 

class FixError : public Error {

 

public:

       FixError() : Error(FIX) {}

       void ProcessError(ErrorReport &Err)

       {

              if(Err.GetState() == FIX)

                     cout << "Error to be fixed "<< endl;

              else

              {

                     cout <<"error not fixed"<< endl;

 

 

                     next->ProcessError(Err);

              }

       }

};

class AnalyzeError : public Error

{

public:

       AnalyzeError() : Error(ANALYZE){}

       void ProcessError(ErrorReport &Err)

       {

              if(Err.GetState() == ANALYZE)

                     cout << "Error to be analyzed "<< endl;

              else

              {

                     cout <<"error not handled in analysis"<< endl;

                     next->ProcessError(Err);

              }

       }

};

 

class VerifyError : public Error

{

public:

       VerifyError() : Error(VERIFY){}

       void ProcessError(ErrorReport &Err)

       {

              if(Err.GetState() == VERIFY)

                     cout << "Error to be verified "<< endl;

              else

              {

                     cout <<"error not handled in verify"<< endl;

                     next->ProcessError(Err);

              }

       }

};

class CloseError : public Error

{

public:

       CloseError() : Error(CLOSE){}

       void ProcessError(ErrorReport &Err)

       {

              if(Err.GetState() == CLOSE)

                     cout << "Error to be closed "<< endl;

              else

              {

                     cout <<"error not handled in close"<< endl;

                     next->ProcessError(Err);

              }

       }

};

 

int main() {

       AnalyzeError *AE = new AnalyzeError();

       FixError *FE = new FixError();

 

 

     CloseError *CE= new CloseError();

     VerifyError *VE = new VerifyError();

 

     AE->setnext(FE);

     FE->setnext(VE);

     VE->setnext(CE);

 

     ErrorReport *ERA = new ErrorReport(ANALYZE);

     AE->ProcessError(*ERA);

 

     ErrorReport *ERC = new ErrorReport(CLOSE);

     AE->ProcessError(*ERC);

 

     delete AE;

     delete FE;

     delete CE;

     delete VE;

     delete ERA;

     delete ERC;

 

     cout << "Stack Implementation" << endl; // prints Stack Implementation

     return 0;

}

 





Factory Pattern

 

Factory Patterns:

Creational patterns: Abstract the object instantiation process. They hide how objects are

                               created and help make the overall system independent of how its  

                               objects are created and composed.

 Factory Method:     It’s a class creational pattern. Uses inheritance to decide the object to  

                                be instantiated.

 Abstract Factory:    It’s a object creational pattern. Focuses on the delegation of the 

                                instantiation to another object.


The Factory method pattern:

“Define an interface for creating an object but let subclasses decide which class to instantiate. Factory method lets a class defer instantiation to subclasses.”

Applicability:

Use the Factory Method pattern in any of the following situations:

v  A class can't anticipate the class of objects it must create

v  A class wants its subclasses to specify the objects it creates

Structure:





Product : Defines the interface for the type of objects the factory method creates
ConcreteProduct: Implements the Product interface
Creator: Declares the factory method, which returns an object of type Product
ConcreteCreator: Overrides the factory method to return an instance of concreteProduct

The Factory Method Pattern lets subclasses decide which class to instantiate?

 It means that Creator class is written without knowing what actual ConcreteProduct class will be instantiated. The ConcreteProduct class which is instantiated is determined solely by which ConcreteCreator subclass is instantiated and used by the application.


Example:

#include <iostream>

using namespace std;

 class product

{

public:

       product()

       {

              cout << "product constructor" << endl;

       }

       virtual void displayname() = 0;

 };

class concreteprd1 : public product

{

public:

       concreteprd1()

       {

              cout << "concreteprd1 constructor" << endl;

       }

       void displayname()

       {

              cout << "the concrete product 1" << endl;

       }

 };

class concreteprd2 : public product

{

public:

       concreteprd2()

       {

              cout << "concreteprd2 constructor" << endl;

       }

       void displayname()

       {

              cout << "the concrete product 2" << endl;

       }

};

class creator

{

public:

       virtual product* createproduct() = 0;

};

class concretecreator1 : public creator

{

public:

       virtual product* createproduct()

       {

              cout << "concrete creator 1 " << endl;

              return new concreteprd1;

       }

};

class concretecreator2 : public creator

{

public:

       virtual product* createproduct()

       {

              cout << "concrete creator 2 " << endl;

              return new concreteprd2;

       }

};

 int main() {

       cout << "Factory Pattern" << endl; // prints Factory Pattern

       creator *c = new concretecreator1();

       product *p = c->createproduct();

       p->displayname();

       delete c;

       delete p;

       return 0;

}

=======================================================================

Simple Factory Example

//
// Interface
//
public interface IChoice
{
    string Buy();
}
//
// Factory Class
//
public class FactoryChoice
{
    static public IChoice getChoiceObj(string cChoice)
     {
        IChoice objChoice=null;
        if (cChoice.ToLower() == "car")
        {
            objChoice = new clsCar();
        }
        else if (cChoice.ToLower() == "bike")
        {
            objChoice = new clsBike();
        }
        else
        {
            objChoice = new InvalidChoice();
        }
        return objChoice;
    }
}
 
//Business classes
//Car
public class clsBike:IChoice
{
    #region IChoice Members
 
    public string Buy()
    {
        return ("You choose Bike");
    }
 
    #endregion
}
 
//Bike
public class clsCar:IChoice
{
 
    #region IChoice Members
 
    public string Buy()
    {
        return ("You choose Car");
    }
 
    #endregion
}
 
//Client class
IChoice objInvoice;
objInvoice = FactoryClass.FactoryChoice.getChoiceObj(txtChoice.Text.Trim());
MessageBox.Show(objInvoice.Buy());
 



















- Copyright © Technical Articles - Skyblue - Powered by Blogger - Designed by Johanes Djogan -