Philosophy
Interfaces
Generic
Hotspots
Graph
Workflow
Reporting
Drawing
Graph
G = <N,E>
N & E = 0
E = <N,N>
Graph – Node – Edge
================================
Graph
1. Graph
Enumeration getEdges()
Enumeration getNodes()
boolean isMember(Node)
boolean isMember(Edge)
int getEdgeCount()
int getNodeCount()
Node
Object getUserObject()
void setUserObject()
Edge
Object getUserObject()
void setUserObject()
Node getFromNode()
Node getToNode()
2. Node
Enumeration getIncomingEdges()
Enumeration getOutgoingEdges()
3. Graph
boolean isValid()
4. Graph
Mutable
addNode(Node)
removeNode(Node)
addEdge(Edge)
removeEdge(Edge)
Edge
Mutable ??
setFromNode()
setToNode()
5. Node
inNodes
outNodes
6. Graph
throws??
Decisions –
* Add edges to the nodes or the graph?
* Should createNode() and createEdge () be factory methods on Graph?
* Implementations – Node could have list of outnodes (with implicit edges), or perhaps independent nodes & edges in a bitarray.
Graph Applications:
Workflow
Bug-tracking
Trouble tickets
Student registration
DRAWING TOOL
Figure
bounds
position
draw
dependents
contains
Handle
Canvas
Tool
BACKGROUND THINKING
Frameworks in the small:
* Interface – trace specs Hoffman??
* Specsmanship – model
* Parnas
* Booch
* Meyer
FINAL GRAPH
Node
Object getUserObject()
void setUserObject(Object o)
Enum getInEdges(), getOutEdges()
Enum getInNodes(), getOutNodes()
Edge
Node getFromNode()
Node getToNode()
Object getUserObject() *
void setUserObject(Object o) *
* implications for independent representation
Graph
Enum getEdges()
Enum getNodes()
int getEdgeCount()
int getNodeCount()
bool isMember(node)
bool isMember(edge)
bool isValid()
MutableGraph – subtype
createNode([uo])
createEdge([uo])
removeNode(n)
removeEdge(e)
throw graph change exception??
OUTLINE
I. What is a framework?
Philosophy – generic, interface, hotspots
definitions
II. Graph – mini-framework
Domain – sample uses
Dimensions of flexibility
First few cuts – multiple implementations
Frameworks in the small
Final framework – code
Sample uses
web checker
traffic simulator
UML Diagrammer
Use of packages
INTERLUDE: Frameworks in the small
III. Patterns and Swing
IV. Workflow
Layered framework
model
framework
design patterns – policy vs implementation, strategy
uses
bug tracker
student registration
trouble tickets
V. Reporting
Predicate / Result
Groups
VI. Drawing
Separate framework
Connect to graph
VII. Assembly
VIII. Growth, Delivery, Engineering
HOFFMAN – FRAMEWORKS in the SMALL
* Consistent: “with partial knowledge, the remainder of the system can be predicted”
* Essential – omit needless features
* General: Open-ended (future expansion) and complete (all functions of class)
* Minimal – independent features are separate
* Opaque – information hiding. Each module hides a secret. The module needn’t change its interface even if the secret changes.
Application:
Pop combines pop and top – bad
ungetc combines get and advance – bad
graph – node & edge deletion
combining get/set generally bad
Graph interface
Function Input Output Exceptions
s_init int – maxnodes
g_numnodes – int
———————————————————-
s_addnode int – nodenum, exnode
s_delnode int – notexnode
g_exnode int bool
———————————————————-
s_addedge int – exedge, len
int
real
s_deledge int – notexedge
int
g_exedge int bool
int
g_edgelen int real notexedge
int
———————————————————-
g_expath int bool
int
g_pathlen int real notexpath
int
g_firststep int int notexpath
int
——————————————————–
Note: ex=exist, g=get, s=set
Abstract Data Types
Completeness
Each method defined for each representation
Consequence
Does it accept null?
Does it return null?
Can args have illegal values eg out of range?
WHAT IS A GRAPH?
We aren’t doing this to provide a pure mathematical graph: we’re doing it so we can apply the idea of a graph to real problems. This leads us to other considerations:
* We have information to attach to nodes and edges
* Edge from node to itself?
* Do we want multiple occurrences of an edge? (Classical def doesn’t allow it.)
* Are our graphs mutable or immutable? We might like to distinguish these cases.
* Do we want constraints on our graph? (eg connected or non-cyclic)
From our sample domains, we see the need to handle these cases:
* We need to attach information to both nodes and edges. Every application we examined could take advantage of this.
* We will allow multiple occurrences of edges. When an edge has extra information, it’s not merely recording connectivitiy, it’s attaching ther info to the edge, and many sets of information could connect two nodes.
* Mutable/immutable is a useful distinction. (Example jdk1.2 collections) Many situations may have an expensive construction stage, followed by read-only use.
* Validity of the graph is important. This may be useful in allowing for multiple implementations. Some can take advantage of limited graph structure.
APPROACH
Graph class
Develop class – subclass to use – critique interface
From class to framework
Move to interface – black-box via adding userObject
HOFFMAN _ BAD GRAPH
Function Input Output Exceptions
s_init int – maxnodes
g_numnodes – int
g_inf – real *1
s_addedge int – nodenum, len, src_q_dst
int
real
g_visited int real *2
int
g_pathlen int real
g_firststep int int notexpath
int
g_edgelen int real notexedge *3
int
*1 Infinity > any path length
*2 True if edge for node
*3 Length s to d, or g_inf if no path.
Notes: Assumes edge of length 0 between any node and itself.
Method g_first_step returns the first node in the shortest path to d. Pass in the previous result to compose a path.
Problems:
1. Can’t add node without edges present
2. “self-loop” on node is a pain
3. Pathlen – can’t find edge without also finding the path
4. No deletion except s_init
GRAPH CLASS – NOTES
Now – this is not a terrible class.
But there are things that can be improved.
Three things stand out:
1.
2. The “name” field is in all subclasses – but some won’t need it. Furthere – it’s there as a public field – it should at least be wrapped. Probably best to remove it completely.
3.
Guidelines:
Don’t make subclasses pay for extra baggage
List of nodes:
Let’s make them enumerations.
String name – remove it. Let subclasses add it if they need it.
// v0.2
public class Node {
private Vector nodes;
public void addEdge (Node n)
public void removeEdge(Node n)
public Enumeration getNodes()
public Enumeration pathTo(Node n)
}
PULLING OUT THE ABSTRACTION
The graph case is “easy”, because we have the mathematical model to fall back on.
First, we see there is a class for Nodes, but none for the graph as a whole, so we’ll add
public class Graph {
public Enum getNodes()
public void addNode(Node n)
public Enum getNodeCount()
public void removeNode(Node n)
}
Second, we may want edges to be explicit. This may make our overall representation a little more expensive, but we have information we need to associate with edges.
public class Edge {
public Node getFromNode()
public Node getToNode()
Edge(Node n1, Node n2)
}
We’d like to be able to look at all edges in the graph:
getEdges()
getEdgeCount()
Where do we add edges – the node or the graph? Probably want to add them to the graph.
add(edge)
remove(edge)
add(node)
remove(node)
Multiple implementations are a consideration.
GROWING INTO A FRAMEWORK
* Indepdent of implementation – strong barrier
* Inversion of control (vs library)
* Extensible – black-box
IDEAS
* Adapter classes
* Frameworks
* Pree – Hot spots
GUIDELINES
Rules – Interface
* Avoid getter/setter functions
* Look for missing abstractions
* Pre/post-conditions
* Defined behavior for all arguments (eg null)
* Consistency
* Independent features are separate (minimal)
* What’s the secret?
* Don’t expose attributes
* Essential: omit needless features
* General: open-ended and complete
Closed set – native types or frameworks’
Guidelines – framework
* Abstract classes
* Black-box, white-box
* Library
* Flow of control
* Hot spots
* Don’t make subclasses pay for what they don’t use (cost ala carte)
* Implementation -independent
* Class relationships to base class
* Seek models – steal ideas
Patterns in frameworks
* Template method
* Factory
* Composite
* Decorator
* Strategy
Lifetimes
* Expand/contract
* Release
* Testing
PATTERNS IN AWT
MVC/Event-Observer
Event mechanism
PLAF
Composite
JComposite -> Container
Flyweight
Border
Decorator
Border (Compound Border)
Template Method
JComponent paint, paintComponent, etc.
Strategy
LayoutManager
Factory Method
DateFormat
Interpreter
SimpleDateFormat
REPORTS
Query
Format
Accumulators
By type
By date
By page
References
Schmidt, Douglas. Using Design Patterns to Develop Reusable Object-Oriented Software. ACM Computing Surveys, 28(4), December, 1996.
J. Vlissides. Subject Oriented Design. C++ Report, Feb., 1998.
Harrison & Ossher. Subject-Oriented Programming. OOPSLA ’93.
Testing OO
R.M. Poston. Automated Testing from Object Models. CACM Sept’94, v37 #9, pp 48-58.
G. Rothermel & M.J.Harrold. Selecting Regression[s] Tests for Object-Oriented Software. Proc Conf Software Maintenance, IEEE, 1994, pp 14-25.
D.E. Perry & G.E. Kaiser. Adequate Testing and Object-Oriented Programming. JOOP 1990 2(5) pp 13-19.
Sept ’94 CACM. Special issue on object-oriented testing.
Jacobson. OOSE.
Marrick. The Craft of Software Testing.
McGregor. Object-oriented Software Development.
Siegel. Object-Oriented Software Testing.
Object Magazine. Pattern Language for Testing Object-Oriented Software. V5 #8 Jan’96. pp 32-38. “PLOOT” – Firesmith.
CACM Oct. ’97 – Special issue on frameworks
Framework-Based Software Development in C++
Gregory F. Rogers, Jan. ’97
CACM Oct’ 96
Special issue on patterns
References
Online (URLs)
Books
Articles
Winograd/Flores
Reflection in Action
The Reflective Practitioner
Donald Schoen
Ideas
Frameworks vs class libraries
[What’s the difference?]
Show dynamic models for designs
Beans as a framework
Workflow
(Idea for another framework)
Entities
Processes
Constraints
“Who’s next?” – workflow engine
Measurement
Return to sender
State machine?
Aging
Off the clock
Reports:
Time in node
Time in cycle
Close time (clock, off-clock)
By node, etc.
Predicates
Recursion?
JotDraw
Fast interaction
Links count (move objects => links adjust)
Fast
X for shapes [buttons]
Auto-scroll for typing
Keystrokes for shapes
Auto resize
Zones (tab key)
Click to drag or delete
Drag bomb over node to kill?
Issues
Conflicting Class Hierarchies
Separation of concerns
Coupling & cohesion
Separate policy & implementation
Explain why it’s better (rules)
Threads
Corba
Applet as an example of template method