240 likes | 257 Views
cs205: engineering software university of virginia fall 2006. Design. David Evans www.cs.virginia.edu/cs205. Midterm Comments. Question 2: what can you say about a program that passes its test cases?. Very little: “It worked on those test cases in that execution environment.”
E N D
cs205: engineering software university of virginia fall 2006 Design David Evans www.cs.virginia.edu/cs205
Midterm Comments • Question 2: what can you say about a program that passes its test cases? Very little: “It worked on those test cases in that execution environment.” It might not work on different inputs. It might not even work on the same inputs with a different execution environment (hidden inputs).
Testing • Does this mean testing is useless? No, it is necessary. It finds some obvious bugs. It increases confidence, but is not enough to support any strong correctness claims for non-trivial software.
Nullifying null • A very strange beast! • null matches any Object type (including arrays which are Object types) • Except: null instanceof T is always false • No method can be invoked on null (generates NullPointerException)
null puzzle 1 Object obj = null; String s = (String) obj; if (!(s instanceof String)) { launchMissiles(); } Yes, it launches the missiles! An object with apparent type String might not be instanceof String!
null puzzle 2 publicclass NullPuzzle { publicstaticvoid method(int [] x) { System.out.println("Array"); } publicstaticvoid method(String s) { System.out.println("String"); } publicstaticvoid main (String [] args) { method(null); } } Compiler error: The method method(int[]) is ambiguous for the type NullPuzzle
null puzzle 2b publicclass NullPuzzle { publicstaticvoid method(int [] x) { System.out.println("Array"); } publicstaticvoid method(String s) { System.out.println("String"); } publicstaticvoid main (String [] args) { method((Object) null); } } Compiler error: The method method(int[]) is not applicable for the arguments (Object)
null puzzle 2c publicclass NullPuzzle { publicstaticvoid method(int [] x) { System.out.println("Array"); } publicstaticvoid method(String s) { System.out.println("String"); } publicstaticvoid main (String [] args) { method((int []) null); } } Array
Problems null causes • Every method that invokes a method on an object, either needs a precondition to guarantee the object is non-null or needs to deal with it • Rep invariants: usually need to require all reachable objects are non-null If null causes so many problems, why does Java have it?
Design Criteria • Human Understandability • Cost/Time to Implement • Independence of Modules • Decoupled modules can be developed and tested independently • Ability to Change • Requirements for software change, poorly designed software is hard/impossible to change
Modular Dependency Diagrams • Show the component modules • How is the program organized? • Show the dependencies between them • How do modules depend on each other? • Why do we want to know?
Using MDDs • Design Time • Consider different designs • If the MDD has lots of cycles, crossings, etc. the design is not decoupled enough • Implementation • Organize the implementation • Testing • Where do you look when a test fails? • Maintenance • What modules must be considered when specification of one changes?
MDD Notation Module Usually a Java class GUI
MDD Notation GUI depends on the specification of Filter
Code MDD • If A calls a method of B, then A depends on the specification of B • If the specification of B changes, we need to reconsider A • If A mentions the class B, but doesn’t call any methods or access fields, then A weakly depends on B • If the specification of B changes, we don’t need to reconsider A. A B A B
GridDisplay Cell PS1 Module Dependency Diagram CellAutomata is a subtype of (extends) Grid ConwayLifeCell CellState Is this is “good” design?
Cell Evaluating Designs Circular Dependency: Grid depends on Cell Cell depends on Grid Grid
Why are circular dependencies bad? • Need to finish both modules before you can test them (can use stub versions for testing) • If a test fails, may be hard to figure out which module is at fault • If spec of one changes, need to reconsider other module, but what if its spec changes as a result? • But…sometimes unavoidable • Challenge: come up with a better design for PS1 (worth 100 bonus points!)
Conflicting Goals • Modules: • Too many modules: lots of dependencies, overall design too complex to understand • Too few modules: hard to divide, each module may be too big to implement • Dependencies: • Close coupling is bad: too many dependencies makes independent development and testing hard • Reuse is good: too few dependencies limits opportunities for reuse
Design Problem Imagine that you are designing the program to generate VISTAA reports (that show what courses a student has completed and what requirements remain to be completed to complete a degree). What modules do you need? What are the dependencies and subclass relationships between them? Develop and document a high-level design for your VISTAA implementation.
Summary • No absolute rules, no magic • Important thing is that you can justify your design by explaining why it is better than alternatives • A good design will make implementation (relatively) easy, a bad design will make implementation impossible