| Practice with Composite and Interpreter Patterns |
| Another Composite Example Computing with Lists |
| An IntList is either: | ||
| Empty(), the empty list, or | ||
| NonEmpty(first,rest), a non-empty list, where first is an int and rest is an IntList. | ||
| Some examples include: Empty() NonEmpty(7,Empty()) NonEmpty(12, NonEmpty(17, Empty())) |
||
| IntList |
| import java.util.NoSuchElementException; | |
| abstract class IntList { | |
| abstract int getFirst(); | |
| abstract IntList getRest(); | |
| } | |
| class Empty extends IntList { | |
| int getFirst() { | |
| throw new | |
| NoSuchElementException("getFirst applied to Empty()"); | |
| } | |
| int getRest() { | |
| throw new | |
| NoSuchElementException("getRest applied to Empty()"); | |
| } | |
| public String toString() { return "Empty()"; } | |
| } | |
| class NonEmpty extends IntList { | |
| int first; | |
| IntList rest; | |
| int getFirst() { return first; ); | |
| IntList getRest() { return rest; } | |
| public String toString() { return "NonEmpty(" + first + ", " + rest + ")"; } | |
| } | |
| Remarks on IntList |
| The operations getFirst() and getRest() are included in the abstract class IntList because they are useful operations for clients of IntList. | |
| Invoking getFirst() or getRest() on the Empty list is a run-time error, which we implement by throwing an exception. The Java throw construct takes an object of type Exception (which is a built-in class). In the absence of a catch handler attached to a method on the call stack, throwing an exception aborts the computation and prints the String message embedded in the exception. |
| Finger Exercise |
| Open the class IntList.java in DrJava, compile it, and try evaluating | |||
| new Empty().getFirst() | |||
| il1 = new NonEmpty(17, new Empty()) | |||
| il1 | |||
| Il1.getRest().getFirst() | |||
| The Singleton Pattern |
| Each execution of the expression new Empty() creates a new object. In principle, there is only one empty list, just like there is only one number 0. Hence, we would like to represent the empty list by a single library. |
||
| The singleton pattern is the mechanism that we use to create a unique instance of a class. This pattern consists of two chunks of code: | ||
| a static final field in the class that holds the single instance of the class | ||
| a private attribute on the class constructor, so no client can create another instance of the class. | ||
| Singleton IntList |
| import java.util.NoSuchElementException; | |
| abstract class IntList { | |
| abstract int getFirst(); | |
| abstract IntList getRest(); | |
| } | |
| class Empty extends IntList { | |
| static final Empty ONLY = new Empty(); | |
| private Empty() {} | |
| int getFirst() { | |
| throw new | |
| NoSuchElementException("getFirst applied to Empty()"); | |
| } | |
| int getRest() { | |
| throw new | |
| NoSuchElementException("getRest applied to Empty()"); | |
| } | |
| public String toString() { return "Empty()"; } | |
| } | |
| class NonEmpty extends IntList { | |
| int first; | |
| IntList rest; | |
| int getFirst() { return first; ); | |
| IntList getRest() { return rest; } | |
| public String toString() { return "NonEmpty(" + first + ", " + rest + ")"; } | |
| } | |