Computer Science 209 The Singleton Pattern. Random Numbers System.out.println((int)(Math.random() * 6) + 1); Math.random() uses a single generator that.

Presentation on theme: "Computer Science 209 The Singleton Pattern. Random Numbers System.out.println((int)(Math.random() * 6) + 1); Math.random() uses a single generator that."— Presentation transcript:

Computer Science 209 The Singleton Pattern

Random Numbers System.out.println((int)(Math.random() * 6) + 1); Math.random() uses a single generator that is seeded at the startup of the JVM. The seed is calculated as a function of the computer s clock Kind of a pain to use to obtain random integers

java.util.Random java.util.Random generator = new java.util.Random(); System.out.println(generator.nextInt(6) + 1); System.out.println(generator.nextDouble()); System.out.println(generator.nextBoolean()); The Random class is much more convenient to use A Random object is also seeded from the clock

java.util.Random java.util.Random generator1 = new java.util.Random(); java.util.Random generator2 = new java.util.Random(); System.out.println(generator1.nextInt(6) + 1); System.out.println(generator2.nextInt(6) + 1); If distinct Random objects are seeded during the same millisecond, they will get the same seed and generate the same pseudo-random sequence

Rolling a Die import java.util.Random; public class Die{ private int value; private Random generator; public Die(){ value = 0; generator = new Random(); } public void roll(){ value = generator.nextInt(6) + 1; } public String toString(){ return "" + value; }

Rolling a Die private Die die1 = new Die(); private Die die2 = new Die(); public DiceApp(){ setTitle("Roll the Dice"); diceField1.setEditable(false); diceField2.setEditable(false); rollButton.addActionListener(new ActionListener(){ public void actionPerformed(ActionEvent e){ die1.roll(); die2.roll(); diceField1.setText(die1.toString()); diceField2.setText(die2.toString()); } }); Container c = getContentPane(); JPanel panel = new JPanel(); panel.add(diceField1); panel.add(diceField2); c.add("Center", panel); c.add("South", rollButton); }

Two Won t Work The two dice are created within a millisecond of each other, so their random number generators produce the same sequence of numbers We need a way of sharing one instance of Random among all dice

The Context of the Singleton Pattern All clients need to share a single instance of a class No additional instances can be created accidentally

Solution of the Singleton Pattern Define a class with a private constructor The class constructs a single instance of itself The class includes a static method to return the single instance

A Better Random import java.util.Random; public class SingleRandom{ private static SingleRandom instance = new SingleRandom(); private Random generator; private SingleRandom(){ generator = new Random(); } public int nextInt(int limit){ return generator.nextInt(limit); } public static SingleRandom getInstance(){ return instance; }

A Better Die public class BetterDie{ private int value; private SingleRandom generator; public BetterDie(){ value = 0; generator = SingleRandom.getInstance(); } public void roll(){ value = generator.nextInt(6) + 1; } public String toString(){ return "" + value; }

Playing Cards import javax.swing.*; public class Card implementsComparable { private String suit; private int rank; public Card(String suit, int rank){ this.suit = suit; this.rank = rank; } Card queenOfSpades = new Card("spades", 12); Card twoOfHearts = new Card("hearts", 2); Suits are strings, but should not be just any strings Must check and throw exceptions to enforce proper use

Define a New Type for Suits import javax.swing.*; public class Card implementsComparable { private Suit suit; private int rank; public Card(Suit suit, int rank){ this.suit = suit; this.rank = rank; } Card queenOfSpades = new Card(Suit.spade, 12); Card twoOfHearts = new Card(Suit.heart, 2); The type Suit is restricted to just 4 values The compiler enforces their proper use

public class Suit implements Comparable { static public final Suit spade = new Suit(4, "spades"); static public final Suit heart = new Suit(3, "hearts"); static public final Suit diamond = new Suit(2, "diamonds"); static public final Suit club = new Suit(1, "clubs"); private int order; private String name; private Suit(int ord, String nm){ name = nm; order = ord; } public int compareTo(Suit other){ return order - other.order; } public String toString(){ return name; } Similar to the singleton, but has 4 instances

Problem with Decks of Cards Every time you create a new deck, the card images must be reloaded from disk If you do this in an applet, theyre reloaded from a remote Web server Decks are mutable, but cards are not

Solution: 52 Singleton Cards The Card class maintains a static list of all cards, which are instantiated just once, when the first card is instantiated When new decks are instantiated, they receive references to cards in this list Card queenOfSpades = Card.newInstance(Suit.spade, 12); Card twoOfHearts = Card.newInstance(Suit.heart, 2);

Download ppt "Computer Science 209 The Singleton Pattern. Random Numbers System.out.println((int)(Math.random() * 6) + 1); Math.random() uses a single generator that."

Similar presentations