Read / Write Pattern Design

N

Nephi Immortal

I create ten digits. Ten digits are stored into one array with ten
elements. They are the English number symbols. I want to translate
them into international number symbols into other arrays.
Notice global variable – const rgDigits[ 10 ]. It is fine, but each
array can have the choice to support read only, write only, or read/
write only.
I create two classes. First class is read only and second class is
write only. It is more flexible because suppose you have ten read
only arrays and two write only arrays such as “customize”.
Attempt to use const_cast keyword is bad idea because it might lead
to undefined behavior.
Both classes are the replacement of parameter objects which I mean
that I don’t need to put ten arguments or perhaps twenty arguments
into one constructor function. It should be called Parameter Object
Design Pattern, but I was unable to find good example code. Builder
Pattern Design is very similar.
I call it as Read / Write Object Design Pattern. Please let me know
if my code looks neat.


class Digits_Read_Only;

class Digits_Write_Only
{
private:
friend class Digits_Read_Only;

enum EDigits
{
eZero,
eOne,
eTwo,
eThree,
eFour,
eFive,
eSix,
eSeven,
eEight,
eNine
};

char data[ 10 ];

public:
Digits_Write_Only()
{
set_zero();
set_one();
set_two();
set_three();
set_four();
set_five();
set_six();
set_seven();
set_eight();
set_nine();
}

Digits_Write_Only& set_zero( char zero = 0x30 )
{
data[ eZero ] = zero;
return *this;
}

Digits_Write_Only& set_one( char one = 0x31 )
{
data[ eOne ] = one;
return *this;
}

Digits_Write_Only& set_two( char two = 0x32 )
{
data[ eTwo ] = two;
return *this;
}

Digits_Write_Only& set_three( char three = 0x33 )
{
data[ eThree ] = three;
return *this;
}

Digits_Write_Only& set_four( char four = 0x34 )
{
data[ eFour ] = four;
return *this;
}

Digits_Write_Only& set_five( char five = 0x35 )
{
data[ eFive ] = five;
return *this;
}

Digits_Write_Only& set_six( char six = 0x36 )
{
data[ eSix ] = six;
return *this;
}

Digits_Write_Only& set_seven( char seven = 0x37 )
{
data[ eSeven ] = seven;
return *this;
}

Digits_Write_Only& set_eight( char eight = 0x38 )
{
data[ eEight ] = eight;
return *this;
}

Digits_Write_Only& set_nine( char nine = 0x39 )
{
data[ eNine ] = nine;
return *this;
}
};

class Digits_Read_Only
{
private:
const Digits_Write_Only& _digits;

public:
Digits_Read_Only( const Digits_Write_Only& digits ) :
_digits( digits )
{
}

char get_zero() const
{
return _digits.data[ Digits_Write_Only::eZero ];
}

char get_one() const
{
return _digits.data[ Digits_Write_Only::eOne ];
}

char get_two() const
{
return _digits.data[ Digits_Write_Only::eTwo ];
}

char get_three() const
{
return _digits.data[ Digits_Write_Only::eThree ];
}

char get_four() const
{
return _digits.data[ Digits_Write_Only::eFour ];
}

char get_five() const
{
return _digits.data[ Digits_Write_Only::eFive ];
}

char get_six() const
{
return _digits.data[ Digits_Write_Only::eSix ];
}

char get_seven() const
{
return _digits.data[ Digits_Write_Only::eSeven ];
}

char get_eight() const
{
return _digits.data[ Digits_Write_Only::eEight ];
}

char get_nine() const
{
return _digits.data[ Digits_Write_Only::eNine ];
}

char operator[]( int index ) const
{
if( Digits_Write_Only::eZero <= index && index <=
Digits_Write_Only::eNine )
return _digits.data[ index ];
else
return 0xFF; // invalid index
}

int begin() const
{
return Digits_Write_Only::eZero;
}

int end() const
{
return Digits_Write_Only::eNine;
}

};

Digits_Write_Only initialize_digits;
const Digits_Read_Only digits( initialize_digits );

const char rgDigits[ 10 ] =
{
0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9
};

