Thursday, May 13, 2010

Observer Pattern : My understanding

Imagine few security events like - Order, Trade, Quotes etc.
So, whatever changes happening to Security object (like ticksize change, lot size, etc) have to be broadcasted to Order, Trade, Quotes objects.

So, the idea is like this -

We have the Security Class
And classes like Order, Trade, Quotes will be derived from Security.

And we have a class SecurityObserver.
Security class has a list of SecurityObserver objects, once each for Order, Trade, Quote.

The code looks like this -


class Security;

class SecurityObserver
{
public:
virtual void updateEvent(const Security&) = 0;
};

class Security
{
std::list _observers;
typedef std::list::iterator _iterator;
Notify()
{
//iterate thru list _observers
call updateEvent for each observer.
}

public:
void add_to_observer_list(SecurityObserver &);
void remove_from_observer_list(SecurityObserver &);
void some_function()
{
Notify();
}
}

Class Order : public SecurityObserver
{
public:
void updateEvent(const Security&)
{
//some implementation
}

};

Class Trade : public SecurityObserver
{
public:
void updateEvent(const Security&)
{
//some implementation
}

};

Monday, May 10, 2010

Multi-Threaded Singleton : My understanding

Well, there are two aspects of problems arising in multi-threaded environment, for Singleton classes -

1. While creating the object
2. While accessing the object

Both of them pointing to the same static function - getInstance()

http://www.bombaydigital.com/arenared/2005/10/25/1 has provided a good-decent-detailed discussion. Many Thanks to him/her.

The best solution (if possible) is to create instance when only main thread is executing. So, later, when the binary has multiple threads, the object is already in place.

This is the basic code -
class T
{
public:
static T* instance();
private:
T() {}
~T() {}
static T* smInstance;
static VMutex smMutex;
};
// T.cpp:
T* T::smInstance = NULL;
VMutex T::smMutex;
T* T::instance()
{
VMutexLocker lock(&smMutex);
if (smInstance == NULL)
smInstance = new T();
return smInstance;
}

However, you might notice that we've incurred the overhead of locking every time someone accesses the instance of the singleton. There's a well-known pattern to eliminate this overhead, called the double-checked lock. It takes advantage of the fact that we can (apparently) check for null as a quick test before we even bother with locking. Here's how this would look:

T* T::instance()
{
if (smInstance == NULL)
{
VMutexLocker lock(&smMutex);

if (smInstance == NULL) // double-check
smInstance = new T();
}
return smInstance;
}

But, Here is the core problem: We have no guarantee that T will be fully constructed before the pointer smInstance is assigned. For example, the compiler is within its rights to generate processor instructions that implement the statement in the following order:
1. Allocate a memory block sized for T.
2. Assign the address of the memory block to smInstance
3. Call T's constructor.

Consider then what happens if the other thread performs its unsynchronized null pointer test when we are between steps 2 and 3 of the instantiation statement: It will see a non-null value, and will proceed to return the pointer to the raw memory of the not-yet-constructed object.

Friday, May 7, 2010

Single Threaded Singleton : My understanding

class CMyClass
{
private:
CMyClass() {} // Private Constructor - prevent construction
CMySingleton(const CMySingleton&); // Prevent copy-construction
CMySingleton& operator=(const CMySingleton&); // Prevent assignment

static int nCount; // Current number of instances
static int nMaxInstance; // Maximum number of instances

public:
~CMyClass() // Public Destructor
{
--nCount; // Decrement number of instances
}


static CMyClass* CreateInstance() // Construct Indirectly
{
CMyClass* ptr = NULL;

if(nMaxInstance > nCount)
{
ptr = new CMyClass;
++nCount; // Increment no of instances
}
return ptr;
}

//Add whatever members you want
};

int CMyClass::nCount = 0;
int CMyClass::nMaxInstance = 1; // When maxInstance is 1, we have a pure singleton class

Practical usage of singleton is -
The OrderEvent class - the factory in the factory method design pattern.
All financial login screens etc are nice examples of singleton behaviour.

Tuesday, May 4, 2010

Template Method : My example

We had several order events like – EnterOrder, SendOrder, CancelOrder etc.

We had 2 variations of the bzness logic in these events – one for UK and one for US.
So the class hierarchy was like this –
Base : EnterOrder
Derived1 : EnterOrderUK : public EnterOrder
Derived2 : EnterOrderUS : public EnterOrder

Base Class declaration is like this –
Class EnterOrder{
Public :
Run(){
Step1();
Step2();
Step3();
}
Private:
Virtual Step1(){}
Virtual Step2(){}
Virtual Step3(){}
};

Class EnterOrderUK{
Private :
Step1(){//UK specific code}
//other steps not overridden, so base class default functionality will be executed.
}

Class EnterOrderUS{
Private :
Step3(){//US specific code}
//other steps not overridden, so base class default functionality will be executed.
}

The code in main would be like this –
EnterOrder *ptr = NULL;
If(UK)
ptr= new EnterOrderUK();
Else (US)ptr = new EnterOrderUS();

Ptr->run();

Here, run in the base class is the only function my application has access to. This is a template algorithm, and functionality specific to derived classes will be overriden(step() functions).

Factory Method : My example

We had several order events like EnterOrder, ExecOrder, SendOrder, CancelOrder, ModifyOrder, Etc

All these events were classes, which had methods for bzness logic.

And we had our factory class – OrderEvent as –
Class OrderEvent {
Virtual EnterOrder * createEnterOrder() = 0;
Virtual ExecOrder * createEnterOrder()= 0;
Virtual SendOrder * createEnterOrder()= 0;

};

Depending upon US or UK, we had following various derived classes –
UKEnterOrder/USEnterOrder
UKExecOrder/USExecOrder etc

And UKOrderEvent/USOrderEvent

Class UKOrderEvent {
EnterOrder * createEnterOrder() {
return new UKEnterOrder();
}
ExecOrder * createExecOrder() {
return new UKExecOrder();
}
};

Class USOrderEvent {
EnterOrder * createEnterOrder() {
return new USEnterOrder();
}
ExecOrder * createExecOrder() {
return new USExecOrder();
}
};

In the main(), it was used like this –
OrderEvent *ptr = NULL;
If(country = UK)
ptr = new UKOrderEvent;
Else if (country = US)
ptr = new USOrderEvent;

ptr->createEnterOrder();

The beauty here is that - the OrderEvent classes can be made Singleton, and this is a good example of Singleton classes, in addition to normal banking login, logger, COW type of singleton examples.