There are several distinct kinds of UML diagrams

advertisement
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
Download