There are several distinct kinds of UML diagrams... Typical UML class diagram, see notes from "Strategy Pattern coded in Java" classes depicted by rectangle boxes class name in 1/3 of box member names & types shown in 1/3 of box member fn & signature shown in 1/3 of box not too different from Gang of Four book Small programs for drawing UML class diagrams: Dia: http://www.lysator.liu.se/~alla/dia/ ArgoUML: http://argouml.tigris.org/ Big program: Together J or Together C++: http://www.togethersoft.com/ -Requires 128MB RAM and an academic license 'key' file from the course instructor Let's consider a collection ('Aggregation') class diagram (connecting lines have open diamonds) Sample diagram ('Fundamentals' page 128) Question: What do the connecting lines mean at the implementation level? Answer: the aggregating class has data members that are objects of the pointed-to class, or the aggregating class has pointers to objects of the pointed-to class, or the aggregating class has a data member that is a port connection to objects of the pointed-to class, etc. ...the diagram looks the same in any case Programming example: an aggregation can have an array of Strings, or an array of pointers to Strings, but the diagram is unaffected Other kinds of UML diagrams: Collaboration diagram--good for modeling the 'participants' Object-interaction diagram--excellent for modeling multi-stage transactions State transition diagram--indispensable when modeling state-based systems Collaboration diagrams ('Fundamentals' Chapter 5) sample on p. 138 "Why use a square-cornerned box for objects (not classes)?" what about multiple messages? setValue, getValue, etc. (clutters the diagram without adding much value) what about polymorphism among classes? Section 5.1.2 what about timing or sequencing? perhaps less useful than class, interaction, state transition diagrams Object-interaction diagrams (Sample: page 147) very useful to SW engineers, especially in real-time systems includes time component clearly separates different message kinds between the same two objects objects shown instead of classes; gives 'run-time flavor' State transition diagrams (Sample: page 168) for some systems, absolutely required for comprehensible design helps identify faulty logic or unanticipated member data values can be nested to capture recursive complexity (page 170) Ultimately, every system created with OO Design is state-based. (Why?) But this doesn't mean that we diagram all such systems this way. We usually produce state transition diagrams when a real-world system is state-based. Examples of this: machinery driven by embedded software (traffic signal, safety device, robotics), manufacturing processes (factory, refinery, industrial kitchen), complex financial transactions (insurance, banking, trading) Big 3 implementation SE 455-96-102 Week 3 Page 1 2/16/2016 "Every class that contains a handle implemented as a pointer should contain a destructor, a copy constructor, and an overloaded assignment operator." -from 'C++ Strategies and Tactics' by Robert B. Murray, Addison-Wesley class String { private: char* rep; public: String(const char* = ""); ~String(); // destructor String(const String&); // copy constructor const String& operator=(const String&); // overloaded assignment operator }; String::String(const char* c): rep(new char[strlen(c)+1]){ strcpy(rep,c); } String::~String() { delete [] rep; } String::String(const String& s): rep(new char[strlen(s.rep)+1]) { strcpy(rep, s.rep); } const String& String::operator=(const String& s) { if (rep != s.rep) { delete [] rep; rep = new char[strlen(s.rep)+1]; strcpy(rep,s.rep); } // assignment operators should return a const reference to the assigned-to object. // this prevents an assignment from being used as an l-value. [e.g. '(a=b)=c;'] return *this; } In the overloaded assignment operator, what does the 'if' test guard against? Why does the assignment operator have a 'delete' call? What effect does the use of pointers have on the execution stack at runtime? Individual String objects can have different numbers of characters, but sizeof(String) is always the same size--how is this possible? SE 455-96-102 Week 3 Page 2 2/16/2016 /* C++ Compiler Problem: StackIterator must know about MyStack, and MyStack must know about StackIterator. We can put both in the same header file to avoid compiler recursion failure. What else must we do here? */ #include <iostream> using namespace std; class MyStack; // this 'forward declaration' is needed here. class Iterator { public: virtual void First() = 0; virtual void Next() = 0; virtual bool IsDone() const = 0; virtual int CurrentItem() const =0; protected: Iterator(); }; class StackIterator: public Iterator { public: StackIterator(const MyStack* astack):_stack(astack), _current(-2){} // compile error would have occured on next line---Why? virtual void First() {_current = _stack->top;} SE 455-96-102 Week 3 Page 3 2/16/2016 virtual void Next() {_current--;} virtual bool IsDone() const {return (_current==-1);} virtual int CurrentItem() const {return _stack->a[_current];} private: const MyStack* _stack; int _current; }; class MyStack { public: StackIterator* CreateIterator() const { return new StackIterator(this); } MyStack(): max(100){ count = 0; top = -1; a = new int[max]; } MyStack(int SIZE):max(SIZE){ count = 0; top = -1; a = new int[max]; } bool IsFull() const; bool IsEmpty() const; int Count() const { return count;} //added void Remove(int); SE 455-96-102 Week 3 Page 4 2/16/2016 void Append(int); int Top() const; ~MyStack() {delete[] a;} friend class StackItertor; private: int* a; int top; int max; int count; }; // MyStack method definitions should appear before StackIterator definitions. // StackIterator definitions should appear last. Reading for Background (Chapters 5 & 6 in the "Fundamentals" Text expand on the Collaboration, Object-interaction, and sequence diagrams.) SE 455-96-102 Week 3 Page 5 2/16/2016