Iterators and Design Patterns in Programming Language - Lecture Slides | CMSC 433, Papers of Programming Languages

Material Type: Paper; Class: PROG LANG TECH & PDGMS; Subject: Computer Science; University: University of Maryland; Term: Spring 2005;

Typology: Papers

Pre 2010

Uploaded on 07/30/2009

koofers-user-d41
koofers-user-d41 🇺🇸

10 documents

1 / 45

Toggle sidebar

This page cannot be seen from the preview

Don't miss anything!

bg1
1
CMSC 433 – Programming Language
Technologies and Paradigms
Spring 2005
Iterators and Design Patterns
February 15, 2005
2
Administrivia
Other resources:
Thinking in Patterns with Java
Link from the class web page
Gamma, Helm, Johnson, Vlissides, Design Patterns,
Addison-Wesley 1995
Freeman et al, Head First Design Patterns, O’Reilly,
2004
3
Inner Classes
Classes can be nested inside other classes
These are called inner classes
Within a class that contains an inner class, you
can use the inner class just like any other class
4
Example: The Queue Class
class Queue<Element> {
class Entry { // Java inner class
Element elt; Entry next;
Entry(Element i) { elt = i; next = null; }
}
private Entry theQueue;
void enqueue(Element e) {
if (theQueue == null) theQueue = new Entry(e);
else {
Entry last = theQueue;
while (last.next != null) last = last.next;
last.next = new Entry(e);
}
}
...
pf3
pf4
pf5
pf8
pf9
pfa
pfd
pfe
pff
pf12
pf13
pf14
pf15
pf16
pf17
pf18
pf19
pf1a
pf1b
pf1c
pf1d
pf1e
pf1f
pf20
pf21
pf22
pf23
pf24
pf25
pf26
pf27
pf28
pf29
pf2a
pf2b
pf2c
pf2d

Partial preview of the text

Download Iterators and Design Patterns in Programming Language - Lecture Slides | CMSC 433 and more Papers Programming Languages in PDF only on Docsity!

1

CMSC 433 – Programming Language

Technologies and Paradigms

Spring 2005

Iterators and Design Patterns

February 15, 2005

2

Administrivia

• Other resources:

– Thinking in Patterns with Java

