Wednesday, 28 July 2010

C++ example for Abstract Factory Design Pattern

The Abstract Factory Design Pattern provides an interface for creating families of related or dependent objects without specifying their concrete classes. The following UML class diagram explains how the Abstract Factory fits with the rest.


The following is example of Abstract factory design pattern:



//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
//Abstract Factory is part of Creational Patterns
//Creational Patterns deal with initializing and configuring classes and objects
//Abstract Factory creates an instance of several families of classes

//We will take an example of Animal Classes and Abstract them.
//There are 2 types of animals; Herbivores and Carnivores.
//The rule of nature is that Carnivores eats Herbivores which will be shown
//Different animas live in different continents but the same rule applies

#include<iostream>
#include<string>

using namespace
std;

//The Herbivore class - The 'AbstractProductA' abstract class
class Herbivore
{

public
:
virtual const
string& getName(void)=0;
};


//Lets define couple of Herbivores called Cow and Deer
class Cow : public Herbivore //The 'ProductA1' class
{
public
:
Cow():name("Cow"){};
//default destructor
const string& getName(void) {return name;}
private
:
string name;
};


class
Deer : public Herbivore //The 'ProductA2' class
{
public
:
Deer():name("Deer"){};
//default destructor
const string& getName(void) {return name;}
private
:
string name;
};


//The Carnivore class - The 'AbstractProductB' abstract class
class Carnivore
{

public
:
virtual const
string& getName(void)=0;
virtual
void eat(Herbivore& h) = 0;
};


//Lets define couple of Carnivores called Lion and Wolf
class Lion : public Carnivore //The 'ProductB1' class
{
public
:
Lion():name("Lion"){};
const
string& getName(void) {return name;}
void
eat(Herbivore& h) //override
{
cout << name << " eats " << h.getName() << endl;
}

private
:
string name;
};


class
Wolf : public Carnivore //The 'ProductB2' class
{
public
:
Wolf():name("Wolf"){};
const
string& getName(void) {return name;}
void
eat(Herbivore& h) //override
{
cout << name << " eats " << h.getName() << endl;
}

private
:
string name;
};


//The 'AbstractFactory' abstract class
class ContinentFactory
{

public
:
virtual
Herbivore& CreateHerbivore() = 0;
virtual
Carnivore& CreateCarnivore() = 0;
};


class
AfricaFactory : public ContinentFactory //The 'ConcreteFactory1' class
{
Herbivore& CreateHerbivore()
{

return
*(dynamic_cast<Herbivore *>(new Cow()));
}

Carnivore& CreateCarnivore()
{

return
*(dynamic_cast<Carnivore *>(new Lion()));
}
};


class
AmericaFactory : public ContinentFactory //The 'ConcreteFactory2' class
{
Herbivore& CreateHerbivore()
{

return
*(dynamic_cast<Herbivore *>(new Deer()));
}

Carnivore& CreateCarnivore()
{

return
*(dynamic_cast<Carnivore *>(new Wolf()));
}
};


//The 'Client' class
class AnimalWorld
{

public
:
AnimalWorld(ContinentFactory& factory):_herbivore(factory.CreateHerbivore()),_carnivore(factory.CreateCarnivore())
{
}

void
RunFoodChain()
{

_carnivore.eat(_herbivore);
}

private
:
Herbivore& _herbivore;
Carnivore& _carnivore;
};


int
main()
{

//Create and run African Animal World
ContinentFactory& africa = *(dynamic_cast<ContinentFactory *>(new AfricaFactory()));
AnimalWorld& world1 = *(new AnimalWorld(africa));
world1.RunFoodChain();

// Create and run the American animal world
ContinentFactory& america = *(dynamic_cast<ContinentFactory *>(new AmericaFactory()));
AnimalWorld& world2 = *(new AnimalWorld(america));
world2.RunFoodChain();

return
0;
}





The output is as follows:



For more details please see: http://www.dofactory.com/Patterns/PatternAbstract.aspx

Wednesday, 21 July 2010

C++ Design Patterns


Over the next few months we will be looking at Design Pattern examples using C++. Here is a good starting point from which the information in this post has been extracted.

Q: What is a Design Pattern?
A: Design Patterns represent solutions to problems what arise when developing software within a particular context.
Quote:
Each pattern describes a problem which occurs over and over again in our environment, and then describes the core of the solution to that problem, in such a way that you can use this solution a million times over, without ever doing it the same way twice.C. Alexander, The Timeless Way of Building, 1979
Quote:
Patterns help you learn from other's successes, instead of your own
failures.Mark Johnson (cited by Bruce Eckel)

