ObjectClass Design 1 Principles of straightline code Make
Object/Class Design 1
Principles of straight-line code ¢ Make dependences obvious: (e. g. , through passing arguments, return values) first. Result = do. Thing 1(); second. Result = do. Thing. Y(first. Result); ¢ Vs. do. Thing 1(); do. Thing. Y(); 2
Grouping related items (example) ¢ Ordering implicit, but emphasizes grouping Marketing. Data marketing. Data = new Marketing. Data(); marketing. Data. Compute. Quarterly(); marketing. Data. Compute. Annual(); marketing. Data. Print(); Sales. Data sales. Data = new Sales. Data(); sales. Data. Compute. Quarterly(); sales. Data. Compute. Annual(); sales. Data. Print(); 3
Which is better? This code takes an array of strings, it processes all of the strings before a dash one way and all of the remaining strings another way. Assume there is only one dash in the array of strings. A boolean dash. Found = false; for (String arg : args) { if (arg. equals("-")) { dash. Found = true; } else if (!dash. Found) { process 1(arg); } else { process 2(arg); } } B int i = 0; while(i < args. length && !args[i]. equals("-")) { process 1(args[i]); i++; } i++; // skip the dash for( ; i < args. length ; i++) { process 2(args[i]); } C Control flow is fine for both D Control flow is problematic for 4
Which is better? A public int[] copy. Int. Array(int[] input) { int [] copy = new int[input. length]; int i = 0; for (int value: input) { copy[i++] = value; } return copy; } B public int[] copy. Int. Array(int[] input) { int [] copy = new int[input. length]; for (int i = 0; i < input. length; i++) { copy[i] = input[i]; } return copy; } C Control flow is fine for both D Control flow is problematic for both 5
Which is best? A if (get. Amount. Of. Gas. In. Tank() >= gas. Needed(destination)) { // avoid unnecessary stops; reduce wear on engine } else { fill. Gas. Tank(); } if (get. Amount. Of. Gas. In. Tank() < gas. Needed(destination)) { fill. Gas. Tank(); B } else { // avoid unnecessary stops; reduce wear on engine } if (gas. Needed(destination) < get. Amount. Of. Gas. In. Tank()) { // avoid unnecessary stops; reduce wear on engine C } else { fill. Gas. Tank(); } if (gas. Needed(destination) >= get. Amount. Of. Gas. In. Tank()) { fill. Gas. Tank(); D } else { // avoid unnecessary stops; reduce wear on engine } 6
Design is hard ¢ ¢ Design is an art, not a science Large/infinite design space, not enumerable Requirements, constraints, trade-offs, and priorities You get better with practice / experience / seeing good design / hearing critiques of others designs 7
Virtues of a good design (software) ¢ ¢ ¢ ¢ Manages complexity Loose coupling Reusability Ease of maintenance Standard techniques Extensibility High Fan-in Low-to-medium Fan-out 8
Good Design Manages Complexity ¢ ¢ ¢ “Seven plus or minus two” (Miller’s Law) The goal of all software-design techniques § Break complicated problems into simple problems Separation of concerns § Focus on one at a time 9
Keep Coupling Loose ¢ ¢ ¢ small interfaces (few methods, few arguments/method) obvious (interactions through parameter passing) flexible 10
Abstract Data Types ¢ ¢ Define a class based around conceptual structures § Encapsulation / information-hiding § Make interfaces more informative (self-documenting) § Easier to reason about correctness Treat even simple items as ADTs § Good for extensibility 11
Inheritance can provides 2 things ¢ Shared interface: § Public methods § Ensure methods have consistent meaning in derived class § ¢ Liskov Substitution Principle Shared implementation § Code in shared super class, not replicated in each derived § Could be private data/methods 12
has. A vs. is. A relationship Which is a candidate for inheritance? A) B) C) D) has. A relationship is. A relationship both has. A and is. A relationships neither has. A and is. A relationships 13
Inheritance vs. Interfaces ¢ Inheritance should be a is. A relationship ¢ Interfaces are for capabilities (“mixin”s) 14
Designing Good Interfaces ¢ ¢ ¢ Sufficiently Expressive General Minimal 15
- Slides: 15