-------------------------------------------------------------------------- Object-oriented Design Winter 1994 COM 1204 --------------------------------------------------------------------------- Midterm QUESTION 1: 8 UNKNOWNs, 2 points each: 16 QUESTION 2: 27 UNKNOWNs, 1 point each: 27 QUESTION 3: 6 UNKNOWNs, 5 points each: 30 QUESTION 4: 9 UNKNOWNs, 4 points each: 36 QUESTION 5: 6 UNKNOWNs, 4 points each: 24 --------------------------------------------------------------------------- Open book and open notes. To make the grading easier, please put your values for the unknowns on the enclosed answer sheet. THE GAME OF REDUNDANCY AND UNKNOWNS ----------------------------------- Most of the questions in this exam ask you to determine unknowns of the form UNKNOWN1, UNKNOWN2, ... This makes it easier for you to answer the questions, since you get extra context information. Yet you need to master the behavioral objectives of the course to answer the questions. Guessing an answer is not a successful strategy and therefore a "game of redundancy" test is more interesting than a multiple choice test. The questions have the following pattern: I show you several artifacts which are related by the theory of object-oriented design and programming. Because of the dependencies between the artifacts, some of the information is redundant and can be recovered from the context by applying the objectives covered in the course. The information which you should discover is marked UNKNOWNx. If an unknown is not uniquely determined, mark the answer with *CHOICE*. An unknown may be anything, e.g., a number, an identifier, a character, two identifiers with a blank between them, a string etc. If an unknown is the empty string, give NOTHING as answer, e.g., UNKNOWN = NOTHING. Example: 5 + UNKNOWN1 = 8 UNKNOWN1 = 3 --------------- UNKNOWN2 * UNKNOWN3 = 20 UNKNOWN2 = 4 *CHOICE* UNKNOWN3 = 5 *CHOICE* At the beginning of a question we give the number of points per unknown. Question 1: ============================================================================== 2 points per unknown. Below is a class dictionary and the corresponding C++ class interface. Find the unknowns. Class dictionary: A = UNKNOWN2. B : C | D | A *common* W. W ~ {DemIdent}. C = . D = . C++ class declarations: class B : public Construction { private: W* w; static const char* type; public: B( W* = UNKNOWN3 ); W* get_w() const { UNKNOWN4 } void set_w( W* new_w ) { UNKNOWN5 } W* rset_w( W* ); const char* get_type() const { return( type ); } #include "B.h" }; class A : public UNKNOWN6 { private: B* b; static const char* type; public: A( B* = NULL ); B* get_b() const { return( b ); } void set_b( B* new_b ) { b = new_b; } B* rset_b( B* ); const char* get_type() const { return( type ); } #include "A.h" }; typedef DemIdent* DemIdent_; declare(list,DemIdent_); class W : public DemIdent_list_ { private: static const char* type; public: W( DemIdent* first ) : DemIdent_list_( first ) { /* empty */ }; W() { /* empty */ }; const char* get_type() const { return ( type ); } #include "W.h" }; class C : public UNKNOWN7 { private: static const char* type; public: C(); const char* get_type() const { return( type ); } #include "C.h" }; class D : public UNKNOWN8 { private: static const char* type; public: D(); const char* get_type() const { return( type ); } #include "D.h" }; Question 2: ============================================================================== 1 point per unknown. This question is about objects which are legal with respect to a class dictionary. Find the unknowns below. Class dictionary (for all of question 2): A = B. B : C | D | A *common* W. W ~ {DemIdent} . C = . D = . Question 2.1: Consider the following three legal A-objects a1, a2, a3. Find the unknowns. A-object a1: : A ( < UNKNOWN1 > : C ( < w > : UNKNOWN2 { } ) < UNKNOWN3 > : UNKNOWN4 { } ) A-object a2: : A ( < b > : UNKNOWN5 ( < b > : UNKNOWN6 ( < b > : C ( < w > : UNKNOWN7 { } ) < w > : UNKNOWN8 { } ) < w > : UNKNOWN9 { } ) < w > : UNKNOWN10 { } ) A-object a3: : A ( < b > : A ( < b > : D ( < w > : W { : UNKNOWN11 "x" } ) < UNKNOWN12 > : UNKNOWN13 { : UNKNOWN14 "x" , : UNKNOWN15 "y" , : UNKNOWN16 "z" } ) < w > : W { : UNKNOWN17 "z" } ) } ) Question 2.2: For the following A-object, // : A ( // < b > : C ( // < w > : W { } ) // < w > : W { } ) , write C++ statements which create that object. Find the unknowns below. UNKNOWN18 c1 = UNKNOWN19 ; c1 -> UNKNOWN20(new UNKNOWN21()); UNKNOWN22 a1 = new UNKNOWN23 (c1); a1 -> UNKNOWN24(new W()); Question 2.3: Consider the following illegal objects. Find the first error as indicated. A-object i1: // give three answers in UNKNOWN25 The FIRST error is on line UNKNOWN25: replace letter UNKNOWN25 by UNKNOWN25 : A ( < b > : A ( < b > : D ( < b > : C ( < w > : W { } ) < w > : W { } ) < w > : V { } ) < v > : W { } ) A-object i2: The FIRST error is on line UNKNOWN26: UNKNOWN27 is missing. : A ( < b > : A ( < b > : D () < w > : W { : DemReal "x" , : DemReal "y" , : DemReal "z" } ) < w > : W { : DemReal "z" } ) } ) Question 3: =========================================================================== 5 points per unknown Below you get a propagation pattern and the corresponding C++ code for two distinct class dictionaries. From the C++ programs, derive the information in the propagation pattern. Propagation pattern: *operation* void UNKNOWN1() *traverse* UNKNOWN2 // make it as small as possible *wrapper* UNKNOWN3 *prefix* (@ cout << "in UNKNOWN4 " << endl; @) *wrapper* UNKNOWN5 *suffix* (@ cout << "after UNKNOWN6-traversal " << endl; @) class dictionary 1: A = B F. B = C F. C = D F. D = E. E = F. F = . and the corresponding C++ program: // A = B // F . void A::fun( ) { // outgoing calls this->get_b()->fun( ); // suffix class wrappers cout << "after A-traversal " << endl; } // B = C // F . void B::fun( ) { // outgoing calls this->get_c()->fun( ); } // C = D // F . void C::fun( ) { // outgoing calls this->get_d()->fun( ); } // D = E . void D::fun( ) { // outgoing calls this->get_e()->fun( ); } // E = F . void E::fun( ) { // outgoing calls this->get_f()->fun( ); } // F = . void F::fun( ) { // prefix class wrappers cout << "in F " << endl; } class dictionary 2: A = B1 F. B1 = C1. C1 = B. B = C F. C = D F. D = E1 F. E1 = F1. F1 = E. E = F. F = . and the corresponding C++ program // A = B1 // F . void A::fun( ) { // construction edge prefix wrappers this->get_b1()->fun( ); // suffix class wrappers cout << "after A-traversal " << endl; } // B1 = C1 . void B1::fun( ) { // outgoing calls this->get_c1()->fun( ); } // C1 = B . void C1::fun( ) { // outgoing calls this->get_b()->fun( ); } // B = C // F . void B::fun( ) { // construction edge prefix wrappers this->get_c()->fun( ); } // C = D // F . void C::fun( ) { // outgoing calls this->get_d()->fun( ); } // D = E1 // F . void D::fun( ) { // outgoing calls this->get_e1()->fun( ); this->get_f4()->fun( ); } // E1 = F1 . void E1::fun( ) { // outgoing calls this->get_f5()->fun( ); } // F1 = E . void F1::fun( ) { // outgoing calls this->get_e()->fun( ); } // E = F . void E::fun( ) { // outgoing calls this->get_f()->fun( ); } // F = . void F::fun( ) { // prefix class wrappers cout << "in F " << endl; } Question 4: ========================================================================== 4 points per unknown. Rewrite the following programs so that they satisfy the Law of Demeter. Question 4.1: ======================================================== // violating the Law of Demeter // A = P1. void A::f1(A* a, B* b) { this -> get_p1() -> get_p2() -> r(a,b); } // satisfying the Law of Demeter // A = P1. void A::f1(A* a, B* b) { this -> UNKNOWN1() -> UNKNOWN2(a,b); } // P1 = P2. void P1::f1(A* a, B* b) { this -> UNKNOWN3() -> UNKNOWN4(a,b); } ======================================================== Question 4.2: ======================================================== // violating the Law of Demeter // A = P1. void A::f1(A* a, B* b, C* c, D* d) { this -> get_p1() -> r(a,b) -> s(c,d); } // satisfying the Law of Demeter // A = P1. void A::f1(A* a, B* b, C* c, D* d) { this -> f1(UNKNOWN5 -> UNKNOWN6() -> UNKNOWN7(a,b), UNKNOWN8, UNKNOWN9); } // A = P1. void A::f1(R* r, C* c, D* d) { r -> s(c,d); } ======================================================== Question 5: ========================================================================== 4 points per unknown. Consider the following object description: primitives primitive a primitive b description (sew (turn (sew primitive a (turn primitive b))) primitive b) Find the unknowns in the following class dictionary so that the class dictionary can describe objects similar to the one above: // class dictionary Patchwork UNKNOWN1 PrimitiveExp_List UNKNOWN2. PatchworkExp UNKNOWN3. PrimitiveExp = DemIdent. TurnExp = UNKNOWN4 . SewExp = UNKNOWN5 UNKNOWN6 . PrimitiveExp_List ~ {PrimitiveExp}.