Q: How many types of design patterns exist?
A: Basically, there are three categories:

Creational Patterns: deal with initializing and configuring classes and objects
Structural Patterns: deal with decoupling the interface and implementation of classes and objects
Behavioral Patterns: deal with dynamic interactions among societies of classes and objects


Q: What are good books about design patterns.
A: Here are some must-have books:
Design Patterns by Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides (also known as Gang of Four)
Thinking in Patterns with Java, by Bruce Eckel
Thinking in Patterns with C++, by Bruce Eckel


Q: How can I quickly find information about a design pattern?
A: Here are some links on the web:


Creational Patterns

Abstract Factory: Creates an instance of several families of classes
resource 1
resource 2

Builder: Separates object construction from its representation
resource 1
resource 2

Factory Method: Creates an instance of several derived classes
resource 1
resource 2
resource 3

Prototype: A fully initialized instance to be copied or cloned
resource 1
resource 2

Singleton: A class of which only a single instance can exist
resource 1
resource 2

Structural Patterns

Adapter: Match interfaces of different classes
resource 1
resource 2
resource 1

Bridge: Separates an object’s interface from its implementation
resource 1
resource 2

Composite: A tree structure of simple and composite objects
resource 1
resource 2
resource 3

Decorator: Add responsibilities to objects dynamically
resource 1
resource 2
resource 3

Façade: A single class that represents an entire subsystem
resource 1
resource 2

Flyweight: A fine-grained instance used for efficient sharing
resource 1
resource 2
resource 3

Proxy: An object representing another object
resource 1
resource 2

Behavioral Patterns

Chain of Responsibility: A way of passing a request between a chain of objects
resource 1
resource 2

Command: Encapsulate a command request as an object
resource 1
resource 2
resource 3

Interpreter: A way to include language elements in a program
resource 1
resource 2

Iterator: Sequentially access the elements of a collection
resource 1
resource 2

Mediator: Defines simplified communication between classes
resource 1
resource 2

Memento: Capture and restore an object's internal state
resource 1

Observer: A way of notifying change to a number of classes
resource 1
resource 2
resource 3

State: Alter an object's behavior when its state changes
resource 1
resource 2
resource 3

Strategy: Encapsulates an algorithm inside a class
resource 1
resource 2
resource 3

Template Method: Defer the exact steps of an algorithm to a subclass
resource 1
resource 2
resource 3

Visitor: Defines a new operation to a class without change
resource 1
resource 2
resource 3


Source: Code Guru

Wednesday, 14 July 2010

Client/Server communication via sockets

The following is a simple Client Server example that actually covers quite a few different topics. The code is modified from the MadWizard.org Winsock Tutorial. It may be a good idea to go through the StringStreams example here and C/C++ String differences example here.

Please note that the code below is not the best example of coding practice.

Server code:



//Original Client-Server code from www.MadWizard.org
//Part of the Winsock networking tutorial by Thomas Bleeker
//Modified and tested on Microsoft Visual Studio 2008 - Zahid Ghadialy

#include <iostream>
#include <string>
#include <sstream>

#define WIN32_MEAN_AND_LEAN
#include <winsock2.h>
#include <windows.h>

//Add ws2_32.lib in Properties->Linker->Input->Additional Dependencies

using namespace
std;

const
int REQ_WINSOCK_VER = 2; // Minimum winsock version required
const int DEFAULT_PORT = 4444;
const
int TEMP_BUFFER_SIZE = 128;

//Forward Declarations
bool RunServer(int portNumber);

//MAIN
int main()
{

int
iRet = 1;
WSADATA wsaData;

cout << "SERVER STARTED" << endl;
cout << "Initializing winsock... ";

if
(WSAStartup(MAKEWORD(REQ_WINSOCK_VER,0), &wsaData)==0)
{

// Check if major version is at least REQ_WINSOCK_VER
if (LOBYTE(wsaData.wVersion) >= REQ_WINSOCK_VER)
{

cout << "initialized.\n";

int
port = DEFAULT_PORT;
iRet = !RunServer(port);
}

else

{

cerr << "required version not supported!";
}


cout << "Cleaning up winsock... ";

// Cleanup winsock
if (WSACleanup()!=0)
{

cerr << "cleanup failed!\n";
iRet = 1;
}

cout << "done.\n";
}

else

{

cerr << "startup failed!\n";
}

return
iRet;
}



string GetHostDescription(const sockaddr_in &sockAddr)
{

ostringstream stream;
stream << inet_ntoa(sockAddr.sin_addr) << ":" << ntohs(sockAddr.sin_port);
return
stream.str();
}


