Principles of Software Construction: Objects, Design, and Concurrency (Part 2: Designing (Sub-)Systems) More Analysis for Functional Correctness Christian Kästner Bogdan Vasilescu School of Computer Science 15-214 1
Administrativa • Review sessions started yesterday – There are still many slots for review sessions – Once you signed up, please look up the place of the review session in the course calendar https://www.cs.cmu.edu/~ckaestne/15214/s2017/ – If there are office hours and review sessions in parallel, the signup is for the review session • Homework is due on Thursday. 15-214 2
Learning Goals • Basic understanding of refactoring • Integrating unit testing into the design process • Understanding and applying coverage metrics to approximate test suite quality; awareness of the limitations • Basic understanding of the mechanisms and limitations of static analysis tools • Characterizing assurance techniques in terms of soundness and completeness 15-214 3
Correctness? 15-214 4
Software Errors • Functional errors • Design defects • Performance errors • Versioning and configuration errors • Deadlock • Hardware errors • Race conditions • State management errors • Boundary errors • Metadata errors • Buffer overflow • Error-handling errors • Integration errors • User interface errors • Usability errors • API usage errors • Robustness errors • … • Load errors 15-214 5
Software Errors • Functional errors • Design defects • Performance errors • Versioning and configuration errors • Deadlock • Hardware errors • Race conditions • State management errors • Boundary errors • Metadata errors • Buffer overflow • Error-handling errors • Integration errors • User interface errors • Usability errors • API usage errors • Robustness errors • … • Load errors 15-214 6
CODE SMELLS 15-214 7
Bad Smells -> Design Defects • Bad Smells indicate that your code is ripe for refactoring • Refactoring is about how to change code by applying refactorings • Bad smells are about when to modify it 15-214 8
Bad Smells: Classification • Top crime: code duplication • Class / method organization – Large class, Long Method , Long Parameter List, Lazy Class, Data Class, ... • Lack of loose coupling or cohesion – Inappropriate Intimacy, Feature Envy , Data Clumps, ... • Too much or too little delegation – Message Chains, Middle Man , ... • Non Object-Oriented control or data structures – Switch Statements, Primitive Obsession, ... • Other: Comments 15-214 9
Code duplication (1) Class Class Method 1 Method 1 code • Extract MethodX(); method code MethodX(); • Rename method Method 2 Method 2 MethodX(); code Method 3 MethodX(); Method 3 code Method X code 15-214 10
Code duplication (2) Class Subclass A Subclass B Method Method code code Same expression in two sibling classes: • Same code: Extract method + Pull up field • Similar code: Extract method + Form Template Method • Different algorithm: Substitute algorithm 15-214 11
Code duplication (3) ClassA ClassB MethodA MethodB code code 15-214 12
Code duplication (3) ClassA ClassB MethodA MethodB ClassX.MethodX(); ClassX.MethodX(); ClassX MethodX code Same expression in two unrelated classes: • Extract class • If the method really belongs in one of the two classes, keep it there and invoke it from the other class 15-214 13
Long method //700LOC public boolean foo() { try { synchronized () { if () { • Remember this? } else { } for () { if () { if () { if () { if ()? { if () { for () { } } } } else { if () { for () { if () { } else { } if () { } else { if () { } } if () { if () { if () { for () { } } Source: } http://thedailywtf.com/Articles/Coding-Like-the-Tour-de-France.aspx } else { } 15-214 14 } } else {
Refactoring a long method void printOwing() { Enumeration e = _orders.elements(); double outstanding = 0.0; // Print banner System.out.println(“******************“); System.out.println(“***** Customer *****“); System.out.println(“******************“); // Calculate outstanding While (e.hasMoreElements()) { Order each = (Order) e.nextElement(); outstanding += each.getAmount(); } // Print details System.out.println(“name: “ + _name); System.out.println(“amount” + outstanding); } 15-214 15
Refactoring a long method void printOwing() { Enumeration e = _orders.elements(); double outstanding = 0.0; // Print banner System.out.println(“******************“); System.out.println(“***** Customer *****“); System.out.println(“******************“); // Calculate outstanding While (e.hasMoreElements()) { Order each = (Order) e.nextElement(); outstanding += each.getAmount(); } // Print details System.out.println(“name: “ + _name); System.out.println(“amount” + outstanding); } 15-214 16
Refactoring a long method void printOwing() { Enumeration e = _orders.elements(); double outstanding = 0.0; printBanner(); // Calculate outstanding While (e.hasMoreElements()) { Order each = (Order) e.nextElement(); outstanding += each.getAmount(); } // Print details System.out.println(“name: “ + _name); System.out.println(“amount” + outstanding); } Extract method void printBanner(){ System.out.println(“******************“); System.out.println(“***** Customer *****“); System.out.println(“******************“); } Compile and test to see whether I've broken anything 15-214 17
Refactoring a long method void printOwing() { Enumeration e = _orders.elements(); double outstanding = 0.0; printBanner(); // Calculate outstanding While (e.hasMoreElements()) { Order each = (Order) e.nextElement(); outstanding += each.getAmount(); } // Print details System.out.println(“name: “ + _name); System.out.println(“amount” + outstanding); } void printBanner(){…} 15-214 18
Refactoring a long method void printOwing() { Enumeration e = _orders.elements(); double outstanding = 0.0; printBanner(); // Calculate outstanding While (e.hasMoreElements()) { Order each = (Order) e.nextElement(); outstanding += each.getAmount(); } Extract method printDetails(outstanding); } using local variables void printBanner(){…} void printDetails(outstanding){ System.out.println(“name: “ + _name); System.out.println(“amount” + outstanding); } Compile and test to see whether I've broken anything 15-214 19
Refactoring a long method void printOwing() { Enumeration e = _orders.elements(); double outstanding = 0.0; printBanner(); // Calculate outstanding While (e.hasMoreElements()) { Order each = (Order) e.nextElement(); outstanding += each.getAmount(); } printDetails(outstanding); } void printBanner(){…} void printDetails(outstanding){ System.out.println(“name: “ + _name); System.out.println(“amount” + outstanding); } 15-214 20
Refactoring a long method void printOwing() { Enumeration e = _orders.elements(); double outstanding = getOutstanding(); printBanner(); printDetails(outstanding); } void printBanner(){…} void printDetails(outstanding){…} Extract method double getOutstanding() { reassigning a local Enumeration e = _orders.elements(); variable double result = 0.0; While (e.hasMoreElements()) { Order each = (Order) e.nextElement(); result += each.getAmount(); } return result; } Compile and test to see whether I've broken anything 15-214 21
Many More Bad Smells • Top crime: code duplication • Class / method organization – Large class, Long Method , Long Parameter List, Lazy Class, Data Class, ... • Lack of loose coupling or cohesion – Inappropriate Intimacy, Feature Envy , Data Clumps, ... • Too much or too little delegation – Message Chains, Middle Man , ... • Non Object-Oriented control or data structures – Switch Statements, Primitive Obsession, ... • Other: Comments 15-214 22
BACK TO FUNCTIONAL CORRECTNESS 15-214 23
Reminder: Functional Correctness • The compiler ensures that the types are correct (type checking) – Prevents “Method Not Found” and “Cannot add Boolean to Int” errors at runtime • Static analysis tools (e.g., FindBugs) recognize certain common problems – Warns on possible NullPointerExceptions or forgetting to close files • How to ensure functional correctness of contracts beyond? 15-214 24
Formal Verification • Proving the correctness of an implementation with respect to a formal specification, using formal methods of mathematics. • Formally prove that all possible executions of an implementation fulfill the specification • Manual effort; partial automation; not automatically decidable 15-214 25
Testing • Executing the program with selected inputs in a controlled environment (dynamic analysis) • Goals: – Reveal bugs (main goal) – Assess quality (hard to quantify) – Clarify the specification, documentation – Verify contracts "Testing shows the presence, not the absence of bugs Edsger W. Dijkstra 1969 15-214 26
Testing Decisions • Who tests? – Developers – Other Developers – Separate Quality Assurance Team – Customers • When to test? – Before development – During development – After milestones – Before shipping • When to stop testing? (More in 15-313) 15-214 27
TEST-DRIVEN DEVELOPMENT 15-214 28
Recommend
More recommend