head-first design patterns. similar to a reminderentry

21
Head-First Design Patterns

Post on 19-Dec-2015

229 views

Category:

Documents


3 download

TRANSCRIPT

Page 1: Head-First Design Patterns. Similar to a ReminderEntry

Head-First Design Patterns

Page 2: Head-First Design Patterns. Similar to a ReminderEntry

Similar to a ReminderEntry

Page 3: Head-First Design Patterns. Similar to a ReminderEntry

Similar to Reminders

But no iterator. Just the raw data structure, i.e., ArrayList.

To use this, outsider will have to keep index, increment it, etc.

And they can change it!

Page 4: Head-First Design Patterns. Similar to a ReminderEntry

How to use raw

Get raw here.

Set up loop here.

Page 5: Head-First Design Patterns. Similar to a ReminderEntry

Use Iterator instead

Much cleaner.

Don’t need to know what data structure is being used.

Just need to know I can use next and hasNext.

And no access to raw!

What work do we have to do to make this so easy in above code?

1.define createIterator method in BreakfastMenu class.2.Figure out how to define that Iterator class that’s doing all the work.

Page 6: Head-First Design Patterns. Similar to a ReminderEntry

The hard way: define your own Iterator class

Would be similar to defining a RemindersIterator class.

I *think* this code is poorly designed!

Why?

Because is does not clone the list from what I can see.

Page 7: Head-First Design Patterns. Similar to a ReminderEntry

Code to show the strangenessDinerMenu dmenu = new DinerMenu();DinerMenuIterator dit1 = dmenu.createIterator();boolean b1 = dit1.hasNext(); //should be falsedmenu.add(“some new entry”);DinerMenuIterator dit2 = dmenu.creatIterator();boolean b2 = dit2.hasNext(); //should be true

//Big questionb1 = dit1.hasNext(); //I predict will be true now

Solution?public DinerMenuIterator createIterator(){

return new DinerMenuIterator( menuItems.clone() );}

Takes a “snapshot” of the data. If changes made later, snapshot is unchanged.

Page 8: Head-First Design Patterns. Similar to a ReminderEntry

The easy way: look at data structure API!

Data Structure Method to return iterator

ArrayList .iterator()

LinkedList .iterator()

Vector .iterator()

array Class ArrayIterator

… …

Note that these methods do not clone either. If you want a snapshot, you will have to do something like:

return my_linkedlist.clone().iterator();

Page 9: Head-First Design Patterns. Similar to a ReminderEntry

Another Chapter

Page 10: Head-First Design Patterns. Similar to a ReminderEntry

How to use it:

Singleton s = Singleton.getInstance();

s.someMethod();

public void someMethod(){…}

Access Levels

Modifier Class Package Subclass World

public Y Y Y Y

protected Y Y Y N

no modifier Y Y N N

private Y N N N

Page 11: Head-First Design Patterns. Similar to a ReminderEntry

Singleton Brings Up Concurrency Issues

• Many modern programs use multiple threads of control.

• This gives lots of power, e.g., multi-core, time-sharing in single-core.

• But it also brings up problems.• Like to introduce you to one of them:

concurrency bugs.• Can use the Singleton pattern as example.

Page 12: Head-First Design Patterns. Similar to a ReminderEntry

public class ThreadedClass extends Thread

public void run(int i){ //this method runs when start() is invokedwhile( true ){

System.out.println( i );}

}

public static void main( String[] args ){ ThreadedClass t1 = new ThreadedClass(); t1.start(1); ThreadedClass t2 = new ThreadedClass(); t2.start(2);

} }

What is printed?

First Look at Thread class

Page 13: Head-First Design Patterns. Similar to a ReminderEntry

public class ThreadedClass extends Thread static int data;

public ThreadedClass(){

data = 0; }

public void run(){ //this method runs when start() is invokedwhile( true ){

int k = data;k++;data = k;

System.out.println( data );}

}

public static void main( String[] args ){ ThreadedClass t1 = new ThreadedClass(); t1.start(); ThreadedClass t2 = new ThreadedClass(); t2.start();

} }

What is printed?

Gets more interesting. Opens the door for concurrency bugs. This will be shared by all threads.

Page 14: Head-First Design Patterns. Similar to a ReminderEntry

while( true ){ t1int k = data;k++;data = k;

System.out.println( data );}

while( true ){ t2int k = data;k++;data = k;

System.out.println( data );}

t1: k1 = 0t1: k1 = 1<suspend t1>t2: k2 = 0t2: k2 = 1<suspend t2>t1: data = 1t1: SOP 1<suspend t1>t2: data = 1t2: SOP 1

t1: …t1: data = 1<suspend t1>t2: …t2: data = 2<suspend t2>t1: SOP 1<suspend t1>t2: SOP 2ti: SOP 3ti: SOP4etc.

What do we expect printed with two threads running?

data

Page 15: Head-First Design Patterns. Similar to a ReminderEntry

t1

<some Android activity>

t2

<some Android service>

Who Cares?

data

t3<some Android activity>

Where could this bite us in our project?

Page 16: Head-First Design Patterns. Similar to a ReminderEntry
Page 17: Head-First Design Patterns. Similar to a ReminderEntry

You can synchronize methods!

Means only one thread at a time can use.

Can’t break up into smaller chunks.

Solves the concurrency bug we saw.

Why is it expensive?

Page 18: Head-First Design Patterns. Similar to a ReminderEntry

View as an annotation that says multiple threads might share this variable.

Did we squash this concurrency bug?

Page 19: Head-First Design Patterns. Similar to a ReminderEntry

One Other Idea

Page 20: Head-First Design Patterns. Similar to a ReminderEntry

Serialization Issuespublic class Singleton implements java.io.Serializable { public final static Singleton INSTANCE = new Singleton(); private Singleton() { }}

///////////////////////////////////////////////////////////////////////////////////////////

public class SingletonTest { public static void main(String [] args){ writeSingleton(); Singleton s1 = readSingleton(); Singleton s2 = readSingleton(); Assert.assertEquals(true, s1 == s2); }

private static void writeSingleton() { FileOutputStream fos = new FileOutputStream("serializedSingleton"); ObjectOutputStream oos = new ObjectOutputStream(fos); oos.writeObject(Singleton.INSTANCE); oos.flush(); } private static Singleton readSingleton() { Singleton s = null; FileInputStream fis = new FileInputStream("serializedSingleton"); ObjectInputStream ois = new ObjectInputStream(fis); s = (Singleton)ois.readObject(); return s; }}

true or false?

Page 21: Head-First Design Patterns. Similar to a ReminderEntry

Work Aroundpublic class Singleton implements java.io.Serializable { public static Singleton INSTANCE = new Singleton(); protected Singleton() {} private Object readResolve() { return INSTANCE; }}

The readResolve method is called when ObjectInputStream has read an object from the stream and is preparing to return it to the caller. ObjectInputStream checks whether the class of the object defines the readResolve method. If the method is defined, the readResolve method is called to allow the object in the stream to designate the object to be returned. The object returned should be of a type that is compatible with all uses. If it is not compatible, a ClassCastException will be thrown when the type mismatch is discovered.