object-based scanning redo the scanning solutions monolithic, single class solutions –does ui and...

Post on 21-Jan-2016

230 Views

Category:

Documents

0 Downloads

Preview:

Click to see full reader

TRANSCRIPT

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));}

}}

top related