Download presentation
Presentation is loading. Please wait.
1
Object/Class Design
2
Principles of straight-line code
Make dependences obvious: (e.g., through passing arguments, return values) firstResult = doThing1(); secondResult = doThingY(firstResult); Vs. doThing1(); doThingY();
3
Grouping related items (example)
Ordering implicit, but emphasizes grouping MarketingData marketingData = new MarketingData(); marketingData.ComputeQuarterly(); marketingData.ComputeAnnual(); marketingData.Print(); SalesData salesData = new SalesData(); salesData.ComputeQuarterly(); salesData.ComputeAnnual(); salesData.Print();
4
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 dashFound = false; for (String arg : args) { if (arg.equals("-")) { dashFound = true; } else if (!dashFound) { process1(arg); } else { process2(arg); } } B int i = 0; while(i < args.length && !args[i].equals("-")) { process1(args[i]); i++; } i++; // skip the dash for( ; i < args.length ; i++) { process2(args[i]); } C Control flow is fine for both D Control flow is problematic for both
5
Which is better? A public int[] copyIntArray(int[] input) { int [] copy = new int[input.length]; int i = 0; for (int value: input) { copy[i++] = value; } return copy; } B public int[] copyIntArray(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
6
Which is best? A if (getAmountOfGasInTank() >= gasNeeded(destination)) { // avoid unnecessary stops; reduce wear on engine } else { fillGasTank(); } if (getAmountOfGasInTank() < gasNeeded(destination)) { fillGasTank(); } else { // avoid unnecessary stops; reduce wear on engine } B if (gasNeeded(destination) < getAmountOfGasInTank()) { // avoid unnecessary stops; reduce wear on engine } else { fillGasTank(); } C B preferred. Reasons: don't have empty if clauses okay to have empty else clause with comments to explain why nothing is needed getAmountOfGasInTank is more variable and that goes as the left arg if (gasNeeded(destination) >= getAmountOfGasInTank()) { fillGasTank(); } else { // avoid unnecessary stops; reduce wear on engine } D
7
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
8
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
9
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
10
Keep Coupling Loose small interfaces (few methods, few arguments/method) obvious (interactions through parameter passing) flexible
11
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
12
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
13
hasA vs. isA relationship
Which is a candidate for inheritance? A) hasA relationship B) isA relationship C) both hasA and isA relationships D) neither hasA and isA relationships
14
Inheritance vs. Interfaces
Inheritance should be a isA relationship Interfaces are for capabilities (“mixin”s)
15
Designing Good Interfaces
Sufficiently Expressive General Minimal
Similar presentations
© 2025 SlidePlayer.com Inc.
All rights reserved.