480 likes | 615 Views
Housekeeping. SVN Mandatory for project Will be a spot check in the next couple of weeks to identify whether “software craftmanship” is being practiced Individual design reviews due by Monday at 3pm (can submit earlier) All groups have provided access Milestone 5 will be out tomorrow.
E N D
Housekeeping • SVN • Mandatory for project • Will be a spot check in the next couple of weeks to identify whether “software craftmanship” is being practiced • Individual design reviews due by Monday at 3pm (can submit earlier) • All groups have provided access • Milestone 5 will be out tomorrow
Assessing the quality of implementations Verification Validation • Code inspection • Pair programming • Testing
Supporting and Competing Relationships Supporting Competing • Security/reliability • Scalability/flexibility • Security/robustness • Robustness/reliability • Efficiency/security • Efficiency/robustness • Efficiency/scalability • Efficiency/reliability • Efficiency/flexibility • Efficiency/reusability • Reliability/flexibility
Sufficiency • Measures the percentage of the requirements and design specifications actually implemented • Expect to implement all, but generally prioritize in importance due to time constraints • Can calculate with a completely specified list of detailed requirements • Percentage of detailed requirements that are implemented • Percentage of methods specified in the design that are implemented • Percentage of classes specified in the design that are implemented
Robustness • Extent to which it handles anomalous input (unexpected form or content) • Assessment process: • Assess input to the method • Anomalous parameter values • Anomalous global variables • Anomalous event variables • Assess dependent methods: • Measure the extent of compromise • Investigate the pre-conditions (complete?) • Investigate whether the method defends against violations of the pre-conditions • Note: we have a need for documented pre-conditions!
Flexibility • How well does it easily accommodate new or changed requirements? • Methods of increasing flexibility: • Document precisely and thoroughly • Name constants • Hide where possible (variables, methods) • Collect common code (as helper methods and classes) • Reduce dependency on global/external variables (parameterize methods) • Program at a general level • Use understandable variable and function names
Reusability • Capacity for its use in other applications • Making a component more flexible usually makes it more reusable • Possible at the level of method, class, or package • Method of increasing reusability: • Match classes to a real-world concept • Make level of abstraction high enough to cover many applications, but low enough to allow substance • Increase the degree of the description. Reliability of the code promotes reusability – should contain complete error checking
Efficiency • Two kinds: process speed & storage use • Requirements should be specified in SRS • If not, use common sense limits (space & time are not unlimited in practice) • Metrics: • Speed efficiency: fraction of the speed required • Required: 0.5 sec., actual: 2, efficency = 0.5/2=25% • 100% is success baseline • Similar for space efficiency: req/actual = %
Reliability • Goes further than sufficiency and robustness • Need to be sure that it does what it is supposed to (sufficiency) and also behave appropriately in the presence of anomalous input (robustness) • Even sufficient and robust applications may have defects and be less reliable than required • Example: app to add any pair of integers between +/- 100K • Sufficient: it adds them • Robust: displays an error if outside the range • Unreliable: has a memory leak that causes it to crash after running for an hour • MT to failure = total time running/# of failures in that time
Scalability • It is scalable if it is sufficient for all reasonably anticipated homogenous growth (in line with current capability) • Works for 1 record/second, will it work for 1K records per second (max anticipated data rate)? • Can be difficult to assess through inspections • Early testing can be expensive/impractical (difficult to create the scaled up environment) • Metrics measure speeds and data storage in simulated/accelerated environments
Security • Important when connected to networked parts, dealing with confidential data • E.g., Login security challenges: • Store ID/passwords w/o allowing unauthorized access • Ensure that data go only to authorized requesters • Design so that security is easily maintained as application evolves • Isolate security-affecting classes? • Metrics for security: confidentiality, non-repudiation, integrity, authentication, authorization
Code inspections • Tool for producing high quality code • Code is reviewed by team of peers with the goal of identifying as many defects as possible of as high a severity as possible • Typically conducted after code is written, but before it is unit tested • Should first be desk-checked by author • Should compile with no errors or warnings
Inspection process • Author distributes code to group of reviewers • Sometimes and overview meeting to present an overview of the code, its layout, the overall design – provides perspective for review • Individual review • Inspection meeting: • Facilitator leads the group through the code • For each block, inspectors raise issues • If issue is agreed to be a defect, noted • Faults are recorded, but not solved (that is the author’s job)
Code Inspection Checklist A • Variables • Meaningful names • Named constants • Read-only variables declared const or final • All variables used? • Functions • Meaningful names? • Are all parameters used?
Code Inspection Checklist B • Correctness • Are all parentheses & brackets properly matched? • Do all switch statements terminate with a break? Is there a default case? • Initialization • Are variables initialized before their first use? • Dynamic Allocation • Is every dynamically allocated piece of memory properly de-allocated?
Code Inspection Checklist C • Loops • Do all loops successfully terminate? • If used, do break and continue statements work correctly? • Does the body of the loop modify the loop variables? • Pointers • Can a null pointer be de-referenced?
Code Inspection Checklist D • 8. Comments • Is the code properly commented? • Do the comments accurately describe the corresponding code? • 9. Defensive Programming • Are checks made to prevent errors such as divide by zero or illegal data?
Summary • To assess quality of implementation, useful to categorize its qualities • Consider its sufficiency, robustness, flexibility, reusability, efficiency, reliability, scalability, and security • Various metrics to measure the extent of each of these in the application • Code inspections are used to detect and fix defects in the code as close to their injection point as possible • Checklists guide reviewers
Acknowledgements • Material in this presentation was drawn from Martin Fowler, Refactoring: Improving the Design of Existing Code
Definition • Process of altering source code so as to leave its functionality unchanged • Why refactor? • Improve maintainability, especially enhancement • When to refactor? • Considered as soon as code writing begins • Essential part of most agile approaches • Refactor only with valid unit tests in place – need to ensure that refactoring does not break working code
Refactoring is… Refactoring is NOT… • Small, behaviour-preserving, incremental and safe steps • Improving the design of existing code • Making it more understandable and/or flexible • Breaking a large method into smaller, more focused methods • Renaming variables and parameters to be meaningful • Moving a responsibility from one class to a more appropriate one • Creating an interface, based on the methods in one class, and making that class implement the new interface • An excuse to go back and “fill in the blanks” in your application • Improving (adding) error handling • Adding logging • Cramming in another feature • Enhancing the test coverage http://twasink.net/blog/2004/05/refactoring-vs-re-architecting-vs-redesign-vs-rewriting/
Code smells • A code smell is a hint that something is wrong in your code • Use the smell to track down the problem • Differing view points: • Pragmatist: consider code smells on a case by case basis • Purist: all code smells should be avoided without exception • http://c2.com/xp/CodeSmell.html
How to identify code smells? • Experience • Regular code review • Code metrics: • E.g., cyclomatic complexity (# of decision points + 1) • http://www.codeproject.com/KB/architecture/practicalexp.aspx?display=Print • Tools: • http://multiview.cs.pdx.edu/refactoring/smells/
Last class: code smells • How to recognize them? • Experience • Taxonomy (handout) • Helps provide an understanding of the smells and to recognize the relationships between then • Tools: • http://multiview.cs.pdx.edu/refactoring/smells/
Refactoring Catalog • http://www.refactoring.com/catalog/ • List of factorings from Fowlers original book and later sources • How do you get from code smells to refactoring? • Java.net SmellsToRefactorings (handout)
Exercise • From Fowler’s book • Handouts • http://david.koontz.name/home/Projects/Entries/2008/4/13_Photo_of_the_Day_files/Refactoring_FirstExample.zip • Step 1: Familiarize yourself with the classes for a movie rental store (Movie, Rental, Customer) • Step 2: Review the tests that have been set up. Think about why they are important
Exercise • Step 3: Can you identify any code smells?
Consolidate Conditional Expression • Multiple conditionals can be extracted into method • Don’t do if conditions are really independent • Example BEFORE double diasabilityAmount() { if (_seniority < 2) return 0; if (_monthsDisabled > 12) return 0; if (_isPartTime) return 0; if (_isVeteran) return 50; // Calculate disability amount AFTER double diasabilityAmount() { if (isNotEligibleForDisability) return 0; if (_isVeteran) return 50; // Calculate disability amount
Duplicate Observed Data • Problem: You have data stored in a GUI component and domain methods need access • Solution: Copy the data into a domain object (so the methods can access it) and use an Observer to keep the two locations synchronized
Extract Class • Remove a piece of a class and make it a separate class • Done when class is too big to understand easily or behavior is not narrowly defined enough • Indicated by having subsets of data & methods that go together, are changed together, or are dependent on each other • Ask “What if I removed this? What would become useless?”
Extract Interface • Define an interface to move away from a concrete implementation • Allows easier use of differing databases or MockObjects
Extract Method • Pull code out into a separate method when the original method is long or complex • Name the new method so as to make the original method clearer • Each method should have just one task • http://www.refactoring.com/catalog/extractMethod.html
Extract Subclass • Used when a class has some behavior used for some instances and not for others • Make a subclass that inherits the common functionality
Introduce Assertion • Make implicit assumptions in the code explicit • http://www.refactoring.com/catalog/introduceAssertion.html
Introduce Explaining Variable • Break up complex expressions into chunks with clarifying names • http://www.refactoring.com/catalog/introduceExplainingVariable.html
Introduce Parameter Object • Replace a group of parameters that go together with an object • Makes long parameter lists shorter & easier to understand • Can indicate functionality to move to new class • http://www.refactoring.com/catalog/introduceParameterObject.html
Preserve Whole Object • Send the whole object rather than long lists of values obtained from the object • May increase dependency • A method that uses multiple values from another class should be examined to determine if the method should be moved instead • http://www.refactoring.com/catalog/preserveWholeObject.html
Rename Method • Method names should clearly communicate the one task that the method performs • If you are having trouble naming the method, it might be doing too much. Try extracting other methods first
Replace Conditional with Polymorphism • Replace switch statements with polymorphic subclasses (or push case behavior down to existing subclasses) • http://www.refactoring.com/catalog/replaceConditionalWithPolymorphism.html
Replace Magic Number with Symbolic Constant • Replace hard-coded literal values with constants • Avoids duplication and shotgun surgery • http://www.refactoring.com/catalog/replaceMagicNumberWithSymbolicConstant.html
Replace Nested Conditional with Guard Clauses • In some conditionals, both paths are normal behavior & the code just needs to pick one • Other conditionals represent uncommon behavior • Use if/else with the normal behavior paths & guard clauses with uncommon behavior • http://www.refactoring.com/catalog/replaceNestedConditionalWithGuardClauses.html
Replace Parameter with Method • A routine invokes a method just to pass the result of that method on to another method • Let the 2nd method call the first method directly (if it can) • http://www.refactoring.com/catalog/replaceParameterWithMethod.html
DeMorgan’s Law • Used for simplifying boolean expressions • !(a && b) => (!a) || (!b) • !(a || b) => (!a) && (!b)
Further resources • http://www.refactoring.com • http://c2.com/cgi/wiki?CodeSmell