int main()
{
char data[ 10 ];

for( int i = digits.begin() ; i <= digits.end(); ++i )
data[ i ] = digits[ i ];

for( int i = 0; i <= 9; ++i )
data[ i ] = rgDigits[ i ];

return 0;

}
 
A

Alf P. Steinbach

On 16.02.2012 06:05, Nephi Immortal wrote:
[snip intro]
I call it as Read / Write Object Design Pattern. Please let me know
if my code looks neat.


class Digits_Read_Only;

class Digits_Write_Only
{
private:
friend class Digits_Read_Only;

enum EDigits
{
eZero,
eOne,
eTwo,
eThree,
eFour,
eFive,
eSix,
eSeven,
eEight,
eNine
};

char data[ 10 ];

public:
Digits_Write_Only()
{
set_zero();
set_one();
set_two();
set_three();
set_four();
set_five();
set_six();
set_seven();
set_eight();
set_nine();
}

Digits_Write_Only& set_zero( char zero = 0x30 )
{
data[ eZero ] = zero;
return *this;
}

Digits_Write_Only& set_one( char one = 0x31 )
{
data[ eOne ] = one;
return *this;
}

Digits_Write_Only& set_two( char two = 0x32 )
{
data[ eTwo ] = two;
return *this;
}

Digits_Write_Only& set_three( char three = 0x33 )
{
data[ eThree ] = three;
return *this;
}

Digits_Write_Only& set_four( char four = 0x34 )
{
data[ eFour ] = four;
return *this;
}

Digits_Write_Only& set_five( char five = 0x35 )
{
data[ eFive ] = five;
return *this;
}

Digits_Write_Only& set_six( char six = 0x36 )
{
data[ eSix ] = six;
return *this;
}

Digits_Write_Only& set_seven( char seven = 0x37 )
{
data[ eSeven ] = seven;
return *this;
}

Digits_Write_Only& set_eight( char eight = 0x38 )
{
data[ eEight ] = eight;
return *this;
}

Digits_Write_Only& set_nine( char nine = 0x39 )
{
data[ eNine ] = nine;
return *this;
}
};

class Digits_Read_Only
{
private:
const Digits_Write_Only& _digits;

public:
Digits_Read_Only( const Digits_Write_Only& digits ) :
_digits( digits )
{
}

char get_zero() const
{
return _digits.data[ Digits_Write_Only::eZero ];
}

char get_one() const
{
return _digits.data[ Digits_Write_Only::eOne ];
}

char get_two() const
{
return _digits.data[ Digits_Write_Only::eTwo ];
}

char get_three() const
{
return _digits.data[ Digits_Write_Only::eThree ];
}

char get_four() const
{
return _digits.data[ Digits_Write_Only::eFour ];
}

char get_five() const
{
return _digits.data[ Digits_Write_Only::eFive ];
}

char get_six() const
{
return _digits.data[ Digits_Write_Only::eSix ];
}

char get_seven() const
{
return _digits.data[ Digits_Write_Only::eSeven ];
}

char get_eight() const
{
return _digits.data[ Digits_Write_Only::eEight ];
}

char get_nine() const
{
return _digits.data[ Digits_Write_Only::eNine ];
}

char operator[]( int index ) const
{
if( Digits_Write_Only::eZero<= index&& index<=
Digits_Write_Only::eNine )
return _digits.data[ index ];
else
return 0xFF; // invalid index
}

int begin() const
{
return Digits_Write_Only::eZero;
}

int end() const
{
return Digits_Write_Only::eNine;
}

};

Digits_Write_Only initialize_digits;
const Digits_Read_Only digits( initialize_digits );

const char rgDigits[ 10 ] =
{
0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9
};

int main()
{
char data[ 10 ];

for( int i = digits.begin() ; i<= digits.end(); ++i )
data[ i ] = digits[ i ];

for( int i = 0; i<= 9; ++i )
data[ i ] = rgDigits[ i ];

return 0;

}

Regarding whether your code looks "neat", well it isn't untidy, but on
the other hand "neat" is associated with an elegant or surprisingly
simple solution of something.

And I can't see that your code solves any problem?

Cheers & hth.,

- Alf
 
J

Juha Nieminen

