Click to See Complete Forum and Search --> : Design Guidance ..


mop65715
February 3rd, 2007, 10:44 PM
This is in some respects an oversimplification of my problem, nonetheless, I'm having a hard time trying to structure my design. The code below shows two methods that differ in the amount of buffers used. One method supports dual buffer mode. Another method supports single buffer mode. Dual buffer is just that - two buffers where writes to the buffers is done in an alternating fashion. Here's a synopsis of the code.



# include <iostream>
# include <string>

class foo_c {

int buffer_a;
int buffer_b;

public :
foo_c ( int buffer_a, int buffer_b = 0 )
: buffer_a ( buffer_a )
, buffer_b ( buffer_b )
{}

void
dual_buffer_method ( int arg )
{
if ( arg == buffer_a ) {
// stuff
} else if ( arg == buffer_b )
{
// stuff
}
}

void
single_buffer_method ( int arg )
{
if ( arg == buffer_a )
{
// stuff
}
}

};

int main()
{
foo_c single ( 5 ) ;
foo_c dual ( 6, 3 ) ;

}


What disturbs me is the selection of the buffer ( signal versus dual ) is not _quite_ intuitive. Sure I have functions ( single_buffer_method / dual_buffer_method) and a constructor with a default value, however I feel there's something amiss. Ideas welcomed.

Thanks alot

James2007
February 3rd, 2007, 10:51 PM
Is the problem here 'blackboxing' in the sense you do not like how the class exposes it's methods? Or is it more in the sense that you think that there is a better way to do what you want?

If you mean 'intuitive', then I think it's in the 'blackbox' realm.

I think you are hinting at the fact you want the 'buffer selection' transparent to other classes that use it.

Consider since this is 'alternating' you could use a variable (a pointer) that points at the variable that is the 'current buffer'. When a 'write' is called, set it to the 'other' after the write is done to the current. (You'll have to check which one it points at.)

That's for the 'dual'.

For separating single from dual transparently, create an abstract base class that has 'pure virtual functions' that the 'single' and 'dual' derived classes implement.



class IBuffer
{
public:
virtual void CommonInterfaceFunction() throw() = 0;
};

class Single : public IBuffer
{
public:
virtual void CommonInterfaceFunction() throw();
};

class Dual : public IBuffer
{
public:
virtual void CommonInterfaceFunction() throw();
};

// in some function

IBuffer * pBuffer = new Dual();

pBuffer->CommonInterfaceFunction();

delete pBuffer;



Interfacing is all a personal preference. Consider the following.



class IValue
{
public:
virtual void SetValue(int value) = 0;
virtual int GetValue() const = 0;
};

class ClassValue : public IValue
{
public:
virtual void SetValue(int value) { Value = value; }
virtual int GetValue() const { return Value; }
private:
int Value;
};

class EncryptedValue : public ClassValue
{
public:
virtual void SetValue(int value) { ClassValue::SetValue(value ^ 0xC1); }
virtual int GetValue() const { return ClassValue::GetValue() ^ 0xC1; }
};

class EncryptedWrapper : public IValue
{
public:
EncryptedWrapper(IValue * pValue) : InnerValue(pValue) {}
virtual void SetValue(int value) { InnerValue->SetValue(value ^ 0xC1); }
virtual int GetValue() const { return InnerValue->GetValue() ^ 0xC1; }
private:
IValue * InnerValue;
};



You'll see two ways of having the 'encrypted' IValue. One that simply derives and implements, and one that derives and uses an 'inner object'.

mop65715
February 4th, 2007, 12:49 AM
I think you are hinting at the fact you want the 'buffer selection' transparent to other classes that use it.



Correct. I'm sure I'll have some follow-on questions in a few. For now I'll soak up your suggestion.