N
Nephi Immortal
Last time, I posted the topic -- Read / Write Pattern Design. I did
a lot of research trying to find a good solution, but I could not find
anything except I found one website below:
http://en.wikipedia.org/wiki/Fluent_interface
It is called Fluent Pattern. It is the best solution I can use.
Looking at the website’s source code in C++. It does not make any
sense to me. How can mutable class using fluent pattern modify
immutable object?
I wrote my own code. It looks better now. I created Digits class.
It is read only such as constant. It has only getters and it does not
have any setters. It can either be mutable or immutable unless
Fluent_Digits class is a friend with Digits class.
Fluent_Digits has setters at construction-time only.
Please answer my question. Is const_cast safe to be used or will it
lead to undefined behavior? const is an optional, but it is not
necessary because Digits class does not have setters.
Please express your opinion what you think about my code and fluent
pattern.
class Digits
{
private:
enum
{
Digit_Zero,
Digit_One,
Digit_Two,
Digit_Three,
Digit_Four,
Digit_Five,
Digit_Six,
Digit_Seven,
Digit_Eight,
Digit_Nine
};
char digits[ 10 ];
public:
friend class Fluent_Digits;
Digits() {}
char Get_Digit_Zero() const { return digits[ Digit_Zero ]; }
char Get_Digit_One() const { return digits[ Digit_One ]; }
char Get_Digit_Two() const { return digits[ Digit_Two ]; }
char Get_Digit_Three() const { return digits[ Digit_Three ]; }
char Get_Digit_Four() const { return digits[ Digit_Four ]; }
char Get_Digit_Five() const { return digits[ Digit_Five ]; }
char Get_Digit_Six() const { return digits[ Digit_Six ]; }
char Get_Digit_Seven() const { return digits[ Digit_Seven ]; }
char Get_Digit_Eight() const { return digits[ Digit_Eight ]; }
char Get_Digit_Nine() const { return digits[ Digit_Nine ]; }
int Begin() const { return 0; }
int End() const { return 9; }
char operator[]( int index ) const
{
if( 0 <= index && index <= 9 )
return digits[ index ];
else
return 0xFF; // Invalid
}
};
class Fluent_Digits
{
private:
Digits& _digits;
public:
Fluent_Digits( const Digits& digits )
: _digits( const_cast< Digits& >( digits ))
{
}
Fluent_Digits& with_Digit_Zero( char digit_zero = '0' )
{
_digits.digits[ _digits.Digit_Zero ] = digit_zero;
return *this;
}
Fluent_Digits& with_Digit_One( char digit_one = '1' )
{
_digits.digits[ _digits.Digit_One ] = digit_one;
return *this;
}
Fluent_Digits& with_Digit_Two( char digit_two = '2' )
{
_digits.digits[ _digits.Digit_Two ] = digit_two;
return *this;
}
Fluent_Digits& with_Digit_Three( char digit_three = '3' )
{
_digits.digits[ _digits.Digit_Three ] = digit_three;
return *this;
}
Fluent_Digits& with_Digit_Four( char digit_four = '4' )
{
_digits.digits[ _digits.Digit_Four ] = digit_four;
return *this;
}
Fluent_Digits& with_Digit_Five( char digit_five = '5' )
{
_digits.digits[ _digits.Digit_Five ] = digit_five;
return *this;
}
Fluent_Digits& with_Digit_Six( char digit_six = '6' )
{
_digits.digits[ _digits.Digit_Six ] = digit_six;
return *this;
}
Fluent_Digits& with_Digit_Seven( char digit_seven = '7' )
{
_digits.digits[ _digits.Digit_Seven ] = digit_seven;
return *this;
}
Fluent_Digits& with_Digit_Eight( char digit_eight = '8' )
{
_digits.digits[ _digits.Digit_Eight ] = digit_eight;
return *this;
}
Fluent_Digits& with_Digit_Nine( char digit_nine = '9' )
{
_digits.digits[ _digits.Digit_Nine ] = digit_nine;
return *this;
}
void Create()
{
// Nothing
}
};
int main()
{
const Digits digits_english;
const Digits digits_other;
Fluent_Digits( digits_english )
.with_Digit_Zero ()
.with_Digit_One ()
.with_Digit_Two ()
.with_Digit_Three()
.with_Digit_Four ()
.with_Digit_Five ()
.with_Digit_Six ()
.with_Digit_Seven()
.with_Digit_Eight()
.with_Digit_Nine ()
.Create();
Fluent_Digits( digits_other )
.with_Digit_Zero ( 0xB0 )
.with_Digit_One ( 0xB1 )
.with_Digit_Two ( 0xB2 )
.with_Digit_Three( 0xB3 )
.with_Digit_Four ( 0xB4 )
.with_Digit_Five ( 0xB5 )
.with_Digit_Six ( 0xB6 )
.with_Digit_Seven( 0xB7 )
.with_Digit_Eight( 0xB8 )
.with_Digit_Nine ( 0xB9 )
.Create();
for( int i = digits_english.Begin(); i <= digits_english.End(); ++i )
cout << digits_english[ i ] << " ";
cout << endl;
for( int i = digits_other.Begin(); i <= digits_other.End(); ++i )
cout << digits_other[ i ] << " ";
cout << endl;
return 0;
}
a lot of research trying to find a good solution, but I could not find
anything except I found one website below:
http://en.wikipedia.org/wiki/Fluent_interface
It is called Fluent Pattern. It is the best solution I can use.
Looking at the website’s source code in C++. It does not make any
sense to me. How can mutable class using fluent pattern modify
immutable object?
I wrote my own code. It looks better now. I created Digits class.
It is read only such as constant. It has only getters and it does not
have any setters. It can either be mutable or immutable unless
Fluent_Digits class is a friend with Digits class.
Fluent_Digits has setters at construction-time only.
Please answer my question. Is const_cast safe to be used or will it
lead to undefined behavior? const is an optional, but it is not
necessary because Digits class does not have setters.
Please express your opinion what you think about my code and fluent
pattern.
class Digits
{
private:
enum
{
Digit_Zero,
Digit_One,
Digit_Two,
Digit_Three,
Digit_Four,
Digit_Five,
Digit_Six,
Digit_Seven,
Digit_Eight,
Digit_Nine
};
char digits[ 10 ];
public:
friend class Fluent_Digits;
Digits() {}
char Get_Digit_Zero() const { return digits[ Digit_Zero ]; }
char Get_Digit_One() const { return digits[ Digit_One ]; }
char Get_Digit_Two() const { return digits[ Digit_Two ]; }
char Get_Digit_Three() const { return digits[ Digit_Three ]; }
char Get_Digit_Four() const { return digits[ Digit_Four ]; }
char Get_Digit_Five() const { return digits[ Digit_Five ]; }
char Get_Digit_Six() const { return digits[ Digit_Six ]; }
char Get_Digit_Seven() const { return digits[ Digit_Seven ]; }
char Get_Digit_Eight() const { return digits[ Digit_Eight ]; }
char Get_Digit_Nine() const { return digits[ Digit_Nine ]; }
int Begin() const { return 0; }
int End() const { return 9; }
char operator[]( int index ) const
{
if( 0 <= index && index <= 9 )
return digits[ index ];
else
return 0xFF; // Invalid
}
};
class Fluent_Digits
{
private:
Digits& _digits;
public:
Fluent_Digits( const Digits& digits )
: _digits( const_cast< Digits& >( digits ))
{
}
Fluent_Digits& with_Digit_Zero( char digit_zero = '0' )
{
_digits.digits[ _digits.Digit_Zero ] = digit_zero;
return *this;
}
Fluent_Digits& with_Digit_One( char digit_one = '1' )
{
_digits.digits[ _digits.Digit_One ] = digit_one;
return *this;
}
Fluent_Digits& with_Digit_Two( char digit_two = '2' )
{
_digits.digits[ _digits.Digit_Two ] = digit_two;
return *this;
}
Fluent_Digits& with_Digit_Three( char digit_three = '3' )
{
_digits.digits[ _digits.Digit_Three ] = digit_three;
return *this;
}
Fluent_Digits& with_Digit_Four( char digit_four = '4' )
{
_digits.digits[ _digits.Digit_Four ] = digit_four;
return *this;
}
Fluent_Digits& with_Digit_Five( char digit_five = '5' )
{
_digits.digits[ _digits.Digit_Five ] = digit_five;
return *this;
}
Fluent_Digits& with_Digit_Six( char digit_six = '6' )
{
_digits.digits[ _digits.Digit_Six ] = digit_six;
return *this;
}
Fluent_Digits& with_Digit_Seven( char digit_seven = '7' )
{
_digits.digits[ _digits.Digit_Seven ] = digit_seven;
return *this;
}
Fluent_Digits& with_Digit_Eight( char digit_eight = '8' )
{
_digits.digits[ _digits.Digit_Eight ] = digit_eight;
return *this;
}
Fluent_Digits& with_Digit_Nine( char digit_nine = '9' )
{
_digits.digits[ _digits.Digit_Nine ] = digit_nine;
return *this;
}
void Create()
{
// Nothing
}
};
int main()
{
const Digits digits_english;
const Digits digits_other;
Fluent_Digits( digits_english )
.with_Digit_Zero ()
.with_Digit_One ()
.with_Digit_Two ()
.with_Digit_Three()
.with_Digit_Four ()
.with_Digit_Five ()
.with_Digit_Six ()
.with_Digit_Seven()
.with_Digit_Eight()
.with_Digit_Nine ()
.Create();
Fluent_Digits( digits_other )
.with_Digit_Zero ( 0xB0 )
.with_Digit_One ( 0xB1 )
.with_Digit_Two ( 0xB2 )
.with_Digit_Three( 0xB3 )
.with_Digit_Four ( 0xB4 )
.with_Digit_Five ( 0xB5 )
.with_Digit_Six ( 0xB6 )
.with_Digit_Seven( 0xB7 )
.with_Digit_Eight( 0xB8 )
.with_Digit_Nine ( 0xB9 )
.Create();
for( int i = digits_english.Begin(); i <= digits_english.End(); ++i )
cout << digits_english[ i ] << " ";
cout << endl;
for( int i = digits_other.Begin(); i <= digits_other.End(); ++i )
cout << digits_other[ i ] << " ";
cout << endl;
return 0;
}