1
12. Patterns
3/31/2018
John Roberts
2
Overview
• Singleton
• Observer/Observable
• Model View Controller
3
Singleton
• Ensure a class has only one instance, and provide a
means of obtaining that instance
• Typically initialized on first use (just in time initialization)
4
Implementation
• Define a private, static attribute that will maintain a reference to the
single instance of the class
• Define a public static accessor function in the class (getInstance)
• Can use “lazy initialization” in this function to create the instance
the first time accessed
• Set the access level of all constructors to be protected or private
• Clients may only use the access function to manipulate the Singleton
• Github
5 https://sourcemaking.com/design_patterns/singleton/java/1
Singleton
4 public class Singleton {
5 private int counter = 0;
6
8 private Singleton() {
9 System.out.println( "Singleton created" );
10 }
11
12 public int getCounter() {
13 return this.counter;
14 }
15
16 public void incrementCounter() {
17 this.counter++;
18 }
19
20 /**
21 * SingletonHolder is loaded on the first execution of Singleton.getInstance()
22 * or the first access to SingletonHolder.INSTANCE, not before.
23 */
24 private static class SingletonHolder {
25 private static final Singleton INSTANCE = new Singleton();
26 }
27
28 public static Singleton getInstance() {
29 return SingletonHolder.INSTANCE;
30 }
31 }
6
Test
1 public class Main {
2 public static void main( String[] args ) {
3 // This is illegal
4 // Singleton illegal = new Singleton();
5 // Main.java:4: error: Singleton() has private access in Singleton
6
7 Singleton first = Singleton.getInstance();
8 System.out.println( "First count is " + first.getCounter() );
9
10 for( int i = 0; i < 5; i ++ ) {
11 first.incrementCounter();
12 }
13 System.out.println( "First count is " + first.getCounter() );
14
15 Singleton second = Singleton.getInstance();
16 System.out.println( "Second count is " + second.getCounter() );
17 }
18 }
7 https://github.com/sfsu-csc-413-roberts/lecture-12/tree/master/singleton
Output
ᐅ make
javac Main.java; java Main
Singleton created
First count is 0
First count is 5
Second count is 5
8
Benefits
• Prevents other objects from creating their own copies of
the Singleton object, ensuring that all objects access a
single instance
• This is effectively creating global state, however - some
consider this an anti-pattern
9
Singleton Pattern
• Generally considered bad practice, but its in the sample
codebase, so its presented here
• Why is it bad practice?
10
Singleton Pattern
• Generally considered bad practice, but its in the sample
codebase, so its presented here
• Why is it bad practice?
• Global state
• Typically provides behaviors that are just poor OOP
11
Overview
• Singleton
• Observer/Observable
• Model View Controller
12
Observer Pattern
• Allows observer objects to register themselves with a
subject, so that when the subject updates, the objects
receive the update
13
Example
• Professor for a course provides a way to add and remove students
from a mailing list
• Students may send the professor add or remove requests (or
administrator may add or remove as students add or drop the
course)
• When the professor modifies the course website, they send a mail to
the students on the mailing list.
• The notification tells the student which professor sent the message,
so that they know which website to look at.
• The student can then access the page to read the information.
14
Observer
• Provides an update method that can be invoked, to
inform the observer that its subject has updated
• May store a reference to the subject (an alternative
approach passes the subject as a parameter to update)
15
Subject (Observable)
• Maintains a list of observers
• Provides a method by which observers may register for
notifications (attach, addObserver, register -
there’s a few different names for the behavior)
• May also provide a method by which observers may
remove themselves
• Notifies all registered observers whenever a change
occurs to its state
16
Observable Class
1 import java.util.ArrayList;
2
3 public class Observable {
4 private ArrayList<Observer> observers = new ArrayList<>();
5
6 public void addObserver( Observer observer ) {
7 observers.add( observer );
8 }
9
10 public void removeObserver( Observer observer ) {
11 observers.remove( observer );
12 }
13
14 public void notifyObservers() {
15 for( Observer observer : observers ) {
16 observer.update( this );
17 }
18 }
19 }
17
IncrementObservable Concrete Class
1 public class IncrementObservable extends Observable {
2 private int counter;
3
4 public IncrementObservable() {
5 this.counter = 0;
6 }
7
8 public int getIncrement() {
9 return this.counter;
10 }
11
12 public void increment() {
13 this.counter++;
14 this.notifyObservers();
15 }
16 }
18
Observer Interface,
IncrementObserver Concrete Class
1 public interface Observer {
2 public void update( Observable observable );
3 }
1 public class IncrementObserver implements Observer {
2 private String name;
3
4 public IncrementObserver( String name ) {
5 this.name = name;
6 }
7
8 public void update( Observable observable ) {
9 System.out.println(
10 name + " observer sees " +
11 ((IncrementObservable) observable ).getIncrement()
12 );
13 }
14 }
19
Test
1 public class Main {
2 public static void main( String[] args ) {
3 IncrementObservable observable = new IncrementObservable();
4
5 for( int i = 0; i < 5; i++ ) {
6 observable.addObserver( new IncrementObserver( "Blarg " + i ));
7 }
8
9 observable.increment();
10 observable.increment();
11
12 System.out.println( "** I just incremented twice." );
13
14 observable.increment();
15 }
16 }
20
Output
ᐅ make
javac Main.java; java Main
Blarg 0 observer sees 1
Blarg 1 observer sees 1
Blarg 2 observer sees 1
Blarg 3 observer sees 1
Blarg 4 observer sees 1
Blarg 0 observer sees 2
Blarg 1 observer sees 2
Blarg 2 observer sees 2
Blarg 3 observer sees 2
Blarg 4 observer sees 2
** I just incremented twice.
Blarg 0 observer sees 3
Blarg 1 observer sees 3
Blarg 2 observer sees 3
Blarg 3 observer sees 3
Blarg 4 observer sees 3
21
Java Implementations
• java.util.Observable (class)
• java.util.Observer (interface)
• Github (our implementation)
22
Benefits
• Loosely coupled communication between objects
• Observers can be added or removed at any point
23
Overview
• Singleton
• Observer/Observable
• Model View Controller
24
MVC Pattern
• Model, View, Controller
• A pattern that separates internal representations of data,
and application logic specific to that data, from:
• presentation of that data
• acquisition of data from the user
• Used to implement user interfaces
25 In a web application, a model typically represents an entry in a database
Model table
• Application Data - the state of the application
• Business Rules- the logic that defines how the
application data can be manipulated
• Notifies associated views and controllers when a change
in its state occurs
26
View
• The output representation for a model
• If a model changes, the view must update accordingly
• Multiples views are possible for a single model
• Example: For a website, we might render the same
data in HTML, JSON, XML, etc.
27
Controller
• Acts as the broker between the Model and View(s)
• Sends commands to Model to update its state
• Receives input from View, converts to commands for the
Model - translates a user’s interactions with the View into
actions that the Model will perform
28
MVC Pattern
Controller
Manipulates User Input
Model Updates View
29
MVC Pattern
• A use of the Observer/Observable pattern
• The Model is an Observable
• The View is an Observer
• The Controller associates a View (Observer) with a
Model (Observable)
30
Benefits
• Loosely Coupled
• Each piece has its own responsibility
• Business logic is not embedded in the view, event
processing is not embedded in the model