EXTRA CREDIT
{Anti-Patterns}
The Blob- This is when your code becomes more procedural than object-oriented. "The blob" refers to a large class that contains the majority of the processes. The remaining classes contain data. Hence, this code is procedural in that it is separating process from data. Object-oriented programming aims to integrate process and data. Typical causes include the lack of an object-oriented (or any) architecture, the lack of enforcing an object-oriented architecture, and iteratively adding functionality to existing classes rather than redesigning and creating new classes.
Poltergeists - These are classes that have very limited uses in the system. Poltergeists are undesirable because they are (i) unnecessary and waste resources when they "appear", (ii) inefficient because they use multiple navigation paths, (iii) clutter the code and make it difficult to read and organize. Typical causes include a lack of understanding of object-oriented design, trying to use object-oriented design when a different programming style is more appropriate, and management committing itself to an inappropriate architecture.
The Golden Hammer - This is when programmers fall in love with a certain solution or vendor product. Vendors often advocate extensions to these products to solve additional problems. The problem with this is that often the solution is suboptimal and relying on the "Golden Hammer" diverts attention away from exploring a better solution. Of course, a product may occasional be a legitimate "Golden Hammer", though developers should beware since most solutions are not. Several cause of the Golden Hammer anti-pattern are past successes (pride),
large investment of time or money in a particular solution, and reliance on proprietary products.
[src: "Software Development AntiPatterns" by William H. Brown, Raphael C. Malveau, Hays W. "Skip" McCormick III and Thomas J. Mowbray ]
{Regular Expressions}
The regular expression syntax for java is similar to that of Perl, and is contained in the java.util.regex API. The three main classes of this package are Pattern,Matcher, and PatterSyntaxException.
(i) Pattern
A Pattern object is a representation of a regular expression with no public constructors. Creating a pattern requires first invoking a public static compile method with a regular expression object. This returns a Pattern object.
(ii) Matcher
This object is what interprets that pattern and performs matching operations on string input. It also has no public constructors. Matcher objects are created by invoking the matcher method on a Pattern object.
(iii) PatternSyntaxException
This object is an unchecked exception that indicates that a syntax error in a regular expression.
[src: http://java.sun.com/docs/books/tutorial/essential/regex/intro.html ]
Saturday, May 5, 2007
Thursday, May 3, 2007
last day
EXTRA CREDIT
1. submit (before the final) a problem that may be included in the final (nontrivial and interesting)
2. (Submit with your final) What are your top three favorite anti-patterns (things not to do)? [read online and give a description of each, keep it to 1 page; include your name on each page; include sources]
3.
web dvlpment work requires lots of string matching, handy to use regular expression
What are the most important classes/interfaces for regular expression manipulation
include sources
4. extra credit for class notes - submit your notes before the final
note in your final you took notes for extra credit
SAVE AS HTML - INCLUDE IMAGES
+ project is due today before midnight
+ please solve any issues in by tomorrow
final:
+ comprehensive - everything covered in class, take-home, homeworks, etc.
+ emphasis on second part
+ open books/notes
sample topics
+ design an interface given some plain-english specifications
+ take an UML (class) diagram and write the corresponding Java code
+ extend a class to accomplish some new things
+ exception handling example
NO GUI DESIGN AND IMPLEMENTATION
+ i/o problem
+ threading (write a synchronized block to accomplish... or given some code explain what happens if it isn't synchronized )
+ testing: acceptance testing (white box & black box)
+ design patter (e.g. factory, decorator)
+ describe what a piece of code does in plain english
free software/open-source -- know the difference between free software and opensrc
1. clients can't articulate acceptance criteria (don't mention acceptions to the ideal)
2. developers fall in love with their own code and don't test it
=> hire people who are interested in trying to break other people's code
1. submit (before the final) a problem that may be included in the final (nontrivial and interesting)
2. (Submit with your final) What are your top three favorite anti-patterns (things not to do)? [read online and give a description of each, keep it to 1 page; include your name on each page; include sources]
3.
web dvlpment work requires lots of string matching, handy to use regular expression
What are the most important classes/interfaces for regular expression manipulation
include sources
4. extra credit for class notes - submit your notes before the final
note in your final you took notes for extra credit
SAVE AS HTML - INCLUDE IMAGES
+ project is due today before midnight
+ please solve any issues in by tomorrow
final:
+ comprehensive - everything covered in class, take-home, homeworks, etc.
+ emphasis on second part
+ open books/notes
sample topics
+ design an interface given some plain-english specifications
+ take an UML (class) diagram and write the corresponding Java code
+ extend a class to accomplish some new things
+ exception handling example
NO GUI DESIGN AND IMPLEMENTATION
+ i/o problem
+ threading (write a synchronized block to accomplish... or given some code explain what happens if it isn't synchronized )
+ testing: acceptance testing (white box & black box)
+ design patter (e.g. factory, decorator)
+ describe what a piece of code does in plain english
free software/open-source -- know the difference between free software and opensrc
1. clients can't articulate acceptance criteria (don't mention acceptions to the ideal)
2. developers fall in love with their own code and don't test it
=> hire people who are interested in trying to break other people's code
Thursday, April 19, 2007
4/19 Serialization and Runtime Assertions
Reading & Writing Objects
+ we can write objects to a file without having to connect them to things like strings
+ we can read objects from a file without having to convert strings to objects
Serialization means:
+ save a file the class & the data in the instances of that class
+ if any fields reference other objects those will be serialized, too
+ when reading from a file where the objects were serialized they will be stored to same state and content they had when serialized
package java.util;
public class Date implements java.io.serializable {...}
...
// create a file
FileOut.printStream fos = new FileOutputStream("serialDate.bin");
ObjectOutputStream oos = new ObjectOutputStream(fos);
//create data object and write to file
Date d = new Date();
oos.writeObject(d);
this allows us save an object of type Date to file
Ex: read object from file
FileInputStream fis = new FileInputStream("serialDate.bin");
ObjectInputStream ois = new ObjectInputStream(fis);
Object o = ois.readObject(ois); //reads Object from the object input stream (returns from stream)
// now we need to typecast the object to Date (the type you expect)
Date savedDate =(Date)o;
Type casting is type safe in Java, i.e. you can't force an object into a class it doesn't belong to
If you try to...it will raise a "class cast exception"
EX:
Object o = ois.readObject(ois);
Cup myCup = (Cup)o; //this is wrong - raises a class cast exception
Note: if a class is serializable, then all of its classes are serializable as well.
Serialization and Security
The people designing java debated whether all objects shoul dbe serializable
+ the programmer must explicitly decide what objects are serializable because it has implications on security
EX: assume you serialize a file descriptor. Then somebody evil edits the file where the object is stored and modifies it. When the object is read from the file, the file descriptor will point to someplace other than intended
NOTE: you must consider the security implications of your decision to make a class serializable
What can you do?
+ validate the object after you read it back; cross-check for consistency
+ take care of serialization yourself; implement the Externalizable interface (provide the implementation for the read and write methods)
+ use the keyword "transient" to prevent certain data members from being written to the file
class Employer {
String name;
int employeeID;
private transient int SSN;
//the social security # will not be written to the file
//when an instance of Employee is serialized
...
}
Certain classes cannot be serialized at all, e.g. java.lang.Thread
+ thread include java code and native code (perhaps written in C/C++); threads maintain two stacks, one for Java code, the other for native code; the problem is that Java doesn't know what
's in the native stack, therefore serialization cannot possibly work
Assertions and Defensive Programming
+ defensive programming is a way to mitigate the effects of bugs w/o knoowing where the bugs are
NOTE: adopting a defensive programming attitude does not mean youre incompetent
How does it work?
_ figure out invariants, i.e. conditions you expect to hold true at certain points in the program. Test if the condition actually holds true; if it doesn't then something is really wrong -> abort
EX: assume you are working on a compiler, big sofwatre lots of possibiliteis for stuff to go wrong
class Symbols {
Vector symbols;
Vector types;
Vector partitions;
}
Assume a symbol called "sym", the sumbol vector. To find the Type of "sym" we need to access the Types of vecotr at the same index.
int i = symbols.indexOf(sym);
Type t = types.get(i);
This code only works if the vectors symbols and types have the same length
this is your invariate for this piece of code.
Runtime Assertions
+ don't use assertiona as a crutch for sloppy/bad code
+ ways to use assertions
-at the start of precedure to check that procedure is called as ecpected (e.g. proper value for assigments, etc.)
- at the end of the procedure to check that result is reasonable/plausible
- when an operation is performed that has an external effect
Assertions in Java
+ introduced in Java 1.4
EX:
assert booleanExpression ;
+ assert is not recognized by the java compiler unless you instruct it to;
java -source 1.4 MyClass.java
you'll get compilation error with this flag (-source) if your program contains assert statements
+ assertions are turned off by default: you must instruct the run-time environment to execture them
java -ea MyClass
NOTE: test your program both with assertions enabled and assertions disabled (they should do the exact same thing)
avoid assertions that have side effects
EX:
boolean noMoreData = true;
boolean checkingMethod() {
noMoreData = false;
return noMoreData;
}
PROBLEM: different values for noMOreData depending on whether assertions are enabled or disabled.
Q: what is the status of your code?
A: (typical): I'm X% done (x is typically 80 or 90%)
WRONG! you may be 90% done for another month or year even thought waht you've done took only a week or a day...it's easy to get stuck
The correct answer is I'm done or I'm not done.... DO NOT give any other answer (make promises you cannot keep)
+ we can write objects to a file without having to connect them to things like strings
+ we can read objects from a file without having to convert strings to objects
Serialization means:
+ save a file the class & the data in the instances of that class
+ if any fields reference other objects those will be serialized, too
+ when reading from a file where the objects were serialized they will be stored to same state and content they had when serialized
package java.util;
public class Date implements java.io.serializable {...}
...
// create a file
FileOut.printStream fos = new FileOutputStream("serialDate.bin");
ObjectOutputStream oos = new ObjectOutputStream(fos);
//create data object and write to file
Date d = new Date();
oos.writeObject(d);
this allows us save an object of type Date to file
Ex: read object from file
FileInputStream fis = new FileInputStream("serialDate.bin");
ObjectInputStream ois = new ObjectInputStream(fis);
Object o = ois.readObject(ois); //reads Object from the object input stream (returns from stream)
// now we need to typecast the object to Date (the type you expect)
Date savedDate =(Date)o;
Type casting is type safe in Java, i.e. you can't force an object into a class it doesn't belong to
If you try to...it will raise a "class cast exception"
EX:
Object o = ois.readObject(ois);
Cup myCup = (Cup)o; //this is wrong - raises a class cast exception
Note: if a class is serializable, then all of its classes are serializable as well.
Serialization and Security
The people designing java debated whether all objects shoul dbe serializable
+ the programmer must explicitly decide what objects are serializable because it has implications on security
EX: assume you serialize a file descriptor. Then somebody evil edits the file where the object is stored and modifies it. When the object is read from the file, the file descriptor will point to someplace other than intended
NOTE: you must consider the security implications of your decision to make a class serializable
What can you do?
+ validate the object after you read it back; cross-check for consistency
+ take care of serialization yourself; implement the Externalizable interface (provide the implementation for the read and write methods)
+ use the keyword "transient" to prevent certain data members from being written to the file
class Employer {
String name;
int employeeID;
private transient int SSN;
//the social security # will not be written to the file
//when an instance of Employee is serialized
...
}
Certain classes cannot be serialized at all, e.g. java.lang.Thread
+ thread include java code and native code (perhaps written in C/C++); threads maintain two stacks, one for Java code, the other for native code; the problem is that Java doesn't know what
's in the native stack, therefore serialization cannot possibly work
Assertions and Defensive Programming
+ defensive programming is a way to mitigate the effects of bugs w/o knoowing where the bugs are
NOTE: adopting a defensive programming attitude does not mean youre incompetent
How does it work?
_ figure out invariants, i.e. conditions you expect to hold true at certain points in the program. Test if the condition actually holds true; if it doesn't then something is really wrong -> abort
EX: assume you are working on a compiler, big sofwatre lots of possibiliteis for stuff to go wrong
class Symbols {
Vector symbols;
Vector types;
Vector partitions;
}
Assume a symbol called "sym", the sumbol vector. To find the Type of "sym" we need to access the Types of vecotr at the same index.
int i = symbols.indexOf(sym);
Type t = types.get(i);
This code only works if the vectors symbols and types have the same length
this is your invariate for this piece of code.
Runtime Assertions
+ don't use assertiona as a crutch for sloppy/bad code
+ ways to use assertions
-at the start of precedure to check that procedure is called as ecpected (e.g. proper value for assigments, etc.)
- at the end of the procedure to check that result is reasonable/plausible
- when an operation is performed that has an external effect
Assertions in Java
+ introduced in Java 1.4
EX:
assert booleanExpression ;
+ assert is not recognized by the java compiler unless you instruct it to;
java -source 1.4 MyClass.java
you'll get compilation error with this flag (-source) if your program contains assert statements
+ assertions are turned off by default: you must instruct the run-time environment to execture them
java -ea MyClass
NOTE: test your program both with assertions enabled and assertions disabled (they should do the exact same thing)
avoid assertions that have side effects
EX:
boolean noMoreData = true;
boolean checkingMethod() {
noMoreData = false;
return noMoreData;
}
PROBLEM: different values for noMOreData depending on whether assertions are enabled or disabled.
Q: what is the status of your code?
A: (typical): I'm X% done (x is typically 80 or 90%)
WRONG! you may be 90% done for another month or year even thought waht you've done took only a week or a day...it's easy to get stuck
The correct answer is I'm done or I'm not done.... DO NOT give any other answer (make promises you cannot keep)
Friday, April 13, 2007
4/12 Testing
Samel test for you project
$ java InventoryProject
> user Alice ( user perforimgn command .. a new user is specificied) > role Operations (role of current user) > add-inv ( "add inventory" command . . . > show-user
> Alice
> show-role
> Operations
.
.
> quit
$
NOTE: Instead of having mulitple "show -" commands we culd have just one that takes an argument that indicates what to show
ex:
show -user
show -group
show -available
show -booked
.
.
.
if number of records is small, you can sum "view total"
if number of records exceeds ~1000, you may want to start keeping a running summary, but this makes updating harder, but it makes a summary easier
view booked command needs to iterate thru the store and sum booked inventory
**************************
Testing
black-box (aka functional testing)
+ based on specifications - no inspection
+ avoids the mistake of examining/inspecting the app and making the same wrong assumptions the developers made
-independent verification of functionality
+tests are representation independent
NOTE: this is how the TA is going to test your project. the other part of the grading is code inspection
Clear-Box (aka white-box)
+ test cases are generated by looking at the implementation
+ very effective n pointing out problems with inputs that are handled differently by different branches in the code
EX:
int max3(int x, int y, int z) {
if (x>y) {
if (x>y) return x; else return z;
} else {
if (y>z) return y; else return z;
}
}
Clear-box testing also helps finding additional test condition based on things like local variable, loopiterators, etc.
EX:
possible addtional test case
+ input such that the loop is never exectured
+ execeuted just once
+ executed max number of times
Test Strategy and automation use both black=box and clear box testing
(ideally, the test cases developed by someobdy whos only read the specification for the product)
bottom-up : test each module before it gets integrated into the larger context
top-down test hte application until all test pass
assume the followng module dependency diagram
A
| |
B C
| |
D | |
E F
bottum up : test D before B
test E & F before C
test B & C before A
Q: how do you test D before B?
A: youll need to dvlop drivers/wrappers that provide the inputs needed by D.
top down:write stubs to stimulate the behavrior of those parts of the system that havent been developed yet
write stubs..all tests fail..work on it till it passes
as you start writing more code, you change those stubs in to actual working code
advantage of top-down: erros can be identified early in the process before all code has been written
top down is difficult for a large project because clients are unable to detail all criteria for the application
regression testing
+ test your code after youmake code change
- validate that you havent introduced a defect while fixing some code or adding new functionality
automated acceptance testing
+ the test can record human's actions on screen
+ add custom scripting to supplement the recording
The tool can do what a human would do in front of the same screen (e.g. fill in text bozes, check radio buttions, submit forms, etc.)
NOTE: the development of test scrpting should be treated like any other software development activity.
testing is like code, it's intellectual property... will help manage employee turnover, gaurantee function and customer satisfaction, maintain sofware, ...
"start writing code and see how it evolves"
$ java InventoryProject
> user Alice ( user perforimgn command .. a new user is specificied) > role Operations (role of current user) > add-inv ( "add inventory" command . . . > show-user
> Alice
> show-role
> Operations
.
.
> quit
$
NOTE: Instead of having mulitple "show -" commands we culd have just one that takes an argument that indicates what to show
ex:
show -user
show -group
show -available
show -booked
.
.
.
if number of records is small, you can sum "view total"
if number of records exceeds ~1000, you may want to start keeping a running summary, but this makes updating harder, but it makes a summary easier
view booked command needs to iterate thru the store and sum booked inventory
**************************
Testing
black-box (aka functional testing)
+ based on specifications - no inspection
+ avoids the mistake of examining/inspecting the app and making the same wrong assumptions the developers made
-independent verification of functionality
+tests are representation independent
NOTE: this is how the TA is going to test your project. the other part of the grading is code inspection
Clear-Box (aka white-box)
+ test cases are generated by looking at the implementation
+ very effective n pointing out problems with inputs that are handled differently by different branches in the code
EX:
int max3(int x, int y, int z) {
if (x>y) {
if (x>y) return x; else return z;
} else {
if (y>z) return y; else return z;
}
}
Clear-box testing also helps finding additional test condition based on things like local variable, loopiterators, etc.
EX:
possible addtional test case
+ input such that the loop is never exectured
+ execeuted just once
+ executed max number of times
Test Strategy and automation use both black=box and clear box testing
(ideally, the test cases developed by someobdy whos only read the specification for the product)
bottom-up : test each module before it gets integrated into the larger context
top-down test hte application until all test pass
assume the followng module dependency diagram
A
| |
B C
| |
D | |
E F
bottum up : test D before B
test E & F before C
test B & C before A
Q: how do you test D before B?
A: youll need to dvlop drivers/wrappers that provide the inputs needed by D.
top down:write stubs to stimulate the behavrior of those parts of the system that havent been developed yet
write stubs..all tests fail..work on it till it passes
as you start writing more code, you change those stubs in to actual working code
advantage of top-down: erros can be identified early in the process before all code has been written
top down is difficult for a large project because clients are unable to detail all criteria for the application
regression testing
+ test your code after youmake code change
- validate that you havent introduced a defect while fixing some code or adding new functionality
automated acceptance testing
+ the test can record human's actions on screen
+ add custom scripting to supplement the recording
The tool can do what a human would do in front of the same screen (e.g. fill in text bozes, check radio buttions, submit forms, etc.)
NOTE: the development of test scrpting should be treated like any other software development activity.
testing is like code, it's intellectual property... will help manage employee turnover, gaurantee function and customer satisfaction, maintain sofware, ...
"start writing code and see how it evolves"
Thursday, April 5, 2007
April 5, streams , testing and project testing
project checkpoint is today
-submit on blackboard
+ the code you've developed so far
+ a quick/short description of where you are with the project
today:
+ stream I/O
+ Testing
+ Acceptance testing for your project
Stream I/O
Q: Where does stream input come from (or go) ?
A:
+Files
+ terminal window
+network connections
+ audio, video,
+ printers, and other devices
+ pipes (way to do interprocess communication
EX:
$ ls | wc -l
the output of one command (ls) is piped (|) to another command (wc , word count)
Stream Semantics
there are 4 basic operations supported on stream (you should find them in any implementation)
1) open
stream = open(device or file name);
+create a new stream -OR-error thrown if stream cannot be opened
2) close
close(stream);
+closes the given stream; no longer available for reading/writing
3) read
num = read(byte[] buf, int nbytes, Stream stream);
+reads up to nbytes bytes from the stream into buf
+ returns the number of bytes actually read
+read data is removed from the stream, the next read will get different data
4) write
num = write(byte[] buf, int nbytes, Stream stream);
+ writes up to bytes nbytes of data from buf to the stream
+ returns number of bytes actually written
blocking
usually read doesn't return every character, usually you wait for a line or so
read() waiting for some input to appear before returning
EX: read from keyboard before user has hit any key, or from network before any packet has arrived
NOTE: write(), open(), close() can also block , though typically when dealing when dealing with network connections, other program, etc (things outside your environment)
NOTE: sometimes we don't want blocking because it may get entire application stuck. Most stream implementations provide a way to find if there is any data in the stream
EX: in Java call available()
Buffering
reading one byte at a time is expensive and slow --> read data in large chunks that will minimize the (per byte) overhead
+ "buffered" read and write
NOTE: in JAVA buffering is explicit (have to create a buffer, otherwise its one byte at a time)
JAVA
byte-oriented I/O
+ InputStream and OutputStream are two big (decoroator) classes
+ one byte at a time
character-oriented I/O (Unicode compliant)
+ a character in JAVA is two bytes
+ Reader and Writer (are two big (decorator) classes)
Testing
unit testing will test that a specific method in a class will do what you think it should do
but when you put together multiple components into software, how do you know that the final product will actually do what the user wants?
+Goal: ensure that the application works properly
+Testing cannot prove the absence of errors, only their presence
- through testing we can increase our confidence in the application, assume by testing the application that errors will be found
3 techniques to verify a program
1) prove correctness ; through formal specifications (preconditions, post -conditions, loop invariants, etc.)
+ it's impractical, people don't use it for real applications, it just doesn't work cuz it's too complicated.
+ does not solve the fact that specification is incorrect
2) run the program on all possible inputs
+ infeasible due to the large number of possible combinations of inputs
EX: assume a program written in JAVA that takes three 'int' as inputs.
Q: how many possible combinations of inputs are there?
int is 32 bits, so 2^32 possible integers
A: (2^32)^3 = 2^96 ~ 8*10^28
Q: assuming you test 10^6 combinations per second?
A: 8*10^22
86,000 sec/day ~ 100,000 sec /day
so ~ 8*10^17 days = HUGE!
3) run the program on a subset of all possible inputs
+ doesn't gaurantee correctness
+ partition the space of all possible inputs in equivalence classes; any member in each equivalence class is equivalent to any other
EX: the realation hasSameGradeAs on the set of stduents in this class is an eq uivalence relation (i.e. reflexive, symmetric and transitive)
insteadof doing a mathematically crroect partitioning of the set of inputes well use hearuistics
and hope that at least one test case derive through heuristics maps to oone of the unknowable equivalence classes
guess equivalence classes
add additional test cases to account for potential problems related to our guess
Heustics
1) Coverage: find test cases that will exercise each code or specification construct
EX: Java app that takes one 'int' as input. How do youpartition the input space?
2) Boundary cases: include values at the extremities of the range
3) Duplicates: programs often behave differently when there inputs have particular relationships to each other.
EX: an airline bookingsystem a non-stop flight w the same origin and destination (e.g ORD-ORD)
NOTE: the three heuristic should be applied to
+ input values
+ output values
+ nonexplicit values (e.g. loop iterations, set size, number of occurrences of a specific argument)
NOTE: When multiple heuristics apply you should take their cross-product
EX: one heuristic suggest two partitions over one input and another heuristic 3 partitions over another input, then your test untits should have at least 2*3=6 test cases
NOTE: the heuristic can be applied to
+ black box testing -- based on specificiations only; have no idea how it's been built
+ clear box tsting (aka white-box testing) -- you know how its been built
III. Testing your project
NOTE: missing throughout this example is name/role of user
e.g. Mike-Sales, Virgil-President
Prof: I'll give you a set of test cases to use, such as...
add-section "sports"
add-section "news"
add-subsection "news" "local"
add-subsection "news" " national"
list section
(prints) > "sports", "news"
add-inv "news" "local" "300x250" 7/15/2007 100000
add-inv "news" "local" "300x250" 7/15/2007 500000
list-inv "news" "local" "300x250" 7/15/2007
(prints) > 1500000 //total inventory for this section,sub,placement, date
list-inv-avail "news" "local" "300x250" 7/15/2007
(prints)> 1500000 //since i havent booked any yet
book-inv "news" "local" "300x250" 7/15/2007 600000
list-inv-avail "news" "local" "300x250" 7/15/2007
(prints)> 900000 //what's left after i booked 600000
book-inv "news" "local" "300x250" 7/15/20007
(prints)> get lost dude, i dont have this much inventory!
(prints)> Error: only 100000 impressions available
This can be implemented in a number of ways.
(i) one class for each command
EX: java add-section "sports"
NOTE: jave doesn't allow "-" in class name, so use addSection
NOTE: the only way to maintain state between commands is to make sure you write objects to a file or database (otherwise there is no history of command) make sure all objects are serializable. when a command is executed it starts be reading from the file/db.
(ii) implement a command processor
+ read command from std-in (standard input)
+ parse command
+ delegate execution to class method
+ return results
in this case, you only need to save the state once, when the "quit" command is executed.
EX:
$ java InventorySystem
add-inv #waiting for command to be typed
...
...
...
quit
"good bye" # will save state in file/db
$
-submit on blackboard
+ the code you've developed so far
+ a quick/short description of where you are with the project
today:
+ stream I/O
+ Testing
+ Acceptance testing for your project
Stream I/O
Q: Where does stream input come from (or go) ?
A:
+Files
+ terminal window
+network connections
+ audio, video,
+ printers, and other devices
+ pipes (way to do interprocess communication
EX:
$ ls | wc -l
the output of one command (ls) is piped (|) to another command (wc , word count)
Stream Semantics
there are 4 basic operations supported on stream (you should find them in any implementation)
1) open
stream = open(device or file name);
+create a new stream -OR-error thrown if stream cannot be opened
2) close
close(stream);
+closes the given stream; no longer available for reading/writing
3) read
num = read(byte[] buf, int nbytes, Stream stream);
+reads up to nbytes bytes from the stream into buf
+ returns the number of bytes actually read
+read data is removed from the stream, the next read will get different data
4) write
num = write(byte[] buf, int nbytes, Stream stream);
+ writes up to bytes nbytes of data from buf to the stream
+ returns number of bytes actually written
blocking
usually read doesn't return every character, usually you wait for a line or so
read() waiting for some input to appear before returning
EX: read from keyboard before user has hit any key, or from network before any packet has arrived
NOTE: write(), open(), close() can also block , though typically when dealing when dealing with network connections, other program, etc (things outside your environment)
NOTE: sometimes we don't want blocking because it may get entire application stuck. Most stream implementations provide a way to find if there is any data in the stream
EX: in Java call available()
Buffering
reading one byte at a time is expensive and slow --> read data in large chunks that will minimize the (per byte) overhead
+ "buffered" read and write
NOTE: in JAVA buffering is explicit (have to create a buffer, otherwise its one byte at a time)
JAVA
byte-oriented I/O
+ InputStream and OutputStream are two big (decoroator) classes
+ one byte at a time
character-oriented I/O (Unicode compliant)
+ a character in JAVA is two bytes
+ Reader and Writer (are two big (decorator) classes)
Testing
unit testing will test that a specific method in a class will do what you think it should do
but when you put together multiple components into software, how do you know that the final product will actually do what the user wants?
+Goal: ensure that the application works properly
+Testing cannot prove the absence of errors, only their presence
- through testing we can increase our confidence in the application, assume by testing the application that errors will be found
3 techniques to verify a program
1) prove correctness ; through formal specifications (preconditions, post -conditions, loop invariants, etc.)
+ it's impractical, people don't use it for real applications, it just doesn't work cuz it's too complicated.
+ does not solve the fact that specification is incorrect
2) run the program on all possible inputs
+ infeasible due to the large number of possible combinations of inputs
EX: assume a program written in JAVA that takes three 'int' as inputs.
Q: how many possible combinations of inputs are there?
int is 32 bits, so 2^32 possible integers
A: (2^32)^3 = 2^96 ~ 8*10^28
Q: assuming you test 10^6 combinations per second?
A: 8*10^22
86,000 sec/day ~ 100,000 sec /day
so ~ 8*10^17 days = HUGE!
3) run the program on a subset of all possible inputs
+ doesn't gaurantee correctness
+ partition the space of all possible inputs in equivalence classes; any member in each equivalence class is equivalent to any other
EX: the realation hasSameGradeAs on the set of stduents in this class is an eq uivalence relation (i.e. reflexive, symmetric and transitive)
insteadof doing a mathematically crroect partitioning of the set of inputes well use hearuistics
and hope that at least one test case derive through heuristics maps to oone of the unknowable equivalence classes
guess equivalence classes
add additional test cases to account for potential problems related to our guess
Heustics
1) Coverage: find test cases that will exercise each code or specification construct
EX: Java app that takes one 'int' as input. How do youpartition the input space?
2) Boundary cases: include values at the extremities of the range
3) Duplicates: programs often behave differently when there inputs have particular relationships to each other.
EX: an airline bookingsystem a non-stop flight w the same origin and destination (e.g ORD-ORD)
NOTE: the three heuristic should be applied to
+ input values
+ output values
+ nonexplicit values (e.g. loop iterations, set size, number of occurrences of a specific argument)
NOTE: When multiple heuristics apply you should take their cross-product
EX: one heuristic suggest two partitions over one input and another heuristic 3 partitions over another input, then your test untits should have at least 2*3=6 test cases
NOTE: the heuristic can be applied to
+ black box testing -- based on specificiations only; have no idea how it's been built
+ clear box tsting (aka white-box testing) -- you know how its been built
III. Testing your project
NOTE: missing throughout this example is name/role of user
e.g. Mike-Sales, Virgil-President
Prof: I'll give you a set of test cases to use, such as...
add-section "sports"
add-section "news"
add-subsection "news" "local"
add-subsection "news" " national"
list section
(prints) > "sports", "news"
add-inv "news" "local" "300x250" 7/15/2007 100000
add-inv "news" "local" "300x250" 7/15/2007 500000
list-inv "news" "local" "300x250" 7/15/2007
(prints) > 1500000 //total inventory for this section,sub,placement, date
list-inv-avail "news" "local" "300x250" 7/15/2007
(prints)> 1500000 //since i havent booked any yet
book-inv "news" "local" "300x250" 7/15/2007 600000
list-inv-avail "news" "local" "300x250" 7/15/2007
(prints)> 900000 //what's left after i booked 600000
book-inv "news" "local" "300x250" 7/15/20007
(prints)> get lost dude, i dont have this much inventory!
(prints)> Error: only 100000 impressions available
This can be implemented in a number of ways.
(i) one class for each command
EX: java add-section "sports"
NOTE: jave doesn't allow "-" in class name, so use addSection
NOTE: the only way to maintain state between commands is to make sure you write objects to a file or database (otherwise there is no history of command) make sure all objects are serializable. when a command is executed it starts be reading from the file/db.
(ii) implement a command processor
+ read command from std-in (standard input)
+ parse command
+ delegate execution to class method
+ return results
in this case, you only need to save the state once, when the "quit" command is executed.
EX:
$ java InventorySystem
add-inv #waiting for command to be typed
...
...
...
quit
"good bye" # will save state in file/db
$
Thursday, March 22, 2007
3/29 Collection Frameworks (Containers)
Administrative:
midterm - return next week
new homework posted on website
NOTE: you have to start working more diligently on the project
*******************************************
take home problems:
assume you can calculate 10 million different circuits per second thru a fully connected weighted graph. If N=100, how long will it take you to solve the TSP problem.
*****************************
framework design requirements
completeness - do what its supposed to do
adaptability- adapt to new problems or requirements
efficiency - memory, run-time, time spent programming
safety - run-time behavior
simplicity - easy to understand how it works and is used
extensibility - easily extend framework
FRAMEWORKS
1. Collection Framework (containers)
- support storing and retrieving objects
2. GUI Framework
3. Input/Output Framework
Collection Framework (Containers)
A collection is an object that contains another object.
Collection are classified based on their structures and capabilities
-bags (rarely used)
-sets (sometimes used)
-lists (used all the time)
-maps (used all the time)
Bags
-order of elements is unimportant
-repetitions are allowed
- least restrictive
-general form
- extend the collection interface
Example:
B1=[a,b,a]
B2 = [a,a,b]
B1 = B2
public class Box
{
private Object object;
public void add(Object object)
{
this.object = object;
}
public Object get() { return object; }
}
NOTE on generics
problem is you can only add Objects , what about string, cup, etc.
public class Box
{
private T t; //T stands for type
public void add(T t)
{
this.t= object;
}
public T get() { return t; }
}
Box integerBox;
to instantiate this class, use the new keyword but place between the class name and the parenthesis: integerBox = new Box();
Collection Interface
size
isEmpty
contains
add
remove
Iterator
...
Java Collection Documentation
http://java.sun.com/j2se/1.4.2/docs/api/java/util/Collection.html
Collection
-----------------------
| | |
Set List Queue
|
SortedSet
Map
|
SortedMap
Set
order of element is important
repetitions are NOT allowed
Set Interface
http://java.sun.com/j2se/1.4.2/docs/api/java/util/Set.html
List
- order is important
- repetitions are allowed
Example: L1 =<>, L2 = , L3 = ,b>
http://java.sun.com/j2se/1.5.0/docs/api/java/util/List.html
Map
-collection of key-value pairs
- don't allow duplicate pairs
-
http://java.sun.com/j2se/1.4.2/docs/api/java/util/Map.html
Implementation of sets
HashSet
-very efficient add() and contains() : O(1)
-iteration order is unpredictable
LinkedHashSet
-iteration order is predictable
TreeSet
-used red-black tree for implementation
-elements ordered in natural order or user-defined
-time complexity for add() and contains : O(logn)
Iterator Example
midterm - return next week
new homework posted on website
NOTE: you have to start working more diligently on the project
*******************************************
take home problems:
assume you can calculate 10 million different circuits per second thru a fully connected weighted graph. If N=100, how long will it take you to solve the TSP problem.
*****************************
framework design requirements
completeness - do what its supposed to do
adaptability- adapt to new problems or requirements
efficiency - memory, run-time, time spent programming
safety - run-time behavior
simplicity - easy to understand how it works and is used
extensibility - easily extend framework
FRAMEWORKS
1. Collection Framework (containers)
- support storing and retrieving objects
2. GUI Framework
3. Input/Output Framework
Collection Framework (Containers)
A collection is an object that contains another object.
Collection are classified based on their structures and capabilities
-bags (rarely used)
-sets (sometimes used)
-lists (used all the time)
-maps (used all the time)
Bags
-order of elements is unimportant
-repetitions are allowed
- least restrictive
-general form
- extend the collection interface
Example:
B1=[a,b,a]
B2 = [a,a,b]
B1 = B2
public class Box
{
private Object object;
public void add(Object object)
{
this.object = object;
}
public Object get() { return object; }
}
NOTE on generics
problem is you can only add Objects , what about string, cup, etc.
public class Box
{
private T t; //T stands for type
public void add(T t)
{
this.t= object;
}
public T get() { return t; }
}
Box
to instantiate this class, use the new keyword but place
Collection Interface
size
isEmpty
contains
add
remove
Iterator
...
Java Collection Documentation
http://java.sun.com/j2se/1.4.2/docs/api/java/util/Collection.html
Collection
-----------------------
| | |
Set List Queue
|
SortedSet
Map
|
SortedMap
Set
order of element is important
repetitions are NOT allowed
Set Interface
http://java.sun.com/j2se/1.4.2/docs/api/java/util/Set.html
List
- order is important
- repetitions are allowed
Example: L1 =<>, L2 = , L3 = ,b>
http://java.sun.com/j2se/1.5.0/docs/api/java/util/List.html
Map
-collection of key-value pairs
- don't allow duplicate pairs
-
http://java.sun.com/j2se/1.4.2/docs/api/java/util/Map.html
Implementation of sets
HashSet
-very efficient add() and contains() : O(1)
-iteration order is unpredictable
LinkedHashSet
-iteration order is predictable
TreeSet
-used red-black tree for implementation
-elements ordered in natural order or user-defined
-time complexity for add() and contains : O(logn)
Iterator Example
Thursday, March 1, 2007
3/1 - Midterm Review + More Patterns
Midterm: Next Week
-open books/notes
-no pc allowed
-material covered:
-everything discussed in class
-take-home assignments
- project assignments
Recommend problems to answer when studying for exam:
find examples of classes where these two keywords (private, void) can appear in the class declaration (classes with return types)
send solution of problem 10 for feedback
Show a class diagram for problem #5.
#6.iii, 6.iv
What are the characteristics of good unit tests?
EXAMPLE EXAM PROBLEMS
1. Which of these pairs represents the IS-A relationship?
> (i) duck/bird
(ii) bird/fly
beak/bird
bird/nest
2. Which Java technology best supports the IS-A relationship
> Inheritance
Access restriction
strong typing
garbage collection
3. Which Java keywords cannot appear in a class declaration?
extends
> protected
void (classes can have return types)
private
4. Which of these code fragments represents a HAS-A relationship between Foo and Bar?
class Foo extends Bar {...}
class Foo implements Bar {...}
> class Foo {private Bar;}
class abstract class Bar extends Foo {...}
5. You are designing an Object-Oriented program to help people plan an evening out. It is proposed that the following classes are used:
class Address { }
class Business { } //anything that appears in the yellow pages
class City { }
class Restaurant { }
class Theater { }
Add inheritance and instance variables to show the IS-A and HAS-A relationships. Do not introduce any additional classes. Do not introduce any additional classes.
((a variation would be to draw a class diagram for these entities))
Ans:
// Restaurant and Theater extend Business
class Restaurant extends Business {
}
class Theater extends Business {
}
class Business {
Address bizAddress;
}
class City {
Business someBusiness;
}
6. True/False. Circle the correct answer for each of the following statements.
T (i) If class B is a subclass of A, then B's constructor can explicitly call A's constructor using the keyword 'super'.
T (ii) One can declare a variable of an interface type, but cannot create an object of that type.
(iii) The private fields of a class are visible within the file in which the class is defined.
(iv) A non-static method cannot refer to any static fields of the class.
7. The following is declared within the class A.
public static void main(String[] s)
Which statement is correct?
(i) Since main is static, then no object of class A can be created within main.
> (ii) Main is required to be static since the program cannot an object of class A before main() is executed
(iii) The array s must be initialized in A's constructor
(iv) A compile-time error will result since the string array must be called argc. ((no, you can call it anything you want))
8. Write a ThreeWayLamp class that models the behavior of a lamp with a three-way bulb. (off, med, high). Each time the switch is activated, the bulb goes to the next state.
class ThreeWayLamp {
private int state;
void switch() {
state = (state + 1) % 3;
// print message here
}
ThreeWayLamp() {
state = 0; //new lamp is off
}
}
9. What are the characteristics of good unit tests?
10. Draw a class diagram for the following
"A building can be specialized in many ways; in this example we show HighRise and TownHouse. A building is owned by one or more Persons. A building can be queried for its creation date with the message getCreationdate(). A HighRise response to the hasElevator() message. A Person can own zero or more buildings. A Person has an age and a name. Man and Woman are the only possible types of Person. A building has one or two front doors and zero or more back doors, all of which are Doors. At any point in time a Building can contain zero or more Persons. A building must be able to reference its doors, but not the other way around. "
11. Draw a sequence diagram for two Subscriber objects s1 and s2. . .
Behavioral Patterns
Ex: assume a database of all IIT student grades and the staff of cs445 wishes to view the grades of students in cs445.
They could write a SpreadSheetView class that pulls data from the DB and displays it.
HW1 HW2 HWs
Anna 45 85 80
Joe 95 90 85
Gus 90 100 95
The code to communicate between the view and the DB:
interface GradDMViewer {
void update(String course, String name, String assignment, int mark);
}
Where new grade (mark) information is available (e.g. new grades posted on conections to existing ones) the grade DB must commuincate this to the view.
Let's suppose that Anne's mark in HW1 changed to 100. The DB code must make a call to spreadSheetView.update().
EX:
SpreadSheetView ssv = new SpreadSheetView();
. . .
ssv.update("cs445", "Anne", "HW1", "100");
Then the view redisplays itself.
HW1 HW2 HWs
Anna 100 85 80
Joe 95 90 85
Gus 90 100 95
We want to add a bargraph view for averages.
# # #
*
* *
* * *
* * *
* * *
A J G
If we want to maintain both view then the code will look like this.
SpreadSheetView ssv = new SpreadSheetView();
BarGraphView bgv = new Bargraph();
ssv.update("cs445","Anne","HW1", 100);
bgv.update("cs445","Anne", "HW1",100);
Q: what if i want a pie chart?
A: need to change the code again.
! This is wrong; The code should be reusable without having to change implementation.!
leads to the Observer Pattern (which you'll find all the time) which addresses this issue.
Observer Pattern
Instead of hard-coding the views that need to be notified on change, the database can maintain a list of observers (objects) that need to be notified about a change.
Vector observers = new Vector();
. . .
for(int i = 0; i < v =" (GradeDBViewer)" style="font-weight: bold;">Pattern Functionality) Interface
---------------------------------------
--------------------------------------------------
Adapter same different
--------------------------------------------------
Decorator different same
--------------------------------------------------
Proxy same same
--------------------------------------------------
EX: Adapter some code that works on Rectangle objects and calls their scale method.
interface Rectangle {
void scale(float factor); //grow/shrink by a factor
float area();
float circumference();
}
class MyClass {
void myMethod(Rectangle r) }
. . .
r.scale(2);
. . .
}
}
Let's assume another class of non-scaleable rectangles, call 'em NonScaleRectangle, which lacks
the scale method but has the other methods in Rectangle and in addition, other methods such as setWidth, setHeight, etc.
class NonScaleRectangle {
void setWidth(float w) { . . . }
void setHeight(float h) { . . . }
. . .
}
Problem: You may wish to use objects of this type (e.g. improve performance, interoperability). But you cannot use NonScaleRectangle directly because the interface is different from Rectangle.
Solution: Write an Adapter
(i) subclassing
class ScaleRectangle extends NewScaleRectangle implements Rectangle {
void scale(float factor) {
setWidth(factor*getWidth( ) );
setHeight(factor*getHeight( ) );
}
}
(ii) Composition / Forwarding
class ScaleRectangle2 implements Rectangle {
NonScaleRectangle r;
ScaleRectangle2( NonScaleRectangle r) {
this.r = r;
}
void scale (float factor) {
setWidth(factor*getWidth( ) );
setHeight(factor*getHeight( ) );
}
float area() {
return r.area( );
}
}
Decorator Pattern
Adapter changes interface without adding functionality.
Decorator extends functionality with the same interface.
-Decorator changes some instances of a class such that they have extra functionality.
-Decorator sounds like subclassing, but it's NOT (subclassing modifies functionality of ALL instances ??)
EX: Assume a Window interface (for a window manager) and a BorderedWindows interface. BorderedWindow draws a border outside the window.
interface Window {
Rectangle bounds(); //rectangle bounding the windows
void draw(Screen s); //draw it on a screen
. . .
}
class WindowImpl implements Window {
. . .
}
(i) decoration by subclassing
class BorderedWindow1 extends WindowImple {
void draw(Screen s) {
supper.draw(s);
bounds().draw(s);
}
}
(ii) Composition / Forwarding
class BorderedWindow2 implements Window {
Window innerWindow;
BorderedWindow2(Window innerWindow) {
this.innerWindow = innerWindow;
}
void draw(Screen s){
innerWindow.draw(s);
innerWindow.bounds().draw(s);
}
. . .
}
ADVICE: Do not try forcing a pattern until you have a real need for it. With experience, you;ll notice problems and ask yourselves "hmm, how have other people solved this problem." It will come naturally with experience, but you should be aware of this.
-open books/notes
-no pc allowed
-material covered:
-everything discussed in class
-take-home assignments
- project assignments
Recommend problems to answer when studying for exam:
find examples of classes where these two keywords (private, void) can appear in the class declaration (classes with return types)
send solution of problem 10 for feedback
Show a class diagram for problem #5.
#6.iii, 6.iv
What are the characteristics of good unit tests?
EXAMPLE EXAM PROBLEMS
1. Which of these pairs represents the IS-A relationship?
> (i) duck/bird
(ii) bird/fly
beak/bird
bird/nest
2. Which Java technology best supports the IS-A relationship
> Inheritance
Access restriction
strong typing
garbage collection
3. Which Java keywords cannot appear in a class declaration?
extends
> protected
void (classes can have return types)
private
4. Which of these code fragments represents a HAS-A relationship between Foo and Bar?
class Foo extends Bar {...}
class Foo implements Bar {...}
> class Foo {private Bar;}
class abstract class Bar extends Foo {...}
5. You are designing an Object-Oriented program to help people plan an evening out. It is proposed that the following classes are used:
class Address { }
class Business { } //anything that appears in the yellow pages
class City { }
class Restaurant { }
class Theater { }
Add inheritance and instance variables to show the IS-A and HAS-A relationships. Do not introduce any additional classes. Do not introduce any additional classes.
((a variation would be to draw a class diagram for these entities))
Ans:
// Restaurant and Theater extend Business
class Restaurant extends Business {
}
class Theater extends Business {
}
class Business {
Address bizAddress;
}
class City {
Business someBusiness;
}
6. True/False. Circle the correct answer for each of the following statements.
T (i) If class B is a subclass of A, then B's constructor can explicitly call A's constructor using the keyword 'super'.
T (ii) One can declare a variable of an interface type, but cannot create an object of that type.
(iii) The private fields of a class are visible within the file in which the class is defined.
(iv) A non-static method cannot refer to any static fields of the class.
7. The following is declared within the class A.
public static void main(String[] s)
Which statement is correct?
(i) Since main is static, then no object of class A can be created within main.
> (ii) Main is required to be static since the program cannot an object of class A before main() is executed
(iii) The array s must be initialized in A's constructor
(iv) A compile-time error will result since the string array must be called argc. ((no, you can call it anything you want))
8. Write a ThreeWayLamp class that models the behavior of a lamp with a three-way bulb. (off, med, high). Each time the switch is activated, the bulb goes to the next state.
class ThreeWayLamp {
private int state;
void switch() {
state = (state + 1) % 3;
// print message here
}
ThreeWayLamp() {
state = 0; //new lamp is off
}
}
9. What are the characteristics of good unit tests?
10. Draw a class diagram for the following
"A building can be specialized in many ways; in this example we show HighRise and TownHouse. A building is owned by one or more Persons. A building can be queried for its creation date with the message getCreationdate(). A HighRise response to the hasElevator() message. A Person can own zero or more buildings. A Person has an age and a name. Man and Woman are the only possible types of Person. A building has one or two front doors and zero or more back doors, all of which are Doors. At any point in time a Building can contain zero or more Persons. A building must be able to reference its doors, but not the other way around. "
11. Draw a sequence diagram for two Subscriber objects s1 and s2. . .
Behavioral Patterns
Ex: assume a database of all IIT student grades and the staff of cs445 wishes to view the grades of students in cs445.
They could write a SpreadSheetView class that pulls data from the DB and displays it.
HW1 HW2 HWs
Anna 45 85 80
Joe 95 90 85
Gus 90 100 95
The code to communicate between the view and the DB:
interface GradDMViewer {
void update(String course, String name, String assignment, int mark);
}
Where new grade (mark) information is available (e.g. new grades posted on conections to existing ones) the grade DB must commuincate this to the view.
Let's suppose that Anne's mark in HW1 changed to 100. The DB code must make a call to spreadSheetView.update().
EX:
SpreadSheetView ssv = new SpreadSheetView();
. . .
ssv.update("cs445", "Anne", "HW1", "100");
Then the view redisplays itself.
HW1 HW2 HWs
Anna 100 85 80
Joe 95 90 85
Gus 90 100 95
We want to add a bargraph view for averages.
# # #
*
* *
* * *
* * *
* * *
A J G
If we want to maintain both view then the code will look like this.
SpreadSheetView ssv = new SpreadSheetView();
BarGraphView bgv = new Bargraph();
ssv.update("cs445","Anne","HW1", 100);
bgv.update("cs445","Anne", "HW1",100);
Q: what if i want a pie chart?
A: need to change the code again.
! This is wrong; The code should be reusable without having to change implementation.!
leads to the Observer Pattern (which you'll find all the time) which addresses this issue.
Observer Pattern
Instead of hard-coding the views that need to be notified on change, the database can maintain a list of observers (objects) that need to be notified about a change.
Vector observers = new Vector();
. . .
for(int i = 0; i < v =" (GradeDBViewer)" style="font-weight: bold;">Pattern Functionality) Interface
---------------------------------------
--------------------------------------------------
Adapter same different
--------------------------------------------------
Decorator different same
--------------------------------------------------
Proxy same same
--------------------------------------------------
EX: Adapter some code that works on Rectangle objects and calls their scale method.
interface Rectangle {
void scale(float factor); //grow/shrink by a factor
float area();
float circumference();
}
class MyClass {
void myMethod(Rectangle r) }
. . .
r.scale(2);
. . .
}
}
Let's assume another class of non-scaleable rectangles, call 'em NonScaleRectangle, which lacks
the scale method but has the other methods in Rectangle and in addition, other methods such as setWidth, setHeight, etc.
class NonScaleRectangle {
void setWidth(float w) { . . . }
void setHeight(float h) { . . . }
. . .
}
Problem: You may wish to use objects of this type (e.g. improve performance, interoperability). But you cannot use NonScaleRectangle directly because the interface is different from Rectangle.
Solution: Write an Adapter
(i) subclassing
class ScaleRectangle extends NewScaleRectangle implements Rectangle {
void scale(float factor) {
setWidth(factor*getWidth( ) );
setHeight(factor*getHeight( ) );
}
}
(ii) Composition / Forwarding
class ScaleRectangle2 implements Rectangle {
NonScaleRectangle r;
ScaleRectangle2( NonScaleRectangle r) {
this.r = r;
}
void scale (float factor) {
setWidth(factor*getWidth( ) );
setHeight(factor*getHeight( ) );
}
float area() {
return r.area( );
}
}
Decorator Pattern
Adapter changes interface without adding functionality.
Decorator extends functionality with the same interface.
-Decorator changes some instances of a class such that they have extra functionality.
-Decorator sounds like subclassing, but it's NOT (subclassing modifies functionality of ALL instances ??)
EX: Assume a Window interface (for a window manager) and a BorderedWindows interface. BorderedWindow draws a border outside the window.
interface Window {
Rectangle bounds(); //rectangle bounding the windows
void draw(Screen s); //draw it on a screen
. . .
}
class WindowImpl implements Window {
. . .
}
(i) decoration by subclassing
class BorderedWindow1 extends WindowImple {
void draw(Screen s) {
supper.draw(s);
bounds().draw(s);
}
}
(ii) Composition / Forwarding
class BorderedWindow2 implements Window {
Window innerWindow;
BorderedWindow2(Window innerWindow) {
this.innerWindow = innerWindow;
}
void draw(Screen s){
innerWindow.draw(s);
innerWindow.bounds().draw(s);
}
. . .
}
ADVICE: Do not try forcing a pattern until you have a real need for it. With experience, you;ll notice problems and ask yourselves "hmm, how have other people solved this problem." It will come naturally with experience, but you should be aware of this.
Thursday, February 22, 2007
2/22 - Patterns & Frameworks
Patterns
+ first used - Christopher Alexander, 1972 "A Pattern Language"+ 250 patterns for arch. design
Motivation for Patterns & Frameworks
+ developing software is hard
+ developing reusable software is even harder
Proven solutions include Patterns & Frameworks
Patterns: support reuse of software architecture and design
capture static and dynamic structure and collaboration of successful solutions to problems that arise when building applications in a particular domain
Frameworks: support reuse of detailed design code
a framework is an integrated set of components that collaborate to provide a reusable architecture for a family of related applications
Becoming a Chess Master
(i) learn the rules, e.g. names of pieces, legal movements, where pieces belong on the chessboard
(ii) learn the principles, e.g. relative values of pieces, strategic value of center squares, etc.
(iii) study the game of chess masters:
-patterns of the game, e.g. opening the game, final moves, etc.
(100s of patterns)
Becoming a Software Design Master
(i) learn the rules, e.g. algorithms, data structures, programming languages
(ii) learn the principles, e.g structured programming, modular, OOP, etc.
(iii) study the design of other masters
-these designs contain patterns
- these patterns must be understood and applied in your work
In software engineering, we seem to be making the same mistakes over and over again
design patterns are solutions to problems that arise when developing software in a particular context
PATTERN == problem & solution pair in a context
Design Pattern Descriptions
(i) name and intent
(ii) problems and context
(iii) forces addressed
(iv) abstract description of structure and collaborations in solution
(v) positive and negative consequences of use
(vi) implementation guidelines and sample code
(vii) known uses and related patterns
(some include anti-patterns, i.e. when NOT do use something)
Design Pattern Space
1. Creational patterns - deal with initializing and configuring classes and objects
e.g. factory method, abstract factory, singleton, prototype, etc.
2. structural patterns- deal with decoupling interface and implementation of classes and objects
e.g. adapter, decorator, etc.
3. Behavioral patterns - deal with dynamic interactions among societies of classes and objects
e.g. observer, iterator, etc.
NOTE: these patterns are language independent
Examples of Design Patterns
Pattern: Encapsulation (data hiding)
Problem: exposed data members can be manipulated directly (and inappropriately)
Solution: hide some members, allow access only through methods
Disadvantages: the interface may not provide all desired operation. can be inefficient (extra overhead)
Example Code
class Cup {
float fluidAmt;
float cupCapacity;
//other methods
}
Cup myCup = new Cup(12);
myCup.fluidAmt = 32;
//the cup cannot take more than 12 fluid ounces!!
/********************************/
class Cup {
private float fluidAmt;
private float cupCapacity;
void addFluid(float amt){
//code
}
}
Cup myCup = new Cup(12);
myCup.addFluid(32);
//methods enforce some logic
Pattern: Subclassing (Inheritance)
Problem: similar abstractions have similar members (data and methods); repeating them is tedious, prone to error and hard to maintain
Solution: inherit default members from the superclass; select the correct implementation via run-time dispatching
Disadvantages: code for class is spread out between parent class and subclasses (can make it easier to follow), run-time dispatching introduces overhead
Note: in Java, everything is a subclass of Object
beware very deep inheritance trees because they are expensive at execution time
when you create in inheritance of child all constructors in the inheritance tree will be executed, all the way up to Object
Pattern: Exceptions
Problem: errors occurring in the code are often handled elsewhere. Code should not be cluttered with error-handling code
Solution: introduce language structure for throwing and catching exceptions
Disadvantage: it's still hard at times to know where the exception will be handled (in particular if it's not done locally). programmer's may be tempted to use exception to control program flow (inefficient)
When (not) to Use Patterns
Same rule as for optimization: delay.
Don't try to force patterns into your code.
Creational Patterns
factories
example: write class to represent a bicycle race. a race consists of multiple bicycles
class Race {
Race createRace() {
Frame frame1 = new Frame();
Wheel front1 = new Wheel();
Wheel rear1 = new Wheel();
Bicycle bike1 = new Bicycle(frame1,front1,rear1);
Frame frame2 = new Frame();
Wheel front2 = new Wheel();
Wheel rear2 = new Wheel();
Bicycle bike2 = new Bicycle(frame2,front2,rear2);
// and so on
}
}
Specialize Race for other bicycle races:
class TourDeFrance extends Race {
Race createRace() {
France game1 = new RacingFrance();
Wheel front1 = new Wheel1700c();
Wheel rear1 = new Wheel1700c();
Bicycle bike1 = new Bicycle(frame1, front1,rear1);
// and so on
}
}
class Cyclocross extends Race {
Race createRace() {
Frame frame1 = new MountainFrance();
Wheel front1 = new Wheel27in();
Wheel rear1 = new Wheel27in();
Bicycle bike1 = new Bicycle(frame1, front1, rear1);
//and so on
}
}
This is TEDIOUS since we could not re-use the Race.createRace() method.
A factory method is a method that "manufactures" objects of a particular type.
We can add factory methods to Race.
// Factory methods are in bold
class Race {
Frame createFrame() {
return new Frame();
}
Wheel createWheel() {
return new Wheel() ;
}
Bicycle createBicycle(Frame frame, Wheel front, Wheel rear) {
return new Bicycle(frame, front, rear);
}
//return a complete bicycle without needing any arguments
Bicycle completeBicycle(){
Frame frame = createFrame();
Wheel front = createWheel();
Wheel rear = createWheel();
return createBicycle(frame, front, rear);
}
Race createRace() {
Bicycle bike1 = completeBicycle();
Bicycle bike2 = complete Bicycle();
}
}
class TourDeFrance extends Race {
France createFrance() {
return new RacingFrame();
}
Wheel createWheel() {
return new Wheel1700c();
}
Bicycle createBicycle(Frame frame, Wheel front, Wheel rear) {
return new RacingBicycle();
}
}
class Cyclocross extends Race {
Frame createFrame() {
return new MountainFrame();
}
Wheel createWheel() {
return new Wheel27in();
}
Bicycle createBicycle(France france, Wheel front, wheel rear) {
return new MountainBicycle(frame, front, rear);
}
}
A factory object is an object that encapsulates factory methods
class BicycleFactory {
Frame createFrame() {
return new Frame();
}
Wheel createWheel() {
return new Wheel();
}
Bicycle createBicycle(Frame frame, Wheel front, Wheel rear) {
return new Bicycle(frame, front, rear);
}
Bicycle completeBicycle() {
Frame frame = creatveFrame();
Wheel front = createWheel();
Wheel rear = createWheel();
return createBicycle(frame,front,rear);
}
}
class RacingBicycleFactory {
Frame createFrame() {
return new RacingFrame();
}
Wheel createWheel() {
return new Wheel1700c();
}
Bicycle createBicycle(Frame frame, Wheel front, Wheel rear) {
return new RacingBicycle(frame, front, rear);
}
}
// do same for cyclecross factory Object
The Race methods will use the factory Objects.
class Race {
BicycleFactory bfactory;
Race() {
bfactory = new BicycleFactory();
}
Race createRace() {
Bicycle bike1 = bfactory.completeBicycle();
Bicycle bike2 = bfactory.completeBicycle();
//and so on
}
}
class TourDeFrance extends Race {
//constructor
TourDeFrance() {
bfactory = new RacingBicycleFactory();
}
}
class Cyclocross extends Race {
Cyclocross() {
bfactory = new MountainBicycleFactory();
}
}
Problem with latest code: the type of bike is still hard-coded in the race.
This can be made more flexible by changing the way we call constuctor.
class Race {
BicycleFactory bfactory;
//constuctor
Race (BicycleFactory bfactory) {
this.bfactory = bfactory;
}
Race createRace() {
Bicycle bike1 = bfactory.completeBicycle();
Bicycle bike2 = bfactory.completeBicycle();
}
class TourDeFrance extends Race {
TourDeFrance(BicycleFactory bfactory) {
this.bfactory = bfactory;
}
}
Now you can control the type of race and the variety of bicycle:
new TourDeFrance(new racingBicycleFactory());
One reason that factory methods are required is a weakness in Java constructors .
Constructors cannot return an object of a subtype ( a different type), even though semantically it would be correct.
Take home:
(i) What is the criticism against patterns?
(ii) What is the "Big Ball of Mud" ? Is this in any way related to patterns?
Applying patterns requires good familiarity with a programing language (lots of experience). So focus you time on your project.
Thursday, February 8, 2007
2/8 - More UML (use cases, conceptual, state chart diagrams, sequence diagrams
aggregation - an association in which an object is part of a whole
composition - a strong association in which the parts can belong to only one whole
visibility and scope
a constraint is a condition that every implementation of the design must satisfy
sequence diagram
+ class and object diagram are static model views
+ interaction diagrams are dynamic; they describe how objects collaborate
+ a sequence diagram is an interaction diagram that details how operations are carried out, i.e. what messages are being sent and in what sequence
state chart diagram
+ shows the possible sates of the object and the conditions that cause a transition from a state to another
the beauty of OOP - you design for the interface of a class, NOT an implementation
ask questions of your client; "what do you want in this situation?"
***********************photos of diagrams from lecture notes
2/1 - Review of OOP & Intro to UML + extra credit opp.
Review of the key concepts of object-oriented programming
1) Abstraction - refine away unnecessary details
2) Encapsulation - data and representations are combined in a single entity, an object (user-defined type)
3) Inheritance - create specialized objects from simpler objects (inherit dat and operations from parent and add specific data and operations)
4) Polymorphism - ability to dynamically interchange modules without affecting clients
UML
UML (Unified Modeling Language) is a set of simple graphical notations for describing object-oriented models
+ it's actual uses can from a conceptual tool to a rigorous blueprint
+ goal if UML is independent of the implementation language
9 types of UML diagrams
> use-case diagrams
> class
> object
> sequence
> collaboration
> state chart
> activity
> component
> deployment
+ usually 1-2 paragraph description of what a user does
+ unlikely to have thousands
+ example: a 3 year, $30 mill. project for United Airways had 29 use cases
Example use case: "A patient calls the client to schedule an appointment for a yearly checkup. The receptionist finds the earliest available slot in the schedules the appointment for that time slot."
a use case should consider:
main flows - what happens if everything is ok
alternate flows - what happens in special circumstances
A use case diagram describes what the system does, not how.
+ In the above example, the patient is an actor, a line represents communcation
+ Note that a use case may involve multiple actors or nonhuman actors.
+ Note that an actor represents a role, NOT a specific user or individual.
Image: An example use case diagram

