Object-based Scanning Redo the scanning solutions Monolithic, single class solutions –does UI and...
-
Upload
marcus-harris -
Category
Documents
-
view
224 -
download
0
Transcript of Object-based Scanning Redo the scanning solutions Monolithic, single class solutions –does UI and...
Object-based Scanning
• Redo the scanning solutions
• Monolithic, single class solutions– does UI and scanning
• No reuse of code
Upper case printingpackage warmup;public class AnUpperCasePrinter { public static void main(String[] args){
if (args.length != 1) {System.out.println("Illegal number of arguments:" + args.length + ".
Terminating program.");System.exit(-1);
}System.out.println("Upper Case Letters:");int index = 0;while (index < args[0].length()) {
if (isUpperCase(args[0].charAt(index)))System.out.print(args[0].charAt(index));index++;
}}System.out.println();
} public static boolean isUpperCase(char c) {
return (c >= 'A') && (c <= 'Z'); }}
Forward and reverse printingpackage warmup;public class AReverseUpperCasePrinter {
static final int MAX_CHARS = 5;static char[] upperCaseLetters = new char[MAX_CHARS];static int numberOfUpperCaseLetters = 0;public static void main(String[] args){
if (args.length != 1) {System.out.println("Illegal number of arguments:" +
args.length + ". Terminating program.");System.exit(-1);
}int index = 0;System.out.println("Upper Case Letters:");while (index < args[0].length()) {
if (isUpperCase(args[0].charAt(index))) {System.out.print(args[0].charAt(index));storeChar(args[0].charAt(index));
}index++;
}System.out.println();printReverse();
}
Forward and reverse printing (contd.)
public static void storeChar(char c) {if (numberOfUpperCaseLetters == MAX_CHARS) {
System.out.println("Too many upper case letters. Terminating program. ");
System.exit(-1);}upperCaseLetters[numberOfUpperCaseLetters] = c;numberOfUpperCaseLetters++;
}public static void printReverse() {
System.out.println("Upper Case Letters in Reverse:");for (int index =numberOfUpperCaseLetters - 1; index >= 0; index--) {
System.out.print(upperCaseLetters[index]);}
}}
No reuse in Monolithic Solutions
int index = 0;System.out.println("Upper Case Letters :");//token processingwhile (index < args[0].length()) { if (Character.isUpperCase(args[0].charAt(index);)) { System.out.print(args[0].charAt(index);); // token processing
storeChar(args[0].charAt(index)); }
index++;}
int index = 0;System.out.println("Upper Case Letters :");//token processingwhile (index < args[0].length()) { if (Character.isUpperCase(args[0].charAt(index);)) System.out.print(args[0].charAt(index)); // token processing
index++;}
Class Decomposition?
Main Class
Division of Labor in Radio Scanning
Division of Labor in Radio Scanning
Division of Labor in Radio Scanning
Division of Labor in Radio Scanning
Division of Labor in Radio Scanning
Division of Labor in Radio Scanning
Division of Labor in Radio Scanning
?
Division of Labor in Radio Scanning
Division of Labor in Radio Scanning
Scanner Object
calls
Scanner User
Main Class(Input & Output)
Class Decomposition
Scanner Class
instantiate
BufferedReader Instance
readLine()
Scanner User
Main Class(Input & Output)
Class Decomposition
BufferedReader
instantiate
Scanner User-Scanner Object Interaction
BufferedReader dataIn = new BufferedReader (new InputStreamReader( System.in));int product = 1;// add input list terminated by a negative numberwhile (true) {
int num = Integer.parseInt (dataIn.readLine()); if (num < 0) break; product = product*num;
}System.out.println (product);
Constructor parameters
• InputStreamReader takes System.in as parameter.
• BufferedReader takes InputStreamReader as parameter.
• In general, scanner takes object producing scanned stream as parameter.
BufferedReader Operations
Line 1 Line 2
Multi-lineinput stream
Linestream
dataIn.readLine() Line 1
dataIn.readLine() Line 2
dataIn.readLine() IOException
Scanner Interface?
scanner.nextElement() token 1
scanner.nextElement() token 2
scanner.nextElement() ScannerException
token 1 token 2
Inputstream
TokenStream
Scanner Interface?
scanner.nextElement() token 1
scanner.nextElement() token 2
scanner.hasMoreElements() false
Inputstream
TokenStream
token 1 token 2
scanner.nextElement() ???
Uppercase Scanner Interface?
scanner.nextElement() ‘J’
scanner.nextElement() ‘F’
scanner.hasMoreElements() false
J o h n F . K e n n d ye
token 1 token 2 token 3
scanner.nextElement() ‘K’
scanner.nextElement() ???
Enumeration Interfacespackage enums;public interface CharEnumeration {
public char nextElement(); public boolean hasMoreElements();
}
package enums;public interface StringEnumeration {
public String nextElement(); public boolean hasMoreElements();
}
package <P>;public interface <Type>Enumeration {
public <Type> nextElement(); public boolean hasMoreElements();
}
Using an Enumeration Interface
public static void printChars (CharEnumeration charEnumeration) { while (charEnumeration.hasMoreElements()) System.out.print(charEnumeration.nextElement()); }
J o h n F . K e n n d ye
token 1 token 2 token 3
Using an Enumeration Interfacepackage main;import enums.CharEnumeration;import enums.AnUpperCaseEnumeration;public class UpperCasePrinter { public static void main (String args[]) { if (args.length != 1) {
System.out.println("Illegal number of arguments:" + args.length + ". Terminating program.");
System.exit(-1); } printUpperCase(args[0]); } public static void printUpperCase(String s) { System.out.println("Upper Case Letters:"); printChars (new AnUpperCaseEnumeration(s)); } public static void printChars (CharEnumeration charEnumeration) { while (charEnumeration.hasMoreElements()) System.out.print(charEnumeration.nextElement()); } }
Implementing Scanner
package enums;public class AnUpperCaseEnumeration implements CharEnumeration {
… public AnUpperCaseEnumeration(String theString) { ... } public boolean hasMoreElements() { ... } public char nextElement() { ...; } …
}
Data Structure: Scanned String
package enums;public class AnUpperCaseEnumeration implements CharEnumeration {
String string; … public AnUpperCaseEnumeration(String theString) { string = theString; ... } public boolean hasMoreElements() { ... } public char nextElement() { ...; } …
}
Data Structure: marker
J o h n F . K e n n d ye
nextElementPos
string
scanned part Unscanned part
hasMoreElements()
J o h n F . K e n n d ye
string
nextElementPos
public boolean hasMoreElements() { ...
}
true
hasMoreElements()
J o h n F . K e n n d ye
string
nextElementPos
public boolean hasMoreElements() { ...
}
true
hasMoreElements()
J o h n F . K e n n d ye
string
nextElementPos
public boolean hasMoreElements() { ...
}
false
hasMoreElements()
J o h n F . K e n n d ye
string
nextElementPos
//return true if nextElementPos is beyond end of string; false otherwisepublic boolean hasMoreElements() {
...}
hasMoreElements()
J o h n F . K e n n d ye
string
nextElementPos
//return false if nextElementPos is beyond end of string; true otherwisepublic boolean hasMoreElements() {
return nextElementPos < string.length();}
nextElement()
J o h n F . K e n n d ye
string
nextElementPos
public char nextElement() {
}
nextElement()
J o h n F . K e n n d ye
string
nextElementPos
//Assume nextElemPos is at start of next token or end of string when //method is called. //Method makes sure this is also true before returning.//returns next element if one existspublic char nextElements() {
}
nextElement()
J o h n F . K e n n d ye
string
nextElementPos
//Assume nextElemPos is at start of next token or end of string when //method is called. //Method makes sure this is also true before returning.//returns next element if one existspublic char nextElement() {
}
char retVal = string.charAt(nextElemPos)
return retVal;
while (!isUpperCase(string.charAt(nextElementPos)))
nextElemPos++;
Unexecuted Loop
nextElement()
J o h n F . K e n n d ye
string
nextElementPos
//Assume nextElemPos is at start of next token or end of string when //method is called. //Method makes sure this is also true before returning.//returns next element if one existspublic char nextElements() {
}
movePastCurrentToken();char retVal = extractToken();
return retVal;skipNonTokenCharacters();
nextElement()
J o h n F . K e n n d ye
string
nextElementPos
//Assume nextElemPos is at start of next token or end of string when //method is called. //returns next token if one existspublic char extractToken() {
}return string.charAt(nextElementPos);
movePastCurrentToken()
//Assume nextElemPos is at start of next token or end of string when //method is called. //Moves past current token.public void movePastCurrentToken() {
}
nextElemPos++;
J o h n F . K e n n d ye
string
nextElementPos
skipNonTokenCharacters()
J o h n F . K e n n d ye
string
nextElementPos
// keep advancing nextElementPos until we hit the next upper case public void skipNonTokenCharacters() {
}
while (! isUpperCase(string.charAt(nextElementPos)))
nextElemPos++;
StringIndexOutOfBounds
skipNonTokenCharacters()
J o h n F . K e n n d ye
string
nextElementPos
// keep advancing nextElementPos until we hit the next upper case or go// beyond the end of the string.public void skipNonTokenCharacters() {
}
while (nextElementPos < string.length() && !Character.isUpperCase(string.charAt(nextElementPos)))
nextElemPos++;
StringIndexOutOfBounds?short-circuit
Initialization
j o h n F . K e n n d ye
string
nextElementPos
String string;int nextElementPos = 0;public AnUpperCaseEnumeration(String theString) {
}
string = theString;
skipNonTokenCharacters();
Complete Scannerpackage enums;public class AnUpperCaseEnumeration implements CharEnumeration { String string; int nextElementPos = 0; public AnUpperCaseEnumeration(String theString) { string = theString; skipNonTokenCharacters(); } public boolean hasMoreElements() { return nextElementPos < string.length();} public char nextElement() { char retVal = extractToken(); movePastCurrentToken(); skipNonTokenCharacters(); return retVal; } void movePastCurrentToken() {nextElementPos++;} void skipNonTokenCharacters() { while (nextElementPos < string.length() && !isUpperCase(string.charAt(nextElementPos))) nextElementPos++; } char extractToken() { return string.charAt(nextElementPos);} boolean isUpperCase (char c) { return c >= ‘A’ && c <= ‘Z’;} }
constructor
Scanner Patternpackage <P>;public class <Scanner Name> implements <T>Enumeration { String string; int nextElementStart = 0; int nextElementEnd = ???; public AnUpperCaseEnumeration(String theString) { string = theString; skipNonTokenCharacters(); } public boolean hasMoreElements() { return nextElementStart < string.length();} public <T> nextElement() { <T> retVal = extractToken(tokenLength); movePastCurrentToken(tokenLength); skipNonTokenCharacters(); return retVal; } void movePastCurrentToken() {…}; void skipNonTokenCharacters() {…}; char extractToken() { …} }
AnUpperCaseEnumeration instance
Class Decomposition
AnUpperCaseEnumeration
instantiate
AnUppercasePrinter
AnUpperCaseEnumeration instance
Class Decomposition
AnUpperCaseEnumeration
instantiate
AReverseUpperCasePrinter
Reuse of Enumeration
while (charEnumeration.hasMoreElements()) {char nextChar = charEnumeration.nextElement()); System.out.print(nextChar);
storeChar(nextChar);}
while (charEnumeration.hasMoreElements()) System.out.print(charEnumeration.nextElement());
Enumeration Vs Scanning
public interface CharEnumeration { public char nextElement(); public boolean hasMoreElements();
}
J o h n F . K e n n d ye
token 1 token 2 token 3
Enumeration without Scanning
public interface CharEnumeration { public char nextElement(); public boolean hasMoreElements();
}
AllUppercaseLettersInOrder
implements
‘A’ ‘B’ ... ‘Z’
Enumerating all Uppercase Letters
public boolean hasMoreElements() { ????}
public char nextElement() { ???
}
//instance variables
???
Enumerating all Uppercase Letterspackage enumerations;public class AllUpperCaseLettersInOrder implements CharEnumeration { char nextLetter = 'A'; public boolean hasMoreElements() { return nextLetter <= 'Z'; } public char nextElement() { char retVal = nextLetter; nextLetter = (char) (nextLetter + 1); return retVal; } }
Comparing Two Implementations
public interface CharEnumeration { public char nextElement(); public boolean hasMoreElements();
}
J o h n F . K e n n d ye
token 1 token 2 token 3
AnUpperCaseEnumeration
implements
‘J’ ‘F’‘K’
Radically Different Behaviors
public interface CharEnumeration { public char nextElement(); public boolean hasMoreElements();
}
AllUppercaseLettersInOrder
implements
‘A’ ‘B’ ... ‘Z’
print (new AnUppercaseEnumeration(s));
print (new AllUppercaseLettersInOrder());
Polymorphism
Syntactic Specification!
Forward and reverse printing
package main;import enums.CharEnumeration;import enums.AnUpperCaseEnumeration;public class AReverseUpperCasePrinter {
static final int MAX_CHARS = 5;static char[] upperCaseLetters = new char[MAX_CHARS];static int numberOfUpperCaseLetters = 0;
public static void main(String[] args){if (args.length != 1) {
System.out.println("Illegal number of arguments:" + args.length + ". Terminating program.");
System.exit(-1);}printAndStore(args[0]);printReverse();
}
Forward and reverse printing
public static void printAndStore (String s) { System.out.println("Upper Case Letters:"); printAndStore (new AnUpperCaseEnumeration(s)); } public static void printAndStore (CharEnumeration charEnumeration) { while (charEnumeration.hasMoreElements()) { char inputChar = charEnumeration.nextElement(); System.out.print (inputChar); storeChar(inputChar); } System.out.println(); }
Forward and reverse printing (contd.)
public static void storeChar(char c) {if (numberOfUpperCaseLetters == MAX_CHARS) {
System.out.println("Too many upper case letters. Terminating program. ");
System.exit(-1);}upperCaseLetters[numberOfUpperCaseLetters] = c;numberOfUpperCaseLetters++;
}public static void printReverse() {
System.out.println("Upper Case Letters in Reverse:");for (int index =numberOfUpperCaseLetters - 1; index >= 0;
index--) {System.out.print(upperCaseLetters[index]);
}}
}
Remaining problems
package main;import enums.CharEnumeration;import enums.AnUpperCaseEnumeration;public class AReverseUpperCasePrinter {
static final int MAX_CHARS = 5;static char[] upperCaseLetters = new char[MAX_CHARS];static int numberOfUpperCaseLetters = 0;
public static void main(String[] args){if (args.length != 1) {
System.out.println("Illegal number of arguments:" + args.length + ". Terminating program.");
System.exit(-1);}printAndStore(args[0]);printReverse();
}
Remaining Problems
• Main class does storing
• Non UI code
• Array, size, and max size closely coupled to each other
• Should be in separate class
3 J
F
K
size array
Variable-Size Collection
filled part
unfilled part
current size
maximum size
Variable-Size Collectionpublic class <ClassNeedingVariableSizeTCollection> { …
final static T A_MAX_SIZE = 50;T[] a = new T [MAX_SIZE];int aSize = 0;…//process afor (int index = 0; index < aSize; index++)
System.out.println(a[index]);…final int B_MAX_SIZE = 50;T[] b = new T [MAX_SIZE];int bSize = 0;
//process b …}
Special Typepublic class <ClassNeedingVariableSizeCollection> { ... AVariableSizeTCollection a, b = new AVariableSizeTCollection(); ... for (int index = 0; index < a.size; index++) System.out.println(a.contents[index]); …
AVariableSizeTCollection b = new AVariableSizeTCollection(); ...}
public class AVariableSizeTCollection {public static final int MAX_SIZE = ???;public T[] contents = new T [MAX_SIZE];public int size = 0;
}
No encapsulation!
a.size = 0;
Constraints violated
Supporting Encapsulation
package collections;public interface …. {
public static final int MAX_SIZE = 50;
}
public void addElement (char element);
public void printReverse ();
Implementation specific
User specific
Supporting Encapsulation
package collections;public interface CharHistory {
}
public void addElement (char element);
public int size();
public char elementAt (int index);
Implementing the Historypackage collections;public class ACharHistory implements CharHistory {
public final int MAX_SIZE = 5; char[] contents = new char[MAX_SIZE]; int size = 0; public int size() { return size;} public char elementAt (int index) { return contents[index]; } boolean isFull() { return size == MAX_SIZE; } public void addElement(char element) { if (isFull()) {
System.out.println("Adding item to a full history. Terminating program.");
System.exit(-1); } else {
contents[size] = element; size++;}
} }
Using the Historypackage main;import enums.CharEnumeration;import enums.AnUpperCaseEnumeration;import collections.ACharHistory;import collections.CharHistory;public class AModularReverseUpperCasePrinter { static CharHistory upperCaseLetters = new ACharHistory(); public static void main(String[] args) { if (args.length != 1) {
System.out.println("Illegal number of arguments:" + args.length + ". Terminating program.");
System.exit(-1);}printAndStore(args[0]);printReverse();
}
Using the History
public static void printAndStore (String s) { System.out.println("Upper Case Letters:"); printAndStore (new AnUpperCaseEnumeration(s)); } public static void printAndStore (CharEnumeration charEnumeration) { while (charEnumeration.hasMoreElements()) { char inputChar = charEnumeration.nextElement(); System.out.print (inputChar); upperCaseLetters.addElement(inputChar); } System.out.println(); }
Forward and reverse printing (contd.)
public static void printReverse() {System.out.println("Upper Case Letters in Reverse:");for (int index =upperCaseLetters.size() - 1; index >= 0; index--) {
System.out.print(upperCaseLetters.elementAt(index));}
}}