// Purpose. Bridge - before // // Discussion. Even though Date has // a clean interface and a well encap- // sulated implementation, the client // still has to recompile if the class // architect changes his/her mind. // Instead, create a wrapper (or inter // face) class that contains and dele- // gates to a body (or implementation) // class. Client can now specify at // run-time exactly what s/he wants. #include #include using std::cout; using std::endl; class Date { public: Date( int y, int m, int d ); void output(); private: #ifdef OK int year_, month_, day_; #endif #ifdef AA int toJulian(int,int,int); char* fromJulian(void); int julian_; int year_; #endif }; void main( void ) { Date d1( 1996, 2, 29 ); Date d2( 1996, 2, 30 ); d1.output(); d2.output(); cout << endl; } /////// OK ////// // 960229 960230 /////// AA ////// // 960229 960301 #ifdef OK Date::Date( int y, int m, int d ) { year_ = y; month_ = m; day_ = d; } void Date::output() { char buf[20]; int year = year_ - (year_/100*100); sprintf( buf, "%02d%02d%02d", year, month_, day_ ); cout << buf << " "; } #endif #ifdef AA Date::Date( int y, int m, int d ) { year_ = y; julian_ = toJulian( y, m, d ); } void Date::output() { cout << fromJulian() << " "; } int Date::toJulian( int year, int month, int day ) { static int dayTable_[2][13] = { {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} }; int i, leap; leap = year % 4 == 0 && year % 100 != 0 || year % 400 == 0; for (i=1; i < month; i++) day += dayTable_[leap][i]; return( day ); } char* Date::fromJulian( void ) { static int dayTable_[2][13] = { {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} }; int i, leap, year, month, day, jul = julian_; static char buf[20]; leap = year_ % 4 == 0 && year_ % 100 != 0 || year_ % 400 == 0; for (i=1; jul > dayTable_[leap][i]; i++) jul -= dayTable_[leap][i]; year = year_ - (year_/100 * 100); month = i; day = jul; sprintf( buf, "%02d%02d%02d", year, month, day ); return buf; } #endif #if 0 // Purpose. Bridge - after #include #include #include using std::cout; using std::endl; class DateImp; class Date { public: Date( int y, int m, int d ); ~Date(); void output(); static void setImp( char* t ) { strcpy( impType_, t ); } private: DateImp* rep_; static char impType_[10]; }; char Date::impType_[] = "Ok"; class DateImp { public: virtual void output() = 0; }; class DateOk : public DateImp { public: DateOk( int y, int m, int d ); void output(); private: int year_, month_, day_; }; class DateAA : public DateImp { public: DateAA( int y, int m, int d ); void output(); private: int toJulian(int,int,int); char* fromJulian(void); int julian_; int year_; }; void main( void ) { Date d1( 1996, 2, 29 ); Date d2( 1996, 2, 30 ); Date::setImp( "AA" ); Date d3( 1996, 2, 29 ); Date d4( 1996, 2, 30 ); d1.output(); d2.output(); cout << endl; d3.output(); d4.output(); cout << endl; } // 960229 960230 // 960229 960301 Date::Date( int y, int m, int d ) { if ( ! strcmp( impType_, "Ok" )) rep_ = new DateOk( y, m, d ); else rep_ = new DateAA( y, m, d ); } Date::~Date() { delete rep_; } void Date::output() { rep_->output(); } DateOk::DateOk( int y, int m, int d ) { year_ = y; month_ = m; day_ = d; } void DateOk::output() { char buf[20]; int year = year_ - (year_/100*100); sprintf( buf, "%02d%02d%02d", year, month_, day_ ); cout << buf << " "; } DateAA::DateAA( int y, int m, int d ) { year_ = y; julian_ = toJulian( y, m, d ); } void DateAA::output() { cout << fromJulian() << " "; } int DateAA::toJulian( int year, int month, int day ) { static int dayTable_[2][13] = { {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} }; int i, leap; leap = year % 4 == 0 && year % 100 != 0 || year % 400 == 0; for (i=1; i < month; i++) day += dayTable_[leap][i]; return( day ); } char* DateAA::fromJulian( void ) { static int dayTable_[2][13] = { {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}, {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31} }; int i, leap, year, month, day, jul = julian_; static char buf[20]; leap = year_ % 4 == 0 && year_ % 100 != 0 || year_ % 400 == 0; for (i=1; jul > dayTable_[leap][i]; i++) jul -= dayTable_[leap][i]; year = year_ - (year_/100 * 100); month = i; day = jul; sprintf( buf, "%02d%02d%02d", year, month, day ); return buf; } #endif