Martin Fowler describes three levels of class diagrams:
1) conceptual
+ a way to represent entities in the system
+ very helpful in the conceptual phase of development
+ there may be very little connection between these high level entities and the classes you'll end up writing
2) specification
+ defines what software must do, the information it must hold and the behavior it must exhibit
3) implementation
+ every single painful detail of classes (e.g. access control, return types, etc.)
+ these are a little bit too much for Fowler and Professor Bistriceanu
Fowler's Maxim: "don't be dogmatic" (use whatever level of detail you find useful to the particular project).
aggregation - An association in which one class belongs to a collection
generalization - An inheritance link indicating one class is the parent (i.e. superclass) of the other.
navigability - Indicates the direction in which an association can be traversed or queried.
multiplicity - Number of possible occurences.
Image: An example class diagram

1) class notes
+ readable
+ commitment to attend all classes
+ make copies for instructor every week
2) special assignment
+ bring w/ for final and attach to your work
+ up to 10-20% boost of final grade
3) class participation
+ helps settle borderline situations
4) submit a problem or more to be included on the midterm or final
+ criteria: non-trival & original
1) Abstraction - refine away unnecessary details
2) Encapsulation - data and representations are combined in a single entity, an object (user-defined type)
3) Inheritance - create specialized objects from simpler objects (inherit dat and operations from parent and add specific data and operations)
4) Polymorphism - ability to dynamically interchange modules without affecting clients
UML
UML (Unified Modeling Language) is a set of simple graphical notations for describing object-oriented models+ it's actual uses can from a conceptual tool to a rigorous blueprint
+ goal if UML is independent of the implementation language
9 types of UML diagrams
> use-case diagrams
> class
> object
> sequence
> collaboration
> state chart
> activity
> component
> deployment
Use Cases
A use case is a textual description of major activities that take place in a system.+ usually 1-2 paragraph description of what a user does
+ unlikely to have thousands
+ example: a 3 year, $30 mill. project for United Airways had 29 use cases
Example use case: "A patient calls the client to schedule an appointment for a yearly checkup. The receptionist finds the earliest available slot in the schedules the appointment for that time slot."
a use case should consider:
main flows - what happens if everything is ok
alternate flows - what happens in special circumstances
Use Case Diagrams
A use case diagram describes what the system does, not how.
+ In the above example, the patient is an actor, a line represents communcation
+ Note that a use case may involve multiple actors or nonhuman actors.
+ Note that an actor represents a role, NOT a specific user or individual.
Image: An example use case diagram