Nephi Immortal said:
enum EDigits
{
eZero,
eOne,
eTwo,
eThree,
eFour,
eFive,
eSix,
eSeven,
eEight,
eNine
};
Digits_Write_Only& set_zero( char zero = 0x30 )
Digits_Write_Only& set_one( char one = 0x31 )
Digits_Write_Only& set_two( char two = 0x32 )
Digits_Write_Only& set_three( char three = 0x33 )
Digits_Write_Only& set_four( char four = 0x34 )
Digits_Write_Only& set_five( char five = 0x35 )
Digits_Write_Only& set_six( char six = 0x36 )
Digits_Write_Only& set_seven( char seven = 0x37 )
Digits_Write_Only& set_eight( char eight = 0x38 )
Digits_Write_Only& set_nine( char nine = 0x39 )

Surely you must be joking. This looks like something directly from
TheDailyWTF.
 
N

Nephi Immortal

On 16.02.2012 06:05, Nephi Immortal wrote:
[snip intro]




   I call it as Read / Write Object Design Pattern.  Please let me know
if my code looks neat.
class Digits_Read_Only;
class Digits_Write_Only
{
private:
   friend class Digits_Read_Only;
   enum EDigits
   {
           eZero,
           eOne,
           eTwo,
           eThree,
           eFour,
           eFive,
           eSix,
           eSeven,
           eEight,
           eNine
   };
   char data[ 10 ];
public:
   Digits_Write_Only()
   {
           set_zero();
           set_one();
           set_two();
           set_three();
           set_four();
           set_five();
           set_six();
           set_seven();
           set_eight();
           set_nine();
   }
   Digits_Write_Only&  set_zero( char zero = 0x30 )
   {
           data[ eZero ] = zero;
           return *this;
   }
   Digits_Write_Only&  set_one( char one = 0x31 )
   {
           data[ eOne ] = one;
           return *this;
   }
   Digits_Write_Only&  set_two( char two = 0x32 )
   {
           data[ eTwo ] = two;
           return *this;
   }
   Digits_Write_Only&  set_three( char three = 0x33 )
   {
           data[ eThree ] = three;
           return *this;
   }
   Digits_Write_Only&  set_four( char four = 0x34 )
   {
           data[ eFour ] = four;
           return *this;
   }
   Digits_Write_Only&  set_five( char five = 0x35 )
   {
           data[ eFive ] = five;
           return *this;
   }
   Digits_Write_Only&  set_six( char six = 0x36 )
   {
           data[ eSix ] = six;
           return *this;
   }
   Digits_Write_Only&  set_seven( char seven = 0x37 )
   {
           data[ eSeven ] = seven;
           return *this;
   }
   Digits_Write_Only&  set_eight( char eight = 0x38 )
   {
           data[ eEight ] = eight;
           return *this;
   }
   Digits_Write_Only&  set_nine( char nine = 0x39 )
   {
           data[ eNine ] = nine;
           return *this;
   }
};
class Digits_Read_Only
{
private:
   const Digits_Write_Only&  _digits;
public:
   Digits_Read_Only( const Digits_Write_Only&  digits ) :
_digits( digits )
   {
   }
   char get_zero() const
   {
           return _digits.data[ Digits_Write_Only::eZero ];
   }
   char get_one() const
   {
           return _digits.data[ Digits_Write_Only::eOne ];
   }
   char get_two() const
   {
           return _digits.data[ Digits_Write_Only::eTwo ];
   }
   char get_three() const
   {
           return _digits.data[ Digits_Write_Only::eThree ];
   }
   char get_four() const
   {
           return _digits.data[ Digits_Write_Only::eFour ];
   }
   char get_five() const
   {
           return _digits.data[ Digits_Write_Only::eFive ];
   }
   char get_six() const
   {
           return _digits.data[ Digits_Write_Only::eSix ];
   }
   char get_seven() const
   {
           return _digits.data[ Digits_Write_Only::eSeven ];
   }
   char get_eight() const
   {
           return _digits.data[ Digits_Write_Only::eEight ];
   }
   char get_nine() const
   {
           return _digits.data[ Digits_Write_Only::eNine ];
   }
   char operator[]( int index ) const
   {
           if( Digits_Write_Only::eZero<= index&&  index<=
Digits_Write_Only::eNine )
                   return _digits.data[ index ];
           else
                   return 0xFF; // invalid index
   }
   int begin() const
   {
           return Digits_Write_Only::eZero;
   }
   int end() const
   {
           return Digits_Write_Only::eNine;
   }

Digits_Write_Only initialize_digits;
const Digits_Read_Only digits( initialize_digits );
const char rgDigits[ 10 ] =
{
   0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9
};
int main()
{
   char data[ 10 ];
   for( int i = digits.begin() ; i<= digits.end(); ++i )
           data[ i ] = digits[ i ];
   for( int i = 0; i<= 9; ++i )
           data[ i ] = rgDigits[ i ];
   return 0;

Regarding whether your code looks "neat", well it isn't untidy, but on
the other hand "neat" is associated with an elegant or surprisingly
simple solution of something.

And I can't see that your code solves any problem?

Why not? Please provide me parameter object pattern design example
code.
 
N

Nephi Immortal

On 16.02.2012 06:05, Nephi Immortal wrote:
[snip intro]
    I call it as Read / Write Object Design Pattern.  Please let me know
if my code looks neat.
class Digits_Read_Only;
class Digits_Write_Only
{
private:
    friend class Digits_Read_Only;
    enum EDigits
    {
            eZero,
            eOne,
            eTwo,
            eThree,
            eFour,
            eFive,
            eSix,
            eSeven,
            eEight,
            eNine
    };
    char data[ 10 ];
public:
    Digits_Write_Only()
    {
            set_zero();
            set_one();
            set_two();
            set_three();
            set_four();
            set_five();
            set_six();
            set_seven();
            set_eight();
            set_nine();
    }
    Digits_Write_Only&    set_zero( char zero = 0x30 )
    {
            data[ eZero ] = zero;
            return *this;
    }
    Digits_Write_Only&    set_one( char one = 0x31 )
    {
            data[ eOne ] = one;
            return *this;
    }
    Digits_Write_Only&    set_two( char two = 0x32 )
    {
            data[ eTwo ] = two;
            return *this;
    }
    Digits_Write_Only&    set_three( char three = 0x33 )
    {
            data[ eThree ] = three;
            return *this;
    }
    Digits_Write_Only&    set_four( char four = 0x34 )
    {
            data[ eFour ] = four;
            return *this;
    }
    Digits_Write_Only&    set_five( char five = 0x35 )
    {
            data[ eFive ] = five;
            return *this;
    }
    Digits_Write_Only&    set_six( char six = 0x36 )
    {
            data[ eSix ] = six;
            return *this;
    }
    Digits_Write_Only&    set_seven( char seven = 0x37 )
    {
            data[ eSeven ] = seven;
            return *this;
    }
    Digits_Write_Only&    set_eight( char eight = 0x38 )
    {
            data[ eEight ] = eight;
            return *this;
    }
    Digits_Write_Only&    set_nine( char nine = 0x39 )
    {
            data[ eNine ] = nine;
            return *this;
    }
};
class Digits_Read_Only
{
private:
    const Digits_Write_Only&    _digits;
public:
    Digits_Read_Only( const Digits_Write_Only&    digits ) :
_digits( digits )
    {
    }
    char get_zero() const
    {
            return _digits.data[ Digits_Write_Only::eZero];
    }
    char get_one() const
    {
            return _digits.data[ Digits_Write_Only::eOne ];
    }
    char get_two() const
    {
            return _digits.data[ Digits_Write_Only::eTwo ];
    }
    char get_three() const
    {
            return _digits.data[ Digits_Write_Only::eThree ];
    }
    char get_four() const
    {
            return _digits.data[ Digits_Write_Only::eFour];
    }
    char get_five() const
    {
            return _digits.data[ Digits_Write_Only::eFive];
    }
    char get_six() const
    {
            return _digits.data[ Digits_Write_Only::eSix ];
    }
    char get_seven() const
    {
            return _digits.data[ Digits_Write_Only::eSeven ];
    }
    char get_eight() const
    {
            return _digits.data[ Digits_Write_Only::eEight ];
    }
    char get_nine() const
    {
            return _digits.data[ Digits_Write_Only::eNine];
    }
    char operator[]( int index ) const
    {
            if( Digits_Write_Only::eZero<= index&&    index<=
Digits_Write_Only::eNine )
                    return _digits.data[ index ];
            else
                    return 0xFF; // invalid index
    }
    int begin() const
    {
            return Digits_Write_Only::eZero;
    }
    int end() const
    {
            return Digits_Write_Only::eNine;
    }
};
Digits_Write_Only initialize_digits;
const Digits_Read_Only digits( initialize_digits );
const char rgDigits[ 10 ] =
{
    0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9
};
int main()
{
    char data[ 10 ];
    for( int i = digits.begin() ; i<= digits.end(); ++i )
            data[ i ] = digits[ i ];
    for( int i = 0; i<= 9; ++i )
            data[ i ] = rgDigits[ i ];
    return 0;
}
Regarding whether your code looks "neat", well it isn't untidy, but on
the other hand "neat" is associated with an elegant or surprisingly
simple solution of something.
And I can't see that your code solves any problem?
Why not?  Please provide me parameter object pattern design example
code.

I cannot see the point of trying to split a class into two "write only"
and "read only" classes.  Read about physical/logical constness and the
mutable keyword.

Also this is a solution without a problem: you could I think achieve
your goal but just using ordinary arrays.



I am trying to create parameter objects rather than arrays. Putting
information into arrays are so confusing because sometimes, you put
information into the wrong elements. Attempting to locate element and
correct errors will take couple hours unless you have huge arrays.

Compare three class variables and three array variables.

const Individual_Digit english_numbers[ 10 ];
const Individual_Digit arabic_numbers[ 10 ];
const Individual_Digit hebrew_numbers[ 10 ];

vs

const wchar_t g_english_numbers[ 10 ];
const wchar_t g_arabic_numbers[ 10 ];
const wchar_t g_hebrew_numbers[ 10 ];

I believe that Individual_Digit class is very readable. Also, take a
look at my code below. Please let me know if it looks good.

class Individual_Digit
{
public:
Individual_Digit() {}
Individual_Digit( wchar_t digit ) : data( digit ) {}

wchar_t get() const
{
return data;
}

Individual_Digit& set( wchar_t value )
{
data = value;
return *this;
}

private:
wchar_t data;
};

class Digit_Zero : public Individual_Digit
{
public:
Digit_Zero( wchar_t digit_zero = L'0' ) :
Individual_Digit( digit_zero )
{
}
};

class Digit_One : public Individual_Digit
{
public:
Digit_One( wchar_t digit_one = L'1' ) : Individual_Digit( digit_one )
{
}
};

class Digit_Two : public Individual_Digit
{
public:
Digit_Two( wchar_t digit_two = L'2' ) : Individual_Digit( digit_two )
{
}
};

class Digit_Three : public Individual_Digit
{
public:
Digit_Three( wchar_t digit_three = L'3' ) :
Individual_Digit( digit_three )
{
}
};

class Digit_Four : public Individual_Digit
{
public:
Digit_Four( wchar_t digit_four = L'4' ) :
Individual_Digit( digit_four )
{
}
};

class Digit_Five : public Individual_Digit
{
public:
Digit_Five( wchar_t digit_five = L'5' ) :
Individual_Digit( digit_five )
{
}
};

class Digit_Six : public Individual_Digit
{
public:
Digit_Six( wchar_t digit_six = L'6' ) : Individual_Digit( digit_six )
{
}
};

class Digit_Seven : public Individual_Digit
{
public:
Digit_Seven( wchar_t digit_seven = L'7' ) :
Individual_Digit( digit_seven )
{
}
};

class Digit_Eight : public Individual_Digit
{
public:
Digit_Eight( wchar_t digit_eight = L'8' ) :
Individual_Digit( digit_eight )
{
}
};

class Digit_Nine : public Individual_Digit
{
public:
Digit_Nine( wchar_t digit_nine = L'9' ) :
Individual_Digit( digit_nine )
{
}
};

class Number
{
private:
enum EDigits
{
eZero,
eOne,
eTwo,
eThree,
eFour,
eFive,
eSix,
eSeven,
eEight,
eNine
};

Individual_Digit _digits[ 10 ];

public:
Number( const Individual_Digit* digits )
{
for( int i = eZero; i <= eNine; ++i )
_digits[ i ].set( digits[ i ].get() );
}

wchar_t get_zero() const
{
return _digits[ eZero ].get();
}

wchar_t get_one() const
{
return _digits[ eOne ].get();
}

wchar_t get_two() const
{
return _digits[ eTwo ].get();
}

wchar_t get_three() const
{
return _digits[ eThree ].get();
}

wchar_t get_four() const
{
return _digits[ eFour ].get();
}

wchar_t get_five() const
{
return _digits[ eFive ].get();
}

wchar_t get_six() const
{
return _digits[ eSix ].get();
}

wchar_t get_seven() const
{
return _digits[ eSeven ].get();
}

wchar_t get_eight() const
{
return _digits[ eEight ].get();
}

wchar_t get_nine() const
{
return _digits[ eNine ].get();
}

wchar_t operator[]( int index ) const
{
if( eZero <= index && index <= eNine )
return _digits[ index ].get();
else
return 0xFFFF; // invalid index
}

int begin() const
{
return eZero;
}

int end() const
{
return eNine;
}

};

// Very readable objects
const Individual_Digit english_numbers[ 10 ] =
{
Digit_Zero(),
Digit_One(),
Digit_Two(),
Digit_Three(),
Digit_Four(),
Digit_Five(),
Digit_Six(),
Digit_Seven(),
Digit_Eight(),
Digit_Nine()
};

const Individual_Digit arabic_numbers[ 10 ] =
{
Digit_Zero( 0x4800 ),
Digit_One ( 0x4801 ),
Digit_Two ( 0x4802 ),
Digit_Three( 0x4803 ),
Digit_Four( 0x4804 ),
Digit_Five( 0x4805 ),
Digit_Six ( 0x4806 ),
Digit_Seven( 0x4807 ),
Digit_Eight( 0x4808 ),
Digit_Nine( 0x4809 )
};

const Individual_Digit hebrew_numbers[ 10 ] =
{
Digit_Zero( 0x6200 ),
Digit_One ( 0x6201 ),
Digit_Two ( 0x6202 ),
Digit_Three( 0x6203 ),
Digit_Four( 0x6204 ),
Digit_Five( 0x6205 ),
Digit_Six ( 0x6206 ),
Digit_Seven( 0x6207 ),
Digit_Eight( 0x6208 ),
Digit_Nine( 0x6209 )
};

// Very unreadable arrays
const wchar_t g_english_numbers[ 10 ] =
{
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'
};

const wchar_t g_arabic_numbers[ 10 ] =
{
0x4800, 0x4801, 0x4802, 0x4803, 0x4804,
0x4805, 0x4806, 0x4807, 0x4808,0x4809
};

const wchar_t g_hebrew_numbers[ 10 ] =
{
0x6200, 0x6201, 0x6202, 0x6203, 0x6204,
0x6205, 0x6206, 0x6207, 0x6208,0x6209
};



int main()
{
wchar_t data[ 3 ][ 10 ];

Number group_of_digits[ 3 ] =
{
Number( english_numbers ),
Number( arabic_numbers ),
Number( hebrew_numbers )
};

const wchar_t* all_numbers[ 3 ] =
{
g_english_numbers,
g_arabic_numbers,
g_hebrew_numbers
};

for( int j = 0; j < 3; ++j )
{
for( int i = group_of_digits[ j ].begin() ; i <=
group_of_digits[ j ].end(); ++i )
data[ j ][ i ] = group_of_digits[ j ][ i ];
}

for( int j = 0; j < 3; ++j )
{
for( int i = group_of_digits[ j ].begin() ; i <=
group_of_digits[ j ].end(); ++i )
data[ j ][ i ] = all_numbers[ j ][ i ];
}

return 0;
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,071
Latest member
MetabolicSolutionsKeto

Latest Threads

Top