Find some old "procedural" code you have written and rewrite in an object-oriented fashion. I don't mean that you have to use inheritance or polymorphism; all I am really looking for is that you wrap some functions up in a sensible class.
Constrast statechart and activity diagrams in terms of the computational aspects they emphasis, and the kinds of systems that each can best represent.
Add two classes, Polygon and DrawablePolygon, to the figures package in the Example Programs of the courseware distribution. Remember, you need not, indeed must not, modify any of the existing source code files in any way!
Construct detailed class diagrams for the figures package in the Example Programs distribution.
Write a three page paper on the nature of identity in object oriented philosophy. Include some code fragments to illustrate your main points.
Make a list of 20 "dos and don'ts" for finding (discovering) classes.
Although GoF's Design Patterns is a famous book, the authors have not yet updated their text to use UML Diagrams. Instead they use OMT. For further practice with UML, "port" some of the diagrams from the text from OMT to UML. The diagrams you need to port are on pages 233, 335, 152, 141, and 87.
Make a UML State Diagram for a simple traffic light. It should switch from red to green when 10 cars back up at it or after 1 minute, whichever is earlier. It should also let all cars which were initially backed up at the red light when the light changed to green proceed through before turning to yellow, although it should not stay green for more than 30 seconds. If this description is ambiguous or unclear or unworkable, propose changes to the problem to make it make sense and write the corresponding state diagram for your improved requirements.
Design an ATM. Don't make it too trivial.
Make a statechart diagram for the typical digital wristwatch, that has two buttons, MODE and INC. MODE takes you from normal mode to time-setting mode. When you enter time-setting mode, you first see the hour display flashing, and INC increments the current value of the hour (the value is 0..23 and it wraps). MODE will next take you to where you can change minutes, then MODE again takes you to where you can adjust seconds, then back again to normal mode.
In Java, you generally implement "callbacks" via registration of listeners that implement a known interface, rather than using method pointers. Create a Swing component called AngleReader which displays a picture of a circle and notifies all its listeners of the angle, in degrees, that the mouse cursor makes with the horizontal axis of the circle as the mouse moves over it.
UML supports both action states and activity states. Can both appear in a statechart diagram? Can you always faithfully translate state charts to and from activity diagrams, or is one kind inherently more expressive than the other? Under what situations are activity diagrams more appropriate than statechart diagrams?
What is wrong with this?
class Rectangle {
protected double height, width;
// pretend that there are more members here, e.g. constructors,
// an area method, a point-inside-rectangle ("contains") test....
};
class Box extends Rectangle {
protected double depth;
// pretend that there are more members here....
};
Make sure you give detailed answers about its "appropriateness" and how well it works as a model of the application domain. Then fix it. Include comments.
class Item {
protected int id;
private static int numberOfItemsCreated = 0;
public Item() {id = numberOfItemsCreated++;}
// pretend that there are more members here...
};
As you can see, every item that gets created will get a unique id. Because this pattern occurs frequently, it might be nice to generalize this and make make something reusable out of it so we don't have to write this code inside every class that needs ids. Perhaps we need an interface or abstract class. Tell me why these two suggestions won't work with a detailed, technical answer. Then tell me something that will work. (Note: there is nothing wrong with the access modifiers above; the problems with my two suggestions have to do with the nature of interfaces and abstract classes.)
The AccountClient.java program in the courseware distribution, though short, has a few examples of design patterns. Describe how the handling of button presses uses the Template Method pattern, the command pattern, and the observer pattern.
Given a utility class, can you always rewrite it as a singleton? Given a singleton, can you always rewrite it as a utility class? If so, when would you choose one over the other?
It is estimated that nearly 80% of Java textbook authors write crappy code whenever buttons are involved. They use a kind of antipattern in which there is only one listener for many buttons, and the listener's response has a switch statement controlled by the label on the button (no kidding!). For example: http://aleph0.clarku.edu/~fgreen/courses/CS101Labs/PainterDemoWorking.html (listener registration is in the constructor, the response to the event is in actionPerformed). Give at least two reasons why this is poor design. Contrast with the AccountClient.java program in the courseware.
One of the most important ways in which object oriented programming helps us to manage complexity is through the ability to group related classes into a hierarchy of subclasses and superclasses. Dynamic binding (run-time polymorphism) allows us to operate on collections of objects from different classes in a hierarchy safely. Furthermore, systems which are programmed using dynamic binding are more easily extendible.
Why is it said that implementation inheritance is at odds with encapsulation?
Inheritance is not always appropriate. Discuss the reasons why a design with a superclass Person and subclasses for different jobs (e.g., programmer, manager, ticket agent, flight attendant, supervisor, student, etc.) is a lousy design. Give an alternative.
In designing a class hierarchy in C++, when should you make an operation virtual and when should you make an operation non-virtual? Give examples.
Write C++, Java, Smalltalk, and Ada declarations corresponding to the following class diagram:
Virtually every design pattern exists to decouple different aspects of a design. For example in the Java AWT, the Strategy pattern is used so that graphical containers do not have to be polluted with the details of doing layout. Explain the major decouplings of each of the following patterns, with a close-to-real-life example of each. Use UML only if it helps. (a) State (b) Decorator (c) Factory Method (d) Visitor.
Explain how, in C++, you can get access to, and indeed modify, a protected component of an object that someone else declared. As a concrete example, let’s say someone has declared
class C {protected: int x; ...};
C c;
then your job is to assign a new value to c.x. Assume there are no public operations of C that modify x that you know of.
What makes more sense, to inherit a list from a stack or a stack from a list?
Why did the designers of the C++ standard library containers emphatically reject an inheritance hierarchy of containers?
In C++ you can write
class C {int x;};
C c;
p = &c;
cout << p;
and there is no compile-time nor link time error, despite the fact that operator<<(C*) is not a member of ostream (since that class was declared before you declared C), nor for that matter did anyone declare the global function
ostream& operator<<(ostream&, C*);
So why does it all work? Explain exactly what gets printed and why.
What philosophers call a "class" mathematicians call a "set" (i.e., a collection of unordered, unique, values). So, a philosopher says that every member of a subclass is also a member of the superclass. But a C++ programmer says that every member of a superclass is also a member of its subclass! What is going on here?
Give an example which shows that default parameters are unnecessary in C++ because you can always get the desired effect with overloading.
Explain the following statement, with some (not too much) technical justification. "Whoa, 30 use cases was way overboard for this simple system. This designer doesn't seem to know the difference between a use case and an activity."
Consider the implementation of a Container class framework with the following abstract base class Container:
template <class Item>
class Container {
public:
unsigned numberOfItems() {return currentSize;}
bool isEmpty() {return currentSize == 0;};
virtual void flush() = 0;
~Container() {flush();}
private:
unsigned currentSize;
};
Here the idea is that each particular (derived) container class shall implement its own flush() operation (which makes sense because different containers are flushed in different ways: there may be arrays, linked lists, rings or hashtables used in the representation), and when a container is destroyed its flush() operation will be automatically invoked. However, the idea is flawed and the code as written causes a terrible thing to happen. What happens?
It is possible to make a Person class, then subclasses of Person for different jobs, like Manager, Employee, Student, Monitor, Advisor, Teacher, Officer and so on. This is a bad idea, even though the IS-A test passes. Why is this a bad idea and how should this society of classes be built?
Give the collaboration diagram that is exactly equivalent to the sequence diagram on Page 252 of the UML User Guide.
Explain the essential difference between an iterator and a visitor.
Give a complete UML class diagram for the following code. Be specific with associations, aggregations, cardinality, etc. Then give both a sequence and a collaboration diagram for the case in which someone calls the method f on an object of class Alpha. Remember in your sequence and collaboration diagrams to show all objects whose operations are called.
class Alpha {
private int x;
public void f() {y.g(3.0); z[3].f((int)y.g(g()));}
protected Beta y = Gamma.newBeta();
Delta[] z = new Delta[10];
public int g() {return new Epsilon().compareTo(this);}
}
abstract class Beta extends Alpha {
protected double g(double x) {return 5.0;}
}
class Gamma extends java.net.Socket {
public static final synchronized Beta newBeta() {return new Beta(){};}
}
class Delta extends Alpha {
Alpha a = new Delta();
protected final static transient int ONE = 1;
int f(int g) {return a.g() - ONE;}
}
class Epsilon extends Beta implements Cloneable, Comparable {
public int compareTo(Object o) {return (int)Math.random();}
}
Write a two-paragraph summary of the similarities and differences between proxy, decorator and composite.
Consider the following attempt at defining an interface for Binary Trees:
public interface SimpleTreeNode {
Object getData();
void setData(Object data);
SimpleTreeNode getParent();
java.util.List getChildren();
void insertChildAt(int index, Object data);
void remove();
void preorderTraversal(Visitor visitor);
void postorderTraversal(Visitor visitor);
void breadthFirstTraversal(Visitor visitor);
interface Visitor {
void visit(SimpleTreeNode node);
}
}
How does this mechanism for defining and using visitors differ from the class GoF presentation of visitors?