Class Diagrams
Martin Fowler describes three levels of class diagrams:
1) conceptual
+ a way to represent entities in the system
+ very helpful in the conceptual phase of development
+ there may be very little connection between these high level entities and the classes you'll end up writing
2) specification
+ defines what software must do, the information it must hold and the behavior it must exhibit
3) implementation
+ every single painful detail of classes (e.g. access control, return types, etc.)
+ these are a little bit too much for Fowler and Professor Bistriceanu
Fowler's Maxim: "don't be dogmatic" (use whatever level of detail you find useful to the particular project).
modeling relationships
association - If one class must know about an instance of another class to perform its function, then there is an association between the two classes.aggregation - An association in which one class belongs to a collection
generalization - An inheritance link indicating one class is the parent (i.e. superclass) of the other.
navigability - Indicates the direction in which an association can be traversed or queried.
multiplicity - Number of possible occurences.
Image: An example class diagram

Extra Credit Opportunities
1) class notes
+ readable
+ commitment to attend all classes
+ make copies for instructor every week
2) special assignment
+ bring w/ for final and attach to your work
+ up to 10-20% boost of final grade
3) class participation
+ helps settle borderline situations
4) submit a problem or more to be included on the midterm or final
+ criteria: non-trival & original
Subscribe to:
Posts (Atom)