// Purpose. Strategy design pattern lab. // // Problem. Data entry validation is lumped in one function with a large // monolithic case statement. In a more sophisticated application there // might be multiple parallel case statements and the validation code // could easily become several pages in length. If new validation // requirements surface, the situation is exacerbated. // // Strategy. "Abtract out" the validation mechanism into its own class // hierarchy - interface in a base class, implementation in derived classes. // // Assignment. // o Create a Validation base class that can serve as an umbrella for the // three different validation requirements // o Move the interface of the validate() method to the Validation hierarchy // o Move each part of the "case" statement in validate() to its own derived // class // o In DataEntry, replace the "type" attribute and the validate() method // with a Validation* attribute // o Initialize the Validation* member, inside setValidationType() // o In interact(), delegate the validation to the Validation* member // o main() will stay the same #include #include int isdigit( char ch ) { return (ch >= '0' && ch <= '9') ? 1 : 0; } int isupper( char ch ) { return (ch >= 'A' && ch <= 'Z') ? 1 : 0; } int islower( char ch ) { return (ch >= 'a' && ch <= 'z') ? 1 : 0; } class DataEntry { public: void setValidationType( char ch ) { type = ch; } void interact(); private: char type; int validate( char* ); }; void DataEntry::interact() { char answer[20]; cout << "Prompt: "; cin >> answer; while (strcmp( answer, "quit" )) { if (validate( answer )) cout << "*** good ***" << endl; else cout << "*** bad ***" << endl; cout << "Prompt: "; cin >> answer; } } int DataEntry::validate( char* input ) { int valid; unsigned i; valid = 1; if (type == 'n') { for (i=0; i < strlen(input); i++) if ( ! isdigit( input[i] ) ) { valid = 0; break; } } else if (type == 'u') { for (i=0; i < strlen(input); i++) if ( ! isupper( input[i] ) ) { valid = 0; break; } } else if (type == 'l') { for (i=0; i < strlen(input); i++) if ( ! islower( input[i] ) ) { valid = 0; break; } } return valid; } void main( void ) { DataEntry dialog; char answer; cout << "Input type [ (n)umber, (u)pper, (l)ower, e(x)it ]: "; cin >> answer; while (answer != 'x') { dialog.setValidationType(answer); dialog.interact(); cout << "Input type [ (n)umber, (u)pper, (l)ower, e(x)it ]: "; cin >> answer; } } // Input type [ (n)umber, (u)pper, (l)ower, e(x)it ]: n // Prompt: sdf // *** bad *** // Prompt: 234 // *** good *** // Prompt: quit // Input type [ (n)umber, (u)pper, (l)ower, e(x)it ]: u // Prompt: sdf // *** bad *** // Prompt: 234 // *** bad *** // Prompt: GHJ // *** good *** // Prompt: quit // Input type [ (n)umber, (u)pper, (l)ower, e(x)it ]: x