Computer Science 209 The Singleton Pattern Random Numbers
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 generator = new java. util. Random(); System. out. println(generator. next. Int(6) + 1); System. out. println(generator. next. Double()); System. out. println(generator. next. Boolean()); The Random class is much more convenient to use A Random object is also seeded from the clock
java. util. Random generator 1 = new java. util. Random(); java. util. Random generator 2 = new java. util. Random(); System. out. println(generator 1. next. Int(6) + 1); System. out. println(generator 2. next. Int(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. next. Int(6) + 1; } public String to. String(){ return "" + value; } }
Rolling a Die private Die die 1 = new Die(); private Die die 2 = new Die(); public Dice. App(){ set. Title("Roll the Dice"); dice. Field 1. set. Editable(false); dice. Field 2. set. Editable(false); roll. Button. add. Action. Listener(new Action. Listener(){ public void action. Performed(Action. Event e){ die 1. roll(); die 2. roll(); dice. Field 1. set. Text(die 1. to. String()); dice. Field 2. set. Text(die 2. to. String()); } }); Container c = get. Content. Pane(); JPanel panel = new JPanel(); panel. add(dice. Field 1); panel. add(dice. Field 2); c. add("Center", panel); c. add("South", roll. Button); }
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 Single. Random{ private static Single. Random instance = new Single. Random(); private Random generator; private Single. Random(){ generator = new Random(); } public int next. Int(int limit){ return generator. next. Int(limit); } public static Single. Random get. Instance(){ return instance; } }
A Better Die public class Better. Die{ private int value; private Single. Random generator; public Better. Die(){ value = 0; generator = Single. Random. get. Instance(); } public void roll(){ value = generator. next. Int(6) + 1; } public String to. String(){ return "" + value; } }
Playing Cards import javax. swing. *; public class Card implements. Comparable<Card>{ private String suit; private int rank; Suits are strings, but should not be just any strings public Card(String suit, int rank){ this. suit = suit; this. rank = rank; } Card queen. Of. Spades = new Card("spades", 12); Card two. Of. Hearts = new Card("hearts", 2); Must check and throw exceptions to enforce proper use
Define a New Type for Suits import javax. swing. *; public class Card implements. Comparable<Card>{ private Suit suit; private int rank; The type Suit is restricted to just 4 values public Card(Suit suit, int rank){ this. suit = suit; this. rank = rank; } Card queen. Of. Spades = new Card(Suit. spade, 12); Card two. Of. Hearts = new Card(Suit. heart, 2); The compiler enforces their proper use
public class Suit implements Comparable<Suit>{ static public final Suit spade heart diamond club = = new new Suit(4, Suit(3, Suit(2, Suit(1, "spades"); "hearts"); "diamonds"); "clubs"); private int order; private String name; private Suit(int ord, String nm){ name = nm; order = ord; } public int compare. To(Suit other){ return order - other. order; } public String to. String(){ 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, they’re 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 queen. Of. Spades = Card. new. Instance(Suit. spade, 12); Card two. Of. Hearts = Card. new. Instance(Suit. heart, 2);
- Slides: 16