Download presentation
Presentation is loading. Please wait.
1
STREAM STREAM A software process The Mañana Principle The Mañana Principle Don’t try to everything at once! Static Methods Static Methods Stateless Utility Functions
2
S T R E A M S tubs T ests R epresentation E valuation A ttributes M ethods
3
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling Example Wanted: a class to represent a Date. Wanted: a class to represent a Date. Must have the following two methods: Must have the following two methods: - setToNextDay : no parameters - toString : no parameters, returns String with format “ - - ”
4
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 1. Stubs class Date { /** * Advance the date to the next day */ public void setToNextDay () { } /** * @return A representation of this date * in the format - - */ public String toString () { return null; } } This will compile!
5
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 2. Tests The Date class can already be compiled. Using BlueJ, we can immediately create an instance and start testing its methods. Of course, they won’t do much just yet! Make a list of some simple tests we would like to make. To carry out those tests, what else will we need in the Date class? We’ll need a way to set a particular date – only then can we tell if setToNextDay and toString work.
6
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 2. Tests So, just by thinking about testing, we see the need for another method. This is cohesion in action! class Date { /** * Set the date to a particular day */ public void setDate (int day, int month, int year) { }... setToNextDay method (as before)... toString method (as before) }
7
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 3. Representations R1: use three integer fields - day (1..31), month (1..12), year (1..) R1: use three integer fields - day (1..31), month (1..12), year (1..) R2: use one integer field - the number of days since 1 st. January, 1970 R2: use one integer field - the number of days since 1 st. January, 1970 Many others are possible …
8
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 3. Evaluate R1: use three integer fields - day (1..31), month (1..12), year (1..) R1: use three integer fields - day (1..31), month (1..12), year (1..) R2: use one integer field - the number of days since 1 st. January, 1970 R2: use one integer field - the number of days since 1 st. January, 1970 Implementation Effort R1R2setToNextDay toString
9
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling TEACH The TEACH Scale difficulty TrivialTrivial EasyEasy AverageAverage ChallengingChallenging HardHard
10
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 3. Evaluate R1: use three integer fields - day (1..31), month (1..12), year (1..) R1: use three integer fields - day (1..31), month (1..12), year (1..) R2: use one integer field - the number of days since 1 st. January, 1970 R2: use one integer field - the number of days since 1 st. January, 1970 Implementation Effort R1R2setToNextDay toString Challenging HardTrivial
11
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 5. Attributes (we call them fields) class Date { private int day; // 1 ≤ day ≤ daysInMonth private int month; // 1 ≤ month ≤ 12 private int year; // 1 ≤ year... setDate (as before)... setToNextDay method (as before)... toString method (as before) } R1: use three integer fields - day (1..31), month (1..12), year (1..) R1: use three integer fields - day (1..31), month (1..12), year (1..)
12
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 5. Attributes (we call them fields) class Date { private int date; // days since 1970-01-01... setDate (as before)... setToNextDay method (as before)... toString method (as before) } R2: use one integer field - the number of days since 1 st. January, 1970 R2: use one integer field - the number of days since 1 st. January, 1970
13
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling class Date { private int day; // 1 ≤ day ≤ daysInMonth private int month; // 1 ≤ month ≤ 12 private int year; // 1 ≤ year... setDate and setToNextDay methods /** * @return A representation of this date * in the format - - */ public String toString () { } } class Date { private int day; // 1 ≤ day ≤ daysInMonth private int month; // 1 ≤ month ≤ 12 private int year; // 1 ≤ year... setDate and setToNextDay methods /** * @return A representation of this date * in the format - - */ public String toString () { return year + "-" + month + "-" + day; } } 6. Method ImplementationR1 TrivialTrivial
14
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling class Date { private int date; // days since 1970-01-01... setDate and setToNextDay methods /** * @return A representation of this date * in the format - - */ public String toString () { } } class Date { private int date; // days since 1970-01-01... setDate and setToNextDay methods /** * @return A representation of this date * in the format - - */ public String toString () {... tricky !!! } } 6. Method ImplementationR2 HardHard
15
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling class Date { private int date; // days since 1970-01-01... setDate and toString methods /** * Advance the date to the next day */ public void setToNextDay () { } } class Date { private int date; // days since 1970-01-01... setDate and toString methods /** * Advance the date to the next day */ public void setToNextDay () { date = date + 1; } } 6. Method ImplementationR2 TrivialTrivial
16
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling class Date { private int day; // 1 ≤ day ≤ daysInMonth private int month; // 1 ≤ month ≤ 12 private int year; // 1 ≤ year... setDate and toString methods /** * Advance the date to the next day */ public void setToNextDay () { } } class Date { private int day; // 1 ≤ day ≤ daysInMonth private int month; // 1 ≤ month ≤ 12 private int year; // 1 ≤ year... setDate and toString methods /** * Advance the date to the next day */ public void setToNextDay () { day = day + 1;... more stuff needed } } 6. Method ImplementationR1 ChallengingChallenging
17
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling The Mañana Principle When – during implementation of a method – we wish we had a certain support method, write our code as if we had it. Implement it later.
18
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling When – during implementation of a method – we wish we had a certain support method, write our code as if we had it. Implement it later. Special Case Rule: Often, we need to identify and deal with a special case. Write the code for this in a separate method. Implement it later. The Mañana Principle
19
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling class Date { private int day; // 1 ≤ day ≤ daysInMonth private int month; // 1 ≤ month ≤ 12 private int year; // 1 ≤ year... setDate and toString methods /** * Advance the date to the next day */ public void setToNextDay () { day = day + 1;... more stuff needed } } class Date { private int day; // 1 ≤ day ≤ daysInMonth private int month; // 1 ≤ month ≤ 12 private int year; // 1 ≤ year... setDate and toString methods /** * Advance the date to the next day */ public void setToNextDay () { day = day + 1; checkDayOverflow (); } } 6. Method ImplementationR1 ChallengingChallenging
20
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling /** * Advance the date to the next day */ public void setToNextDay () { day = day + 1; checkDayOverflow (); } /** * Advance the date to the next day */ public void setToNextDay () { day = day + 1; checkDayOverflow (); } /** * Advance the date to the next day */ public void setToNextDay () { day = day + 1; checkDayOverflow (); } /** * Spot and deal with special day case */ private void checkDayOverflow () { if (day > 30) { day = 1; month = month + 1; } } /** * Advance the date to the next day */ public void setToNextDay () { day = day + 1; checkDayOverflow (); } /** * Spot and deal with special day case */ private void checkDayOverflow () { if (day > 30) { day = 1; month = month + 1; } } 6. Method ImplementationR1 ChallengingChallenging IncompleteIncomplete
21
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling /** * Spot and deal with special day case */ private void checkDayOverflow () { if (day > 30) { day = 1; month = month + 1; } } /** * Spot and deal with special day case */ private void checkDayOverflow () { if (day > 30) { day = 1; month = month + 1; } } /** * Spot and deal with special day case */ private void checkDayOverflow () { if (day > 30) { day = 1; month = month + 1; checkMonthOverflow (); } } /** * Spot and deal with special month case */ private void checkMonthOverflow () { if (month > 12) { month = 1; year = year + 1; } } /** * Spot and deal with special day case */ private void checkDayOverflow () { if (day > 30) { day = 1; month = month + 1; checkMonthOverflow (); } } /** * Spot and deal with special month case */ private void checkMonthOverflow () { if (month > 12) { month = 1; year = year + 1; } } R1 IncompleteIncomplete CompleteComplete
22
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling The Mañana Principle Hard Problem Rule: when we need the answer to a problem we cannot immediately solve, defer it a separate method. Implement it later.
23
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling /** * Spot and deal with special day case */ private void checkDayOverflow () { if (day > 30) { day = 1; month = month + 1; checkMonthOverflow (); } } /** * Spot and deal with special day case */ private void checkDayOverflow () { if (day > 30) { day = 1; month = month + 1; checkMonthOverflow (); } } /** * Spot and deal with special day case */ private void checkDayOverflow () { if (day > daysInMonth ()) { day = 1; month = month + 1; checkMonthOverflow (); } } /** * Spot and deal with special day case */ private void checkDayOverflow () { if (day > daysInMonth ()) { day = 1; month = month + 1; checkMonthOverflow (); } } /** * Spot and deal with special day case */ private void checkDayOverflow () { if (day > daysInMonth ()) { day = 1; month = month + 1; checkMonthOverflow (); } } /** * @return The number of days in the month */ private int daysInMonth () { return 30; } /** * Spot and deal with special day case */ private void checkDayOverflow () { if (day > daysInMonth ()) { day = 1; month = month + 1; checkMonthOverflow (); } } /** * @return The number of days in the month */ private int daysInMonth () { return 30; } R1 IncompleteIncomplete CompleteComplete
24
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling class Date { private int day; // 1 ≤ day ≤ daysInMonth private int month; // 1 ≤ month ≤ 12 private int year; // 1 ≤ year... other methods /** * @return The number of days in the month */ private int daysInMonth () { return 30; } } class Date { private int day; // 1 ≤ day ≤ daysInMonth private int month; // 1 ≤ month ≤ 12 private int year; // 1 ≤ year private static final int[] monthDays = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};... other methods /** * @return The number of days in the month */ private int daysInMonth () { return 30; } } class Date { private int day; // 1 ≤ day ≤ daysInMonth private int month; // 1 ≤ month ≤ 12 private int year; // 1 ≤ year private static final int[] monthDays = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};... other methods /** * @return The number of days in the month */ private int daysInMonth () { return monthDays[month – 1]; } } IncompleteIncomplete R1
25
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling class Date {... day, month, year fields private static final int[] monthDays = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};... other methods /** * @return The number of days in the month */ private int daysInMonth () { return monthDays[month – 1]; } } class Date {... day, month, year fields private static final int[] monthDays = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};... other methods /** * @return The number of days in the month */ private int daysInMonth () { int answer = monthDays[month – 1]; if ((month == 2) && isLeapYear ()) { answer = answer + 1; } return answer; } } R1 CompleteComplete
26
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling The Mañana Principle Hard Problem Rule: when we need the answer to a problem we cannot immediately solve, defer it a separate method. Implement it later. Heavy Functionality Rule: when some statements or expressions become too long or complex, move them into a separate method. Implement it later.
27
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling /** * @return The number of days in the month */ private int daysInMonth () { int answer = monthDays[month – 1]; if ((month == 2) && isLeapYear ()) { answer = answer + 1; } return answer; } /** * @return The number of days in the month */ private int daysInMonth () { int answer = monthDays[month – 1]; if ((month == 2) && isLeapYear ()) { answer = answer + 1; } return answer; } /** * @return The number of days in the month */ private int daysInMonth () { int answer = monthDays[month – 1]; if ((month == 2) && isLeapYear ()) { answer = answer + 1; } return answer; } /** * @return Whether the year is a leap year */ private boolean isLeapYear () { return (divides (4, year) && !divides (100, year)) || divides (400, year); } /** * @return The number of days in the month */ private int daysInMonth () { int answer = monthDays[month – 1]; if ((month == 2) && isLeapYear ()) { answer = answer + 1; } return answer; } /** * @return Whether the year is a leap year */ private boolean isLeapYear () { return (divides (4, year) && !divides (100, year)) || divides (400, year); } R1 CompleteComplete CompleteComplete
28
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling /** * @return Whether the year is a leap year */ private boolean isLeapYear () { return (divides (4, year) && !divides (100, year)) || divides (400, year); } /** * @return Whether the year is a leap year */ private boolean isLeapYear () { return (divides (4, year) && !divides (100, year)) || divides (400, year); } /** * @return Whether the year is a leap year */ private boolean isLeapYear () { return (divides (4, year) && !divides (100, year)) || divides (400, year); } /** * @param d The divisor * @param n The number being divided * @return Whether d divides n exactly */ private boolean divides (int d, int n) { return (n % d) == 0; } /** * @return Whether the year is a leap year */ private boolean isLeapYear () { return (divides (4, year) && !divides (100, year)) || divides (400, year); } /** * @param d The divisor * @param n The number being divided * @return Whether d divides n exactly */ private boolean divides (int d, int n) { return (n % d) == 0; } R1 CompleteComplete CompleteComplete
29
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 2. Tests So, just by thinking about testing, we see the need for another method. This is cohesion in action! class Date { /** * Set the date to a particular day */ public void setDate (int day, int month, int year) { }... setToNextDay method (as before)... toString method (as before) } RecallRecall
30
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling class Date { private int day; // 1 ≤ day ≤ daysInMonth private int month; // 1 ≤ month ≤ 12 private int year; // 1 ≤ year /** * Set the date to a particular day */ public void setDate (int day, int month, int year) { }... setToNextDay and toString methods } class Date { private int day; // 1 ≤ day ≤ daysInMonth private int month; // 1 ≤ month ≤ 12 private int year; // 1 ≤ year /** * Set the date to a particular day */ public void setDate (int day, int month, int year) { this.day = day; this.month = month; this.year = year; }... setToNextDay and toString methods } R1 But what if bad values are given?
31
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling /** * Set the date to a particular day */ public void setDate (int day, int month, int year) { this.day = day; this.month = month; this.year = year; } /** * Set the date to a particular day */ public void setDate (int day, int month, int year) { this.day = day; this.month = month; this.year = year; } /** * Set the date to a particular day */ public void setDate (int day, int month, int year) { this.day = day; this.month = month; this.year = year; if (!legalDate ()) { } } /** * Set the date to a particular day */ public void setDate (int day, int month, int year) { this.day = day; this.month = month; this.year = year; if (!legalDate ()) { } } /** * Set the date to a particular day */ public void setDate (int day, int month, int year) { this.day = day; this.month = month; this.year = year; if (!legalDate ()) { this.day = 1; this.month = 1; this.year = 1; System.out.println ("*** setDate: Bad parameters" + "... setting date to" + " 0001-01-01"); } } /** * Set the date to a particular day */ public void setDate (int day, int month, int year) { this.day = day; this.month = month; this.year = year; if (!legalDate ()) { this.day = 1; this.month = 1; this.year = 1; System.out.println ("*** setDate: Bad parameters" + "... setting date to" + " 0001-01-01"); } } defer decision as to what is legal !! CompleteComplete EasyEasy R1
32
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling /** * @return Whether the date fields are legal */ private boolean legalDate () { return ((1 <= day) && (day <= 30)) && ((1 <= month) && (month <= 12)) && (1 <= year); } /** * @return Whether the date fields are legal */ private boolean legalDate () { return ((1 <= day) && (day <= 30)) && ((1 <= month) && (month <= 12)) && (1 <= year); } /** * @return Whether the date fields are legal */ private boolean legalDate () { return ((1 <= day) && (day <= daysInMonth ())) && ((1 <= month) && (month <= 12)) && (1 <= year); } /** * @return Whether the date fields are legal */ private boolean legalDate () { return ((1 <= day) && (day <= daysInMonth ())) && ((1 <= month) && (month <= 12)) && (1 <= year); } BUG: if month is not in the range 1..12, daysInMonth() will crash. R1
33
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling class Date {... day, month, year fields private static final int[] monthDays = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};... other methods /** * @return The number of days in the month */ private int daysInMonth () { return monthDays[month – 1]; } } class Date {... day, month, year fields private static final int[] monthDays = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};... other methods /** * @return The number of days in the month */ private int daysInMonth () { int answer = monthDays[month – 1]; if ((month == 2) && isLeapYear ()) { answer = answer + 1; } return answer; } } Recall … Assumes: month is in the range 1..12. R1
34
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling /** * @return Whether the date fields are legal */ private boolean legalDate () { return ((1 <= day) && (day <= daysInMonth ())) && ((1 <= month) && (month <= 12)) && (1 <= year); } /** * @return Whether the date fields are legal */ private boolean legalDate () { return ((1 <= day) && (day <= daysInMonth ())) && ((1 <= month) && (month <= 12)) && (1 <= year); } R1 /** * @return Whether the date fields are legal */ private boolean legalDate () { return (1 <= year) && ((1 <= month) && (month <= 12)) && ((1 <= day) && (day <= daysInMonth ())); } /** * @return Whether the date fields are legal */ private boolean legalDate () { return (1 <= year) && ((1 <= month) && (month <= 12)) && ((1 <= day) && (day <= daysInMonth ())); } BUG: if month is not in the range 1..12, daysInMonth() will crash. FIXED: operands of && are evaluated left-to-right. If any operand is false, the result is false and remaining operands (if any) are not evaluated.
35
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling S T R E A M S tubs S tubs T ests T ests R epresentation R epresentation E valuation E valuation A ttributes A ttributes M ethods M ethods Our choice of representation can have great impact on the complexity of the logic.
36
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling 5. Attributes (we call them fields) class Date { private int date; // days since 1970-01-01... setDate (as before)... setToNextDay method (as before)... toString method (as before) } R2: use one integer field - the number of days since 1 st. January, 1970 R2: use one integer field - the number of days since 1 st. January, 1970 Seen before
37
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling class Date { private int date; // days since 1970-01-01... setDate and setToNextDay methods /** * @return A representation of this date * in the format - - */ public String toString () {... tricky !!! } } 6. Method ImplementationR2 HardHard Seen before
38
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling class Date { private int date; // days since 1970-01-01... setDate and toString methods /** * Advance the date to the next day */ public void setToNextDay () { date = date + 1; } } 6. Method ImplementationR2 TrivialTrivial Seen before
39
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling class Date { private int date; // days since 1970-01-01... setToNextDay and toString methods /** * Set the date to a particular day */ public void setDate (int day, int month, int year) { } } class Date { private int date; // days since 1970-01-01... setToNextDay and toString methods /** * Set the date to a particular day */ public void setDate (int day, int month, int year) {... tricky !!! } } 6. Method ImplementationR2 HardHard
40
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling /** * Set the date to a particular day */ public void setDate (int day, int month, int year) { this.day = day; this.month = month; this.year = year; if (!legalDate ()) { this.day = 1; this.month = 1; this.year = 1; System.out.println ("*** setDate: Bad parameters" + "... setting date to" + " 0001-01-01"); } } /** * Set the date to a particular day */ public void setDate (int day, int month, int year) { this.day = day; this.month = month; this.year = year; if (!legalDate ()) { this.day = 1; this.month = 1; this.year = 1; System.out.println ("*** setDate: Bad parameters" + "... setting date to" + " 0001-01-01"); } } R1 Seen before But the R2 Date has no day, month or year fields to set … … and legalDate has no fields on which it to operate.
41
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling /** * Set the date to a particular day */ public void setDate (int day, int month, int year) { } /** * Set the date to a particular day */ public void setDate (int day, int month, int year) { } /** * Set the date to a particular day */ public void setDate (int day, int month, int year) { if (legalDate (day, month, year)) {... still tricky !!! } else { date = 1; System.out.println ("*** setDate: Bad parameters" + "... setting date to" + " 1970-01-01"); } } /** * Set the date to a particular day */ public void setDate (int day, int month, int year) { if (legalDate (day, month, year)) {... still tricky !!! } else { date = 1; System.out.println ("*** setDate: Bad parameters" + "... setting date to" + " 1970-01-01"); } } /** * Set the date to a particular day */ public void setDate (int day, int month, int year) { if (legalDate (day, month, year)) { setLegalDate (day, month, year) } else { date = 1; System.out.println ("*** setDate: Bad parameters" + "... setting date to" + " 1970-01-01"); } } /** * Set the date to a particular day */ public void setDate (int day, int month, int year) { if (legalDate (day, month, year)) { setLegalDate (day, month, year) } else { date = 1; System.out.println ("*** setDate: Bad parameters" + "... setting date to" + " 1970-01-01"); } } defer decision as to what is legal !! defer hard logic !! CompleteComplete R2
42
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling /** * Set the date to a particular day * * @param day (assume: 1 ≤ day ≤ daysInMonth) * @param month (assume: 1 ≤ month ≤ 12) * @param year (assume: 1 ≤ year) * */ private void setLegalDate (int day, int month, int year) { } /** * Set the date to a particular day * * @param day (assume: 1 ≤ day ≤ daysInMonth) * @param month (assume: 1 ≤ month ≤ 12) * @param year (assume: 1 ≤ year) * */ private void setLegalDate (int day, int month, int year) { } /** * Set the date to a particular day * * @param day (assume: 1 ≤ day ≤ daysInMonth) * @param month (assume: 1 ≤ month ≤ 12) * @param year (assume: 1 ≤ year) * */ private void setLegalDate (int day, int month, int year) {... still tricky !!! } /** * Set the date to a particular day * * @param day (assume: 1 ≤ day ≤ daysInMonth) * @param month (assume: 1 ≤ month ≤ 12) * @param year (assume: 1 ≤ year) * */ private void setLegalDate (int day, int month, int year) {... still tricky !!! } HardHard R2
43
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling /** * Set the date to a particular day */ public void setDate (int day, int month, int year) { } /** * Set the date to a particular day */ public void setDate (int day, int month, int year) { } /** * Set the date to a particular day */ public void setDate (int day, int month, int year) { if (legalDate (day, month, year)) {... still tricky !!! } else { date = 1; System.out.println ("*** setDate: Bad parameters" + "... setting date to " + " 1970-01-01"); } } /** * Set the date to a particular day */ public void setDate (int day, int month, int year) { if (legalDate (day, month, year)) {... still tricky !!! } else { date = 1; System.out.println ("*** setDate: Bad parameters" + "... setting date to " + " 1970-01-01"); } } /** * Set the date to a particular day */ public void setDate (int day, int month, int year) { if (legalDate (day, month, year)) { setLegalDate (day, month, year) } else { date = 1; System.out.println ("*** setDate: Bad parameters" + "... setting date to" + " 1970-01-01"); } } /** * Set the date to a particular day */ public void setDate (int day, int month, int year) { if (legalDate (day, month, year)) { setLegalDate (day, month, year) } else { date = 1; System.out.println ("*** setDate: Bad parameters" + "... setting date to" + " 1970-01-01"); } } defer decision as to what is legal !! defer hard logic !! CompleteComplete R2
44
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling /** * @param day (legal: 1 ≤ day ≤ daysInMonth) * @param month (legal: 1 ≤ month ≤ 12) * @param year (legal: 1 ≤ year) * * @return Whether the parameters are legal * */ private boolean legalDate (int day, int month, int year) { } /** * @param day (legal: 1 ≤ day ≤ daysInMonth) * @param month (legal: 1 ≤ month ≤ 12) * @param year (legal: 1 ≤ year) * * @return Whether the parameters are legal * */ private boolean legalDate (int day, int month, int year) { } /** * @param day (legal: 1 ≤ day ≤ daysInMonth) * @param month (legal: 1 ≤ month ≤ 12) * @param year (legal: 1 ≤ year) * * @return Whether the parameters are legal * */ private boolean legalDate (int day, int month, int year) { return (1 <= year) && ((1 <= month) && (month <= 12)) && ((1 <= day) && (day <= daysInMonth ())); } /** * @param day (legal: 1 ≤ day ≤ daysInMonth) * @param month (legal: 1 ≤ month ≤ 12) * @param year (legal: 1 ≤ year) * * @return Whether the parameters are legal * */ private boolean legalDate (int day, int month, int year) { return (1 <= year) && ((1 <= month) && (month <= 12)) && ((1 <= day) && (day <= daysInMonth ())); } … but daysInMonth has no month or year fields on which to operate. R2 XX
45
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling /** * @param day (legal: 1 ≤ day ≤ daysInMonth) * @param month (legal: 1 ≤ month ≤ 12) * @param year (legal: 1 ≤ year) * * @return Whether the parameters are legal * */ private boolean legalDate (int day, int month, int year) { return (1 <= year) && ((1 <= month) && (month <= 12)) && ((1 <= day) && (day <= daysInMonth ())); } /** * @param day (legal: 1 ≤ day ≤ daysInMonth) * @param month (legal: 1 ≤ month ≤ 12) * @param year (legal: 1 ≤ year) * * @return Whether the parameters are legal * */ private boolean legalDate (int day, int month, int year) { return (1 <= year) && ((1 <= month) && (month <= 12)) && ((1 <= day) && (day <= daysInMonth ())); } /** * @param day (legal: 1 ≤ day ≤ daysInMonth) * @param month (legal: 1 ≤ month ≤ 12) * @param year (legal: 1 ≤ year) * * @return Whether the parameters are legal * */ private boolean legalDate (int day, int month, int year) { return (1 <= year) && ((1 <= month) && (month <= 12)) && ((1 <= day) && (day <= daysInMonth (month, year))); } /** * @param day (legal: 1 ≤ day ≤ daysInMonth) * @param month (legal: 1 ≤ month ≤ 12) * @param year (legal: 1 ≤ year) * * @return Whether the parameters are legal * */ private boolean legalDate (int day, int month, int year) { return (1 <= year) && ((1 <= month) && (month <= 12)) && ((1 <= day) && (day <= daysInMonth (month, year))); } … so we must supply them. R2
46
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling class Date {... day, month, year fields private static final int[] monthDays = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};... other methods /** * @return The number of days in the month */ private int daysInMonth () { int answer = monthDays[month – 1]; if ((month == 2) && isLeapYear ()) { answer = answer + 1; } return answer; } } Assumes: month is in the range 1..12. R1 Seen before
47
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling no year field … so we must supply. class Date { private int date; // days since 1970-01-01 private static final int[] monthDays = {31, 28, 31, 30, 31, 30, 31,..., 31}; /** * @param month (assume: 1 ≤ month ≤ 12) * @param year (assume: 1 ≤ year) * @return The number of days in the month */ private int daysInMonth (int month, int year) { int answer = monthDays[month – 1]; if ((month == 2) && isLeapYear (year)) { answer = answer + 1; } return answer; } } CompleteComplete R2
48
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling /** * @return Whether the year is a leap year */ private boolean isLeapYear () { return (divides (4, year) && !divides (100, year)) || divides (400, year); } /** * @return Whether the year is a leap year */ private boolean isLeapYear () { return (divides (4, year) && !divides (100, year)) || divides (400, year); } R1 Seen before
49
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling /** * @param year (assume: 1 ≤ year) * @return Whether the year is a leap year */ private boolean isLeapYear (int year) { return (divides (4, year) && !divides (100, year)) || divides (400, year); } /** * @param year (assume: 1 ≤ year) * @return Whether the year is a leap year */ private boolean isLeapYear (int year) { return (divides (4, year) && !divides (100, year)) || divides (400, year); } CompleteComplete R2
50
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling class Date { private int day; // 1 ≤ day ≤ daysInMonth private int month; // 1 ≤ month ≤ 12 private int year; // 1 ≤ year... setDate, setToNextDay, toString methods private int daysInMonth () {... } private boolean isLeapYear () {... } private boolean legalDate () {... } } R1
51
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling class Date { private int date; // days since 1970-01-01... setDate, setToNextDay, toString methods private int daysInMonth (int month, int year) {... } private boolean isLeapYear (int year) {... } private boolean legalDate (int day, int month, int year) {... } } R2
52
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling OBSERVATION: R2 We could have used the fully parametrised versions: int daysInMonth (int month, int year) boolean isLeapYear (int year) boolean legalDate (int day, int month, int year) in the version of Date, as well as in version. R1 They do not depend on any chosen field representation. They may, therefore, be worth factoring out into a separate class, DateStuff, which either representation for Date could use.
53
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling class DateStuff { private static final int[] monthDays = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; public int daysInMonth (int month, int year) {... } public boolean isLeapYear (int year) {... } public boolean legalDate (int day, int month, int year) {... } private boolean divides (int d, int n) {... } }
54
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling But, now that they are public methods, daysInMonth and isLeapYear must be protected against misuse. Note: legalDate is already secure – dealing with bad data is, after all, its purpose! public int daysInMonth (int month, int year) {... } public boolean isLeapYear (int year) {... } public boolean legalDate (int day, int month, int year) {... } public int daysInMonth (int month, int year) {... } public boolean isLeapYear (int year) {... } public boolean legalDate (int day, int month, int year) {... } DateStuff
55
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling /** * @param month (1 ≤ month ≤ 12) * @param year (1 ≤ year) * @return The number of days in the month */ public int daysInMonth (int month, int year) { if ((month 12) || (year 12) || (year < 1)) { System.out.println ("*** daysInMonth: bad argument(s)" + " – returning zero"); return 0; } int answer = monthDays[month – 1]; if ((month == 2) && isLeapYear (year)) { answer = answer + 1; } return answer; } DateStuff
56
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling /** * @param year (1 ≤ year) * @return Whether year is a leap year */ public boolean isLeapYear (int year) { if (year < 1){ System.out.println ("*** isLeapYear: bad argument " + "– returning false"); return false; } return (divides (4, year) && !divides (100, year)) || divides (400, year); } } /** * @param year (1 ≤ year) * @return Whether year is a leap year */ public boolean isLeapYear (int year) { if (year < 1){ System.out.println ("*** isLeapYear: bad argument " + "– returning false"); return false; } return (divides (4, year) && !divides (100, year)) || divides (400, year); } } DateStuff
57
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling /** * @param day (legal: 1 ≤ day ≤ daysInMonth) * @param month (legal: 1 ≤ month ≤ 12) * @param year (legal: 1 ≤ year) * * @return Whether the parameters are legal * */ public boolean legalDate (int day, int month, int year) { return (1 <= year) && ((1 <= month) && (month <= 12)) && ((1 <= day) && (day <= daysInMonth (month, year))); } /** * @param day (legal: 1 ≤ day ≤ daysInMonth) * @param month (legal: 1 ≤ month ≤ 12) * @param year (legal: 1 ≤ year) * * @return Whether the parameters are legal * */ public boolean legalDate (int day, int month, int year) { return (1 <= year) && ((1 <= month) && (month <= 12)) && ((1 <= day) && (day <= daysInMonth (month, year))); } DateStuff UnchangedUnchanged* except that now it’s public. except that now it’s public. *
58
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling class DateStuff { private static final int[] monthDays = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; public int daysInMonth (int month, int year) {... } public boolean isLeapYear (int year) {... } public boolean legalDate (int day, int month, int year) {... } private boolean divides (int d, int n) {... } } Just seen
59
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling class DateStuff { private static final int[] monthDays = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; public int daysInMonth (int month, int year) {... } public boolean isLeapYear (int year) {... } public boolean legalDate (int day, int month, int year) {... } private boolean divides (int d, int n) {... } } class DateStuff { private static final int[] monthDays = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; public static int daysInMonth (... ) {... } public static boolean isLeapYear (int year) {... } public static boolean legalDate (int day, int month, int year) {... } private static boolean divides (int d, int n) {... } } New Java concept
60
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling New Java Concept: Methods, as well as fields, may be declared static. static methods may work with fields of its class, but only if they are static. static methods may invoke other methods of its class, but only if they are static. In DateStuff, the methods isLeapYear and divides work only with their parameters – no fields. In DateStuff, the methods daysInMonth and legalDate work with their parameters and (the static field) monthDays. In DateStuff, daysInMonth invokes isLeapYear, which invokes divides. And legalDate invokes daysInMonth.
61
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling class DateStuff { private static final int[] monthDays = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; public static int daysInMonth (... ) {... } public static boolean isLeapYear (int year) {... } public static boolean legalDate (int day, int month, int year) {... } private static boolean divides (int d, int n) {... } } New Java concept
62
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling New Java Concept: Methods, as well as fields, may be declared static. static methods may work with fields of its class, but only if they are static. static methods may invoke other methods of its class, but only if they are static. static fields and methods belong to the class. They are shared by all objects (if any) of the class. To invoke a static method of another class, we don’t need an object of that other class. We invoke it prefixed with the name of its owning class (followed by the usual dot). Normally: we invoke a method on an object. We invoke it prefixed with the name of the variable referencing the object (followed by the usual dot).
63
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling /** * Set the date to a particular day */ public void setDate (int day, int month, int year) { if (legalDate (day, month, year)) { setLegalDate (day, month, year) } else { date = 1; System.out.println ("*** setDate: Bad parameters" + "... setting date to" + " 1970-01-01"); } } /** * Set the date to a particular day */ public void setDate (int day, int month, int year) { if (legalDate (day, month, year)) { setLegalDate (day, month, year) } else { date = 1; System.out.println ("*** setDate: Bad parameters" + "... setting date to" + " 1970-01-01"); } } Seen before R2
64
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling /** * Set the date to a particular day */ public void setDate (int day, int month, int year) { if (legalDate (day, month, year)) { setLegalDate (day, month, year) } else { date = 1; System.out.println ("*** setDate: Bad parameters" + "... setting date to" + " 1970-01-01"); } } /** * Set the date to a particular day */ public void setDate (int day, int month, int year) { if (legalDate (day, month, year)) { setLegalDate (day, month, year) } else { date = 1; System.out.println ("*** setDate: Bad parameters" + "... setting date to" + " 1970-01-01"); } } /** * Set the date to a particular day */ public void setDate (int day, int month, int year) { if (DateStuff.legalDate (day, month, year)) { setLegalDate (day, month, year) } else { date = 1; System.out.println ("*** setDate: Bad parameters" + "... setting date to" + " 1970-01-01"); } } /** * Set the date to a particular day */ public void setDate (int day, int month, int year) { if (DateStuff.legalDate (day, month, year)) { setLegalDate (day, month, year) } else { date = 1; System.out.println ("*** setDate: Bad parameters" + "... setting date to" + " 1970-01-01"); } } R2
65
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling /** * Set the date to a particular day */ public void setDate (int day, int month, int year) { this.day = day; this.month = month; this.year = year; if (!legalDate (){ this.day = 1; this.month = 1; this.year = 1; System.out.println ("*** setDate: Bad parameters" + "... setting date to" + " 0001-01-01"); } } /** * Set the date to a particular day */ public void setDate (int day, int month, int year) { this.day = day; this.month = month; this.year = year; if (!legalDate (){ this.day = 1; this.month = 1; this.year = 1; System.out.println ("*** setDate: Bad parameters" + "... setting date to" + " 0001-01-01"); } } Seen before R1
66
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling /** * Set the date to a particular day */ public void setDate (int day, int month, int year) { this.day = day; this.month = month; this.year = year; if (!legalDate (){ this.day = 1; this.month = 1; this.year = 1; System.out.println ("*** setDate: Bad parameters" + "... setting date to" + " 0001-01-01"); } } /** * Set the date to a particular day */ public void setDate (int day, int month, int year) { this.day = day; this.month = month; this.year = year; if (!legalDate (){ this.day = 1; this.month = 1; this.year = 1; System.out.println ("*** setDate: Bad parameters" + "... setting date to" + " 0001-01-01"); } } /** * Set the date to a particular day */ public void setDate (int day, int month, int year) { this.day = day; this.month = month; this.year = year; if (!DateStuff.legalDate (day, month, year) { this.day = 1; this.month = 1; this.year = 1; System.out.println ("*** setDate: Bad parameters" + "... setting date to" + " 0001-01-01"); } } /** * Set the date to a particular day */ public void setDate (int day, int month, int year) { this.day = day; this.month = month; this.year = year; if (!DateStuff.legalDate (day, month, year) { this.day = 1; this.month = 1; this.year = 1; System.out.println ("*** setDate: Bad parameters" + "... setting date to" + " 0001-01-01"); } } R1
67
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling New Java Concept: Methods, as well as fields, may be declared static. static methods may work with fields of its class, but only if they are static. static methods may invoke other methods of its class, but only if they are static. static fields and methods belong to the class. They are shared by all objects (if any) of the class. To invoke a static method of another class, we don’t need an object of that other class. We invoke it prefixed with the name of its owning class (followed by the usual dot). Classes with only static fields and methods need no objects constructed from them. Classes with only static fields and methods need no objects constructed from them. So … hide the constructor!!
68
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling class DateStuff {... monthDays (private static field)... daysInMonth, isLeapYear, legalDate (public static methods)... divides (private static method) } class DateStuff {... monthDays (private static field) private DateStuff () { // deliberately empty }... daysInMonth, isLeapYear, legalDate (public static methods)... divides (private static method) } constructor This class doesn’t construct any instances of itself. Its constructor is private, so nobody else can. There can be no DateStuff objects.
69
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling OBSERVATION: R2 We could have used the fully parametrised versions: int daysInMonth (int month, int year) boolean isLeapYear (int year) boolean legalDate (int day, int month, int year) in the version of Date, as well as in version. R1 They do not depend on any chosen field representation. They may, therefore, be worth factoring out into a separate class, DateStuff, which either representation for Date could use. Seen before
70
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling They may, therefore, be worth factoring out into a separate class, DateStuff, which either representation for Date could use. DateStuff contains a set of utility functions that work just with their parameters. They need no persistent state to be held in fields. Such things are very reusable. DateStuff can be used with either the R1 or R2 choice for representation of a date in the Date class. Factoring out these low-level functions into DateStuff leaves the Date class (R1 or R2) shorter. Collections of purely static methods are how we used to do things – before Object-Orientation. Don’t make a habit of it! Objects carrying their own state are powerful!!
71
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling The Mañana Principle When – during implementation of a method – we wish we had a certain support method, write our code as if we had it. Implement it later. ReviewReview
72
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling The Mañana Principle When – during implementation of a method – we wish we had a certain support method, write our code as if we had it. Implement it later. Special Case Rule: Often, we need to identify and deal with a special case. Write the code for this in a separate method. Implement it later. ReviewReview
73
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling The Mañana Principle Special Case Rule: Often, we need to identify and deal with a special case. Write the code for this in a separate method. Implement it later. Hard Problem Rule: when we need the answer to a problem we cannot immediately solve, defer it a separate method. Implement it later. ReviewReview
74
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling The Mañana Principle Hard Problem Rule: when we need the answer to a problem we cannot immediately solve, defer it a separate method. Implement it later. Heavy Functionality Rule: when some statements or expressions become too long or complex, move them into a separate method. Implement it later. ReviewReview
75
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling The Mañana Principle Heavy Functionality Rule: when some statements or expressions become too long or complex, move them into a separate method. Implement it later. Nested Loop Rule: when we have a nested loop, move the inner loop into a separate method. Implement it later. ReviewReview
76
Objects First with Java - A Practical Introduction using BlueJ, © David J. Barnes, Michael Kölling Nested Loop Rule: when we have a nested loop, move the inner loop into a separate method. Implement it later. The Mañana Principle Code Duplication Rule: when we repeat the same code, move that code into a separate method and repeat an invocation instead. Implement it later. ReviewReview
77
ReviewReview Mañana – Specific Forms Special Case rule Hard Problem rule Heavy Functionality rule Nested Loop rule Code Duplication rule
78
ReviewReview Utility Classes public static methods, as well as private static fields. Utility classes (like DateStuff ) have only the above kind of methods and fields. public static methods are invoked via the class name – no object is needed. Utility classes (like DateStuff ) have only private constructors – no objects can be constructed.
Similar presentations
© 2024 SlidePlayer.com. Inc.
All rights reserved.