



















Study with the several resources on Docsity
Earn points by helping other students or get them with a premium plan
Prepare for your exams
Study with the several resources on Docsity
Earn points to download
Earn points by helping other students or get them with a premium plan
Pattern classification Creational Pattern singleton pattern adding flexibility UML world diagram protected constructor lazy creation thread synchronize Factory method pattern border factor naming
Typology: Slides
1 / 27
This page cannot be seen from the preview
Don't miss anything!




















Ian Holyer Ian Holyer
โ You remember the "periodic table" of patterns:You remember the "periodic table" of patterns:
โ The creational patterns we will look at are:The creational patterns we will look at are: โ singleton (global variable, but with flexibility) โ factory method (creates objects without 'new') โ abstract factory (create objects in matching families) โ A couple that we won't look at are:A couple that we won't look at are: โ prototype (an alternative factory for complex data) โ builder (helps in building a complex data structure)
โ In Java programming, people often ask "where should IIn Java programming, people often ask "where should I store global data, so I can get at it from everywhere?" store global data, so I can get at it from everywhere?" โ The answer is to use a static objectThe answer is to use a static object public class Program { public static Random globalGenerator; } ... gen = Program.globalGenerator ... โ The singleton pattern is used when you want a singleThe singleton pattern is used when you want a single global object of a particular class (e.g. global object of a particular class (e.g. thethe database ordatabase or the the users orusers or thethe preferences orpreferences or thethe window manager...)window manager...)
โ Here's the simplest possible way of defining a singletonHere's the simplest possible way of defining a singleton public class World { public static World theWorld = new ...; private Continent[] continents ... } โ and how to use it from anywhere:and how to use it from anywhere: ... World theWorld = World.theWorld; ... theWorld.getContinents() ... ...
โ How do you stop someone from accidentally orHow do you stop someone from accidentally or maliciously creating a second world? maliciously creating a second world? โ You override the default constructor, and make it privateYou override the default constructor, and make it private so no other classes can use it: so no other classes can use it: public class World { public static World theWorld = new ...; private Continent[] continents ... private World() { ... } }
โ At this point, we have matched our original UMLAt this point, we have matched our original UML diagram: diagram: โ The most obvious example from the Java libraries isThe most obvious example from the Java libraries is Runtime.getRuntime() โ But this is not the end of the singleton storyBut this is not the end of the singleton story World
โ If the constructor is private, you can't have a class whichIf the constructor is private, you can't have a class which extends World (because you can't create objects) extends World (because you can't create objects) โ So, you can make the contructor protected, i.e. visible toSo, you can make the contructor protected, i.e. visible to extending classes, and classes in the same package extending classes, and classes in the same package โ So you had better put the class in a package:So you had better put the class in a package: package ... public class World { protected World() { ... } }
โ One further potentially big problem with our WorldOne further potentially big problem with our World class is that it is not thread safe class is that it is not thread safe โ What could go wrong with multiple threads?What could go wrong with multiple threads? if (theWorld == null) theWorld = ...; โ Suppose one thread executes the test, and is suspendedSuppose one thread executes the test, and is suspended before the assignment before the assignment โ Now a second thread executes the whole line and createsNow a second thread executes the whole line and creates a world object a world object โ Finally, the first thread runs again and creates aFinally, the first thread runs again and creates a secondsecond world object world object
โ Perhaps the easiest solution is to make the World safe byPerhaps the easiest solution is to make the World safe by synchronizing the getTheWorld method synchronizing the getTheWorld method โ Then only one thread can execute it at a timeThen only one thread can execute it at a time public class World { private static World theWorld ...; synchronized public static World getTheWorld() { ... } }
โ A singleton (or a static, for that matter) is really a globalA singleton (or a static, for that matter) is really a global variable, and global variables are ultimately bad, variable, and global variables are ultimately bad, because they are inflexible because they are inflexible โ Suppose you want to test or adapt a program bySuppose you want to test or adapt a program by replacing the environment (including singletons) by a replacing the environment (including singletons) by a 'fake' one - you can't 'fake' one - you can't โ Suppose you want to write a program which runs twoSuppose you want to write a program which runs two other programs (not as separate processes) and each sub- other programs (not as separate processes) and each sub- program has its own idea of how to use the singletons - program has its own idea of how to use the singletons - you can't you can't โ Example: an auto-marking program: for speed, it mustExample: an auto-marking program: for speed, it must run each person's program in turn in the same process run each person's program in turn in the same process
โ The other patterns are about creating ordinary objects,The other patterns are about creating ordinary objects, not global ones not global ones โ They are based on the fact that using the new keyword isThey are based on the fact that using the new keyword is inflexible, almost NONO inflexible, almost NONO Thing t = new Thing(); โ That is because itThat is because it forcesforces the Thing class tothe Thing class to createcreate a newa new object to respond to your request object to respond to your request โ The Thing class can't be changed to re-use an object thatThe Thing class can't be changed to re-use an object that it already has lying around instead of creating one it already has lying around instead of creating one โ And it can't be changed to return an object of a differentAnd it can't be changed to return an object of a different class which extends Thing class which extends Thing
โ The UML diagram summarising this is:The UML diagram summarising this is: Thing SpecialThing Factory SpecialFactory newThing(): Thing newThing(): Thing (having different factory classes is not essential)
โ A Border in the Swing package (javax.swing) is anA Border in the Swing package (javax.swing) is an object which decorates the edge of a rectangle: object which decorates the edge of a rectangle: โ A variety of different border classes deal withA variety of different border classes deal with variations, e.g. EtchedBorder, CompoundBorder variations, e.g. EtchedBorder, CompoundBorder โ After you have created a border, all you need to knowAfter you have created a border, all you need to know about it is its thickness (it doesn't have a width and about it is its thickness (it doesn't have a width and height, because those come from the component you height, because those come from the component you attach it to, and that allows sharing of border objects) attach it to, and that allows sharing of border objects)