CIS 3142 Advice — Chapter 1

CISC 3142
Programming Paradigms in C++
Abstraction

Printing the array a

The Original Code

int [] a;
…
code to load up  a

for (int i = 0; i < a.length; i++)
	print element a[i]

Abstraction — Define a Procedure (Procedural Decomposition) — Allow Printing from Multiple Locations in the Code

code to load up  a

printA();
…
void printA() {	// (assuming 'a' is accessible from this procedure)

	for (int i = 0; i < a.length; i++)
		print element a[i]
}

Abstraction — Introduce a Parameter — Allow Other Arrays to be Printed

code to load up  a

printAarray(a);
…
void printA(int [] a) {

	for (int i = 0; i < a.length; i++)
		print element a[i]
}

Abstraction — Use a Generic Array — Allow Other Element Types to be Printed

code to load up  a

printAarray(a);
…
<T> void printA(T [] a) {
	for (int i = 0; i < a.length; i++)
		print element a[i]
}

Abstraction — Use an Iterator — Avoid the Details of Moving Through the Array

code to load up  a

printArray(a);
…
void printArray(T [] a) {
	for (Iterator iter = a.iterator(); iter.hasNext(); )
		print iter.next()
}

Abstraction — Generalize the Container — Allow Collections other than an Array to be Printed

code to load up  a

printArray(a);
…
void print(Collection c) {
	for (Iterator iter = c.iterator(); iter.hasNext(); )
		print iter.next()
}

Abstraction — Generalize the Action Taken on Each Element — Allow Actions Other than Printing

interface Procedure {
	void do(Object object);
}
class Printer implements Procedure {
	void do(Object object) {System.out.println(object);}
}
…
code to load up  a

printArray(a, new Printer());
…
void print(Collection c, Procedure procedure) {
	for (Iterator iter = c.iterator(); iter.hasNext(); )
		procedure.do(iter.next())
}

Abstraction — Adding a Test for Which Elements to Process — Add Flexibility as to Which Elements to Process

interface Procedure {
	void do(Object object);
}
interface Predicate {
	boolean test(Object object);
}
class Printer implements Procedure {
	void do(Object object) {System.out.println(object);}
}
class IsEven implements Predicate {
	boolean test(Object object) {return ((Integer)object) % 2 == 0;}
}
…
code to load up  a

printArray(a, new Printer(), new IsEven());
…
void print(Collection c, Procedure procedure, Predicate predicate) {
	for (Iterator iter = c.iterator(); iter.hasNext(); ) {
		Object object = iter.next();
		if (predicate.test(object)) procedure.do(object);
	}
}

Abstraction — Build this General Iteration into the Collection — Avoid Having to Deal with the Iteration Logic

class Printer implements Procedure {
	void do(Object object) {System.out.println(object);}
}
class IsEven implements Predicate {
	boolean test(Object object) {return ((Integer)object) % 2 == 0;}
}
…
code to load up  a

a.forEach(new Printer(), new IsEven());

Abstraction — Anonymous Classes — Avoid Defining 'One-Time' Classes

code to load up  a

a.forEach(new Procedure () {
			void do(Object object) {System.out.println(object);
		},
		new Predicate() {
			boolean test(Object object) {return ((Integer)object) % 2 == 0;}
		});

Abstraction — Lambdas — Avoid Defining 'One-Time' Functions

code to load up  a

a.forEach(object -> System.out.println(object), object -> ((Integer)object) % 2 == 0;);
We've come full circle; started with inline code and ended with inline code, but look at the difference

The code at the link below is working C++ and Java code, and is loosely related to the above sequence

Code Used in this Lecture