  • Link from the class web page

– Gamma, Helm, Johnson, Vlissides, Design Patterns ,

Addison-Wesley 1995

– Freeman et al, Head First Design Patterns, O’Reilly,

Inner Classes

• Classes can be nested inside other classes

– These are called inner classes

• Within a class that contains an inner class, you

can use the inner class just like any other class

Example: The Queue Class

class Queue { class Entry { // Java inner class Element elt; Entry next; Entry(Element i) { elt = i; next = null; } } private Entry theQueue; void enqueue(Element e) { if (theQueue == null) theQueue = new Entry(e); else { Entry last = theQueue; while (last.next != null) last = last.next; last.next = new Entry(e); } } ...

5

Example: The Queue Class (cont’d)

class Queue { ... Element dequeue() throws EmptyQueueException { if (theQueue == null) throw new EmptyQueueException(); Element e = theQueue.elt; theQueue = theQueue.next; return e; } } 6

Referring to Outer Class

class Queue { ... int numEntries; class Entry { Element elt; Entry next; Entry(Element i) { elt = i; next = null; numEntries++; } } }

• Each inner “object” has an implicit reference to

the outer “object” whose method created it

– Can refer to fields directly, or use outer class name.

Other Features of Inner Classes

• Outside of the outer class, use outer.inner

notation to refer to type of inner class

– E.g., Queue.Entry

• An inner class marked static does not have a

reference to outer class

– Can’t refer to instance variables of outer class

– Must also use outer.inner notation to refer to inner class

• Question: Can Queue.Element be made static?

Anonymous Inner Classes

(new Thread() { public void run() { try { Thread.sleep(10006020); System.out.println("..."); System.exit(1); } catch (Exception e) {} } }).start();**

• Create anonymous subclass of thread, and invoke

method on it

13

Using Iterators

Iterator i = c.iterator(); while (i.hasNext()) { Element e = (Element) i.next(); // do stuff with e } // alternatively use for for (Iterator i = c.iterator(); i.hasNext(); ) { Element e = (Element) i.next(); // do stuff with e } 14

Iterators and Queues

• Recall queue example from beginning of lecture

• We’ll explore options for adding iterators

next() Shouldn’t Mutate Aggregate

class Queue { ... class QueueIterator implements Iterator { Entry rest; QueueIterator(Entry q) { rest = q; } boolean hasNext() { return rest != null; } Element next() throws NoSuchElementException { if (rest == null) throw new NoSuchElementException(); Element e = rest.elt; rest = rest.next; // queue data intact return e; } } }

Evil Mutating Clients

• But a client could mutate the data structure …

HashMap h = ...; ... Iterator i = h.entrySet().iterator(); System.out.println(i.next()); System.out.println(i.next()); h.put(“Foo”, “Bar”); // hash table resize! System.out.println(i.next()); // prints ???

17

Defensive (Proactive) Copying

• Solution 1: Iterator copies data structure

class QueueIterator implements Iterator { Entry rest; QueueIterator(Queue q) { // copy q.theQueue to rest } }

• Pro: Works even if queue is mutated

• Con: Expensive to construct iterator

18

Timestamps

• Solution 2: Track Mutations

class Queue { ... int modCount = 0; void enqueue(Element e) { ... modCount++; } Element dequeue() { ... modCount++; } ...

Timestamps (cont’d)

class QueueIterator implements Iterator { int expectedModCount = modCount; // set at iterator // construction time Element next() { if (expectedModCount != modCount) throw new ConcurrentModificationException(); ... } // does hasNext() need to be modified? }}

• Pro: Iteration construction cheap

• Con: Doesn’t allow any mutation 20

Comments

• Neither solution tracks mutations to container elts

– Could use clone(), but tricky

25

Object Modeling Technique (OMT)

• Used to describe patterns in GO4 book

• Graphical representation of OO relationships

– Class diagrams show the static relationship between

classes

– Object diagrams represent the state of a program as

series of related objects

– Interaction diagrams illustrate execution of the

program as an interaction among related objects

26

Classes

Object instantiation

Subclassing and Abstract Classes

29

Pseudo-code and Containment

30

Object diagrams

Interaction diagrams

time

Structure of Iterator (Cursor) Pattern

37

Example

class P implements Processor { int count = 0; public void process(Element e) { count++; } } Processor p = new Processor(); q.intIterate(p); System.out.println(p.count); iterator i = q.extIterate(); int count = 0; while (i.hasNext()) { i.next(); count++; } System.out.println(p.count);

External Internal

38

CMSC 433 – Programming Language

Technologies and Paradigms

Spring 2005

Design Patterns

February 17, 2005

Design Patterns: Goals

• To support reuse of successful designs

• To facilitate software evolution

– Add new features easily, without breaking existing ones

• In short, we want to design for change

Underlying Principles

• Reduce implementation dependencies between

elements of a software system

• Sub-goals:

– Program to an interface, not an implementation

– Favor composition over inheritance

– Use delegation

41

Program to Interface, Not Implementation

• Rely on abstract classes and interfaces to hide

differences between subclasses from clients

– Interface defines an object’s use (protocol)

– Implementation defines particular policy

• Example : Iterator interface, compared to its

implementation for a LinkedList

42

Rationale

• Decouples clients from the implementations of

the applications they use

• When clients manipulate an interface, they

remain unaware of the specific object types being

used.

• Therefore: clients are less dependent on an

implementation, so it can be easily changed later.

Favor Composition over Class Inheritance

• White box reuse:

– Inheritance

• Black box reuse:

– Composition

AClass amethod BClass amethod BClass amethod AClass amethod aVar

Delegation

• Forward messages (delegate) to different

instances at run-time; a form of composition

– May pass invoking object’s this pointer to simulate

inheritance

Rectangle area() width height Window area() rectangle Return width * height return rectangle.area()

49

Behavioral Patterns

• Template

– Define the skeleton of an algorithm in an operation,

deferring some steps to subclasses

• State

– Allow an object to alter its behavior when its internal

state changes. The object will appear to change its class

• Observer

– Define a one-to-many dependency between objects so

that when one object changes state, all its dependents

are notified and updated automatically

50

Singleton Objects

• Problem:

– Some classes have conceptually one instance

  • Many printers, but only one print spooler
  • One file system
  • One window manager

– Creating many objects that represent the same

conceptual instance adds complexity and overhead

• Solution: only create one object and reuse it

– Encapsulate the code that manages the reuse

The Singleton Solution

• Class is responsible for tracking its sole instance

– Make constructor private

– Provide static method/field to allow access to the only

instance of the class

• Benefit:

– Reuse implies better performance

– Class encapsulates code to ensure reuse of the object;

no need to burden client

Singleton pattern

53

Implementing the Singleton method

• In Java, just define a final static field

public class Singleton { private Singleton() {…} final private static Singleton instance = new Singleton(); public static Singleton getInstance() { return instance; } }

• Java semantics guarantee object is created

immediately before first use

54

Marshalling

• Marshalling is the process of transforming

internal data into a form that can be

– Written to disk

– Sent over the network

– Etc.

• Unmarshalling is the inverse process

Marhsalling in Java

• Java provides support for marshalling objects

– Classes implement the Serializable interface

– The JVM imlpements standard marhsalling and

unmarshalling automatically

  • E.g., enables you to create persistent objects, stored on disk
  • This can be useful for build a light-weight database
  • Also useful for distributed object systems

• Often, generic implementation works fine

– But let’s consider singletons...

Marhsalling and Singletons

• What happens when we unmarshall a singleton?

• Problem: JVM doesn’t know about singletons

– It will create two instances of Singleton.instance!

– Oops!

Singleton.instance Singleton.instance

61

Enumerators in Java 1.

• New version of Java has type safe enums

– Built-in: Don’t need to use the design pattern

  • public enum Suit { CLUBS, DIAMONDS, HEARTS, SPADES }

– Type checked at compile time

– Implemented as objects (translated as prev slide?)

– Two extra class methods:

  • public static [] values() -- the enumeration elts
  • public static valueOf(String name) -- get an elt 62

Adapter ( aka Wrapper) Pattern

• Problem:

– You have some code you want to use for a program

– You can’t incorporate the code directly (e.g., you just

have the .class file, say as part of a library)

– The code does not have the interface you want

  • Different method names
  • More or fewer methods than you need

• To use this code, you must adapt it to your

situation

Adapter Pattern (cont’d)

• Here’s what we have:

– Client is already written, and it uses the Target interface

– Adaptee has a method that works, but has the wrong

name

• How do we enable the Client to use the Adaptee?

Adapter Pattern (cont’d)

• Solution: adapter class to implement client’s

expected interface, forwarding methods

65

Proxy Pattern Motivation

• Goal:

– Prevent an object from being accessed directly by its

clients

• Solution:

– Use an additional object, called a proxy

– Clients access protected object only through proxy

– Proxy keeps track of status and/or location of protected

object

66

Uses of the Proxy Pattern

• Virtual proxy : impose a lazy creation semantics,

to avoid expensive object creations when strictly

unnecessary.

• Monitor proxy : impose security constraints on the

original object, say by intercepting some method

calls to proxied object.

• Remote proxy : hide the fact that an object resides

on a remote location.

More OMT Notation

• Arrow ending in filled circle

– More than one

Example Usage Class Diagram

73

Example: Java I/O

class LineNumberReader extends BufferedReader { private int lineNumber; public LineNumberReader(Reader in) { super(in); } public int getLineNumber() { return lineNumber; } public int read() { int c = super.read(); if (c == ‘\n’) { lineNumber++; return ‘\n’; } return c; } } (^) 74

Interaction Diagram

More OMT Notation

• Arrow beginning with diamond

– “Part-of” or aggregation

– Only accessed by object pointing to it

Decorator Pattern: Another Example

77

Decorator Pattern: Features

• Decorator conforms to interface of decorated

component

– Its presence is transparent to the component's clients.

• Decorator forwards requests to encapsulated

component

– May perform additional actions before or after

• Can nest decorators recursively

– Allows unlimited added responsibilities

• Can add/remove responsibilities dynamically

78

Structure

79

Decorator Pattern Analysis

• Advantages

– Fewer classes than with static inheritance

– Dynamic addition/removal of decorators

– Keeps root classes simple

• Disadvantages

– Proliferation of run-time instances

– Abstract Decorator must provide common interface

• Tradeoffs:

– Useful when components are lightweight

– Otherwise use Strategy 80

Decorator vs. Adapter

• A decorator adds to the responsibilities of an

object

– Usually has the same interface plus more features

• An adapter changes the interface

– But usually not the responsibilities