Object-Oriented Design & Patterns

Cay S. Horstmann

Chapter 3

The Object-Oriented Design Process

Slide navigation: Forward with space bar, → arrow key, or PgDn. Backwards with ← or PgUp.

Chapter Topics

Date/Time Classes in the Standard Library

Points in Time

.

Methods of the Instant class

Method Description
long getEpochSecond() Gets the number of seconds since the epoch.
long getNano() Gets the number of nanoseconds since the last second.
Instant plusSeconds(long seconds)
Instant plusNanos(long nanos)
Yields the instant that is obtained by adding the given number of seconds or nanoseconds.
Instant plus(Duration duration) Yields the instant that is obtained by adding the given Duration (which encapulates seconds and nanoseconds).
ZonedDateTime atZone(ZoneId zone) Yields the ZonedDateTime at a given time zone. You get a ZoneId with its static of method, such as ZoneId.of("America/Los_Angeles").
String toString() Yields a representation in ISO-8601 format.

The ZonedDateTime Class

Methods of the ZonedDateTime Class

Method Description
int getYear()
int getMonthValue()
int getDayOfMonth()
Gets the year, month, or day.
DayOfWeek getDayOfWeek() Gets the day of the week. Call the value method on the returned object to get an integer value (1 = Monday ... 7 = Sunday).
int getHour()
int getMinute()
int getSecond()
int getNano()
Gets the hour, minute, second, or nanosecond of this ZonedDateTime.
ZoneOffset getOffset() Gets the offset from the zero meridian. Call getTotalSeconds on the returned object to get the offset in seconds.
ZonedDateTime plusDays(int n)
ZonedDateTime plusWeeks(int n)
ZonedDateTime plusMonths(int n)
ZonedDateTime plusYears(int n)
ZonedDateTime plusHours(int n)
ZonedDateTime plusMinutes(int n)
ZonedDateTime plusSeconds(int n)
ZonedDateTime plusNanos(int n)
Yields a ZonedDateTime that is obtained by adding a the given number of days, weeks, months, years, hours, minutes, seconds, or nanoseconds temporal units to this ZonedDateTime.

Designing a Day Class

Designing a Day Class

Designing a Day Class

.

Designing a Day Class

Implementing a Day Class

Implementing a Day Class

Second Implementation

Third Implementation

The Importance of Encapsulation

Accessors and Mutators

Don't Supply a Mutator for every Accessor

Sharing Mutable References

Sharing Mutable References

Sharing Mutable References

.

Final Instance Fields

Separating Accessors and Mutators

Separating Accessors and Mutators

Side Effects

Side Effects

Side Effects

Law of Demeter

Law of Demeter

Quality of Class Interface

Cohesion

Completeness

Convenience

Clarity

Clarity

Consistency

Consistency

Programming by Contract

Preconditions

Preconditions

Preconditions

/**
   Remove message at head
   @return the message at the head
   @precondition size() > 0
*/
Message remove()
{
   return elements.remove(0);
}

Circular Array Implementation

Inefficient Shifting of Elements

.

A Circular Array

.

Wrapping around the End

.

Preconditions

Assertions

Assertions

public Message remove() 
{ 
   assert count > 0 : "violated precondition size() > 0";
   Message r = elements[head]; 
   . . .
} 

Exceptions in the Contract

/**
   . . .
   @throws NoSuchElementException if queue is empty
*/
public Message remove() 
{ 
   if (count == 0) 
      throw new NoSuchElementException();
   Message r = elements[head]; 
   . . .
} 

Postconditions

Class Invariants

Class Invariants

Unit Testing

JUnit

.

JUnit

import org.junit.*;
import static org.junit.Assert.*;

public class DayTest
{
   @Test public void testAdd() { ... }
   @Test public void testDaysBetween() { ... }
   . . .
}

JUnit

@Test public void testAdd()
{
   Day d1 = new Day(1970, 1, 1);
   int n = 1000;
   Day d2 = d1.plusDays(n);
   assertTrue(d2.daysFrom(d1) == n);
}