void
SetServerSockAddr(sockaddr_in *pSockAddr, int portNumber)
{

// Set family, port and find IP
pSockAddr->sin_family = AF_INET;
pSockAddr->sin_port = htons(portNumber);
pSockAddr->sin_addr.S_un.S_addr = INADDR_ANY;
}


void
HandleConnection(SOCKET hClientSocket, const sockaddr_in &sockAddr)
{

// Print description (IP:port) of connected client
cout << "Connected with " << GetHostDescription(sockAddr) << ".\n";
exception e;

char
tempBuffer[TEMP_BUFFER_SIZE];

// Read data
while(true)
{

int
retval;
retval = recv(hClientSocket, tempBuffer, sizeof(tempBuffer), 0);
if
(retval==0)
{

break
; // Connection has been closed
}
else if
(retval==SOCKET_ERROR)
{

exception e("socket error while receiving.");
throw
e;
}

else

{

string tempBufferString(tempBuffer);
cout<<"Received over the socket :"<<tempBufferString<<endl;
string tempString = "Loopbacked: " + tempBufferString + '\0';
strcpy_s(tempBuffer, tempString.length() + 1, tempString.c_str());
if
(send(hClientSocket, tempBuffer, strlen(tempBuffer)+1, 0)==SOCKET_ERROR)
{

exception e("socket error while sending.");
throw
e;
}
}
}

cout << "Connection closed.\n";
}


bool
RunServer(int portNumber)
{

SOCKET hSocket = INVALID_SOCKET, hClientSocket = INVALID_SOCKET;
bool
bSuccess = true;
sockaddr_in sockAddr = {0};

try

{

// Create socket
cout << "Creating socket... ";
if
((hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET)
{

cout << "failed Creating socket... \n";
return
false;
}

cout << "created.\n";

// Bind socket
cout << "Binding socket... ";
SetServerSockAddr(&sockAddr, portNumber);
if
(bind(hSocket, reinterpret_cast<sockaddr*>(&sockAddr), sizeof(sockAddr))!=0)
{

cout << "failed Binding socket... \n";
return
false;
}

cout << "bound.\n";

// Put socket in listening mode
cout << "Putting socket in listening mode... ";
if
(listen(hSocket, SOMAXCONN)!=0)
{

cout << "failed Putting socket in listening mode... \n";
return
false;
}

cout << "done.\n";

// Wait for connection
cout << "Waiting for incoming connection... ";

sockaddr_in clientSockAddr;
int
clientSockSize = sizeof(clientSockAddr);

// Accept connection:
hClientSocket = accept(hSocket,
reinterpret_cast
<sockaddr*>(&clientSockAddr),
&
clientSockSize);

// Check if accept succeeded
if (hClientSocket==INVALID_SOCKET)
{

cout << "accept function failed... \n";
return
false;
}

cout << "accepted.\n";

// Wait for and accept a connection:
HandleConnection(hClientSocket, clientSockAddr);

}

catch
(exception& e)
{

cerr << "\nError: " << e.what() << endl;
bSuccess = false;
}


if
(hSocket!=INVALID_SOCKET)
closesocket(hSocket);

if
(hClientSocket!=INVALID_SOCKET)
closesocket(hClientSocket);

return
bSuccess;
}




Client code:




//Original Client-Server code from www.MadWizard.org
//Part of the Winsock networking tutorial by Thomas Bleeker
//Modified and tested on Microsoft Visual Studio 2008 - Zahid Ghadialy

#include <iostream>
#include <sstream>

#define WIN32_MEAN_AND_LEAN
#include <winsock2.h>
#include <windows.h>

using namespace
std;

//Add ws2_32.lib in Properties->Linker->Input->Additional Dependencies

using namespace
std;

const
int REQ_WINSOCK_VER = 2; // Minimum winsock version required
const char DEF_SERVER_NAME[] = "127.0.0.1"; //localhost - can be your server name like "www.google.com"
const int SERVER_PORT = 4444;
const
int TEMP_BUFFER_SIZE = 128;

// IP number typedef for IPv4
typedef unsigned long IPNumber;

//Forward Declarations
bool RunClient(const char *pServername);

//MAIN
int main(int argc, char* argv[])
{

int
iRet = 1;
WSADATA wsaData;

cout << "CLIENT STARTED" << endl;
cout << "Initializing winsock... ";

if
(WSAStartup(MAKEWORD(REQ_WINSOCK_VER,0), &wsaData)==0)
{

// Check if major version is at least REQ_WINSOCK_VER
if (LOBYTE(wsaData.wVersion) >= REQ_WINSOCK_VER)
{

cout << "initialized.\n";

// Set default hostname:
const char *pHostname = DEF_SERVER_NAME;
iRet = !RunClient(pHostname);
}

else

{

cerr << "required version not supported!";
}


cout << "Cleaning up winsock... ";

// Cleanup winsock
if (WSACleanup()!=0)
{

cerr << "cleanup failed!\n";
iRet = 1;
}

cout << "done.\n";
}

else

{

cerr << "startup failed!\n";
}

return
iRet;
}



IPNumber FindHostIP(const char *pServerName)
{

HOSTENT *pHostent;

// Get hostent structure for hostname:
if (!(pHostent = gethostbyname(pServerName)))
{

exception e("could not resolve hostname.");
throw
e;
}


// Extract primary IP address from hostent structure:
if (pHostent->h_addr_list && pHostent->h_addr_list[0])
return
*reinterpret_cast<IPNumber*>(pHostent->h_addr_list[0]);

return
0;
}


void
FillSockAddr(sockaddr_in *pSockAddr, const char *pServerName, int portNumber)
{

// Set family, port and find IP
pSockAddr->sin_family = AF_INET;
pSockAddr->sin_port = htons(portNumber);
pSockAddr->sin_addr.S_un.S_addr = FindHostIP(pServerName);
}


bool
RunClient(const char *pServername)
{

SOCKET hSocket = INVALID_SOCKET;
char
tempBuffer[TEMP_BUFFER_SIZE];
sockaddr_in sockAddr = {0};
bool
bSuccess = true;

try

{

// Lookup hostname and fill sockaddr_in structure:
cout << "Looking up hostname " << pServername << "... ";
FillSockAddr(&sockAddr, pServername, SERVER_PORT);
cout << "found.\n";

// Create socket
cout << "Creating socket... ";
if
((hSocket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) == INVALID_SOCKET)
{

cout<<"could not create socket. "<<endl;
return
false;
}

cout << "created.\n";

// Connect to server
cout << "Attempting to connect to " << inet_ntoa(sockAddr.sin_addr)
<<
":" << SERVER_PORT << "... ";
if
(connect(hSocket, reinterpret_cast<sockaddr*>(&sockAddr), sizeof(sockAddr))!=0)
{

cout<<"could not connect. "<<endl;
return
false;
}

cout << "connected.\n";

cout << "Sending requests and checking for loopbacks... "<<endl;

//Lets sent 100 packets and get it looped back from Server
for(int i = 0; i < 10; i++)
{

int
retval = 0;
stringstream ss (stringstream::in | stringstream::out);
ss << "Message " << i <<"\n";

std::string s = ss.str() + '\0'; //Adding the null charachter
if (send(hSocket, s.c_str(), s.size() + 1, 0)==SOCKET_ERROR)
{

cout<<"failed to send data. "<<endl;
return
false;
}


retval = recv(hSocket, tempBuffer, sizeof(tempBuffer), 0);
if
(retval==0)
{

cout<<"Connection closed"<<endl;
break
;
}

else if
(retval==SOCKET_ERROR)
{

exception e("socket error while receiving.");
throw
e;
}

else

{

// retval is number of bytes read
// Terminate buffer with zero and print as string
tempBuffer[retval] = 0;
cout << "Received " << retval << " bytes. Received : " <<tempBuffer;
}
}
}

catch
(exception& e)
{

cerr << "\nError: " << e.what() << endl;
bSuccess = false;
}


if
(hSocket!=INVALID_SOCKET)
{

closesocket(hSocket);
}

return
bSuccess;
}





The Server Output is as follows:


The Client output is as follows:

Wednesday, 7 July 2010

How to Extend existing enums

Picked up this very interesting example on extending enum's. The program is self explanatory and is as follows:



//Program tested on Microsoft Visual Studio 2008 - Zahid Ghadialy
#include<iostream>

using namespace
std;

int
main()
{

enum
Enum1
{

value1,
value2,
value3,
final_value = value3
};


//Print out the enum values
cout<<"Enum1 values : ";
for
(int i = 0; i <= final_value; i++)
cout<<Enum1(i)<<" ";
cout<<endl;

enum
extendedEnum1
{

value4 = final_value + 1,
value5,
value6,
new_final_value = value6
};


//Print out the enum values
cout<<"extendedEnum1 values : ";
for
(int i = 0; i <= new_final_value; i++)
cout<<extendedEnum1(i)<<" ";
cout<<endl;

return
0;
}



The output is as follows: