58
Unit 3 Singleton Summary prepared by Kirk Scott 1

Unit 3 Singleton

  • Upload
    jed

  • View
    41

  • Download
    3

Embed Size (px)

DESCRIPTION

Unit 3 Singleton. Summary prepared by Kirk Scott. Design Patterns in Java Chapter 8 Singleton. Summary prepared by Kirk Scott. General Background on Responsiblity. Objects in general should be responsible for themselves That means that they should be internally consistent - PowerPoint PPT Presentation

Citation preview

Page 1: Unit 3 Singleton

1

Unit 3Singleton

Summary prepared by Kirk Scott

Page 2: Unit 3 Singleton

2

Design Patterns in JavaChapter 8Singleton

Summary prepared by Kirk Scott

Page 3: Unit 3 Singleton

3

General Background on Responsiblity

• Objects in general should be responsible for themselves

• That means that they should be internally consistent

• It also means that they are self-sufficient• They do not depend (on the whole) on other

classes/objects• They do not implement their functionality by

referring to other classes/objects

Page 4: Unit 3 Singleton

4

• In modeling a real problem domain, it can happen that for a given class there will be only one instance

• This situation is known as a singleton• The idea is that the code for the class should

control how many instances of it there are• It should not be the responsibility of all external

code to determine how many instances there are

Page 5: Unit 3 Singleton

5

Classification as a Construction Pattern or a Responsibility Pattern

• For the purposes of this course, whether or not there are one or more instances of a given class is treated as a construction question

• The book classifies the singleton pattern by intention as a responsibility pattern

• Accept as a given that all classes/objects in an application are connected to each other in one way or another

Page 6: Unit 3 Singleton

6

• If there is a singleton class, responsibility for maintaining it as a singleton can be centralized in the class itself

• In the context of the whole application, responsibility for this part of the design has been centralized

• As a consequence, any other class/object that deals with the singleton becomes dependent on the logic implemented in the singleton class

Page 7: Unit 3 Singleton

7

Book Definition of the Pattern

• Book definition:• The intent of the Singleton pattern is to ensure

that a class has only one instance and to provide a global point of access to it.

• Comment mode on:• Note that this statement of intent only indirectly

hints at the justification given for classifying the pattern as a responsibility pattern.

Page 8: Unit 3 Singleton

8

• The authors concede that there is a mismatch between this pattern and its classification

• They state, “The mechanics of Singleton are more memorable than its intent.”

• Put another way, the statement of intent is really a statement of mechanics

• The pattern incidentally involves the apportionment of responsibility, but its purpose really has to do with construction rather than responsibility itself.

Page 9: Unit 3 Singleton

9

• The authors go on to mention that the original Design Patterns book categorized Singleton as a “creational” pattern

• In other words, other authors, equally competent in the field, have classified patterns more by their structure and syntactical consequences

• It doesn’t matter how Singleton is classified

Page 10: Unit 3 Singleton

10

• It is simply worthwhile to remember the pattern and understand where it might be useful to apply it

• Incidentally, as will be seen with other patterns, it is also worth noting some of the implementation “tricks” that the authors reveal

• The authors now jump into the nuts and bolts of implementation

Page 11: Unit 3 Singleton

11

Implementing the Pattern

• Challenge 8.1• How can you prevent other developers from

constructing new instances of your class?

Page 12: Unit 3 Singleton

12

• Solution 8.1• To prevent other developers from instantiating

your class, create a single constructor with private access.

• Note that if you create other, nonprivate constructors or no constructors at all, other objects will be able to instantiate your class

Page 13: Unit 3 Singleton

13

• Comment mode on:• The idea of a private constructor has not come

up before• If you have a private constructor, the question

becomes, how and where do you call it from?

Page 14: Unit 3 Singleton

14

• There is some muddling in the book’s explanation of all this which I will try and straighten out before finishing with the topic

• The book phrases the question of how and where to construct as, “…when to instantiate the single object…”

Page 15: Unit 3 Singleton

15

• The authors propose that there be a SystemStartup class in a software system which contains the following combined instance variable declaration and construction

• private static Factory factory = new Factory();

Page 16: Unit 3 Singleton

16

• The authors seem to have gone slightly off the track here

• If the constructor for Factory is private, it couldn’t be called in the SystemStartup class code

• The next statement they make is that “this class” could make its instance variable available through a public getFactory() method

Page 17: Unit 3 Singleton

17

• Ignore the SystemStartup class for a moment• In skeletal form, the Factory class definition on

the following overhead appears to be the solution that the authors are proposing

• The Factory class contains a default constructor which is declared private

Page 18: Unit 3 Singleton

18

• public class Factory• {• private static Factory factory = new Factory();• private Factory()• {• }• public static getFactory()• {• return factory;• }• }

Page 19: Unit 3 Singleton

19

• The class contains a static instance of itself as an instance variable

• The variable is constructed (once) in the declaration by a call to the private constructor

• The class also contains a static getFactory() method which returns a reference to the singleton

• The call to the get method in a client piece of code would be like any call to a static method:

• Factory singletonReference = Factory.getFactory();

Page 20: Unit 3 Singleton

20

• The book’s solution works• Not having considered the possibility of

private constructors or classes containing instance variables which are instances of themselves, this is not the first solution approach that would have occurred to me

• I would have been thinking along different lines

Page 21: Unit 3 Singleton

21

An Alternative Approach to Implementing the Pattern

• The following overhead shows a starting approach to solving the problem

• Notice that it is incomplete• You are stopped when you realize that a

constructor is a constructor• In other words, a constructor has to construct

something (or so it would seem)

Page 22: Unit 3 Singleton

22

• /* An approach to creating a singleton that doesn’t work. */

• public class Factory• {• private static int instanceCount = 0;• public Factory()• {• if(instanceCount == 0)• // do the construction• else• // don’t do the construction• }• }

Page 23: Unit 3 Singleton

23

• Within the code for a constructor it is not possible to make the construction conditional like for a method

• It’s not like a method where you have a choice of either returning a reference or returning null

• Once the constructor is called, a new object is created and will be returned

• All that’s taken care of in the body of a constructor is the initialization of the instance variables

Page 24: Unit 3 Singleton

24

• However, this is not the end of the story• A constructor, like a method, can be declared

to throw an exception• Then the code can be written either to run

successfully and return a reference to a newly created object

• Or to throw an exception if the conditions for the Singleton design pattern aren’t met

Page 25: Unit 3 Singleton

25

• public class Factory• {• private static int instanceCount = 0;• public Factory() throws Exception• {• if(instanceCount == 0)• instanceCount++;• else• throw new Exception(“Uh-oh”);• }• }

Page 26: Unit 3 Singleton

26

• Although the previous code isn’t the way the book does it, the code compiles

• The thing client code would have to keep in mind is that a call to the constructor would have to be done in a try/catch block

• This is not an entirely bad solution• It does restrict a class to having at most one

instance

Page 27: Unit 3 Singleton

27

• On the other hand, it’s not necessarily an ideal solution

• The point is that it would be convenient to simply be returned a reference to the one existing instance if one has already been created

• This solution puts the burden on the client code of keeping track of whether it’s created an instance before

Page 28: Unit 3 Singleton

28

• In other words, in terms of responsibility and centralization, this solution decentralizes responsibility.

• If there are >1 client and one creates the instance, then any other client that tries to create an instance will receive an exception.

• Responsibility for making sure there is only one instance is centralized in the singleton class.

• Clients, however, are still have responsibility for noting whether or not the one instance has already been created.

Page 29: Unit 3 Singleton

29

Lazy Initialization

• Next, the book introduces what it calls lazy initialization

• The idea is that an instance of the Singleton class is only constructed if some piece of client code requests a reference to it

• This requires removing the construction from the line declaring the instance variable

• Construction is then inserted into the getFactory() method

• This is shown on the next overhead

Page 30: Unit 3 Singleton

30

• public class Factory• {• private static Factory factory;• private Factory()• {• }• public static getFactory()• {• if(factory == null)• factory = new Factory();• return factory;• }• }

Page 31: Unit 3 Singleton

31

• Challenge 8.2• Why might you decide to lazy-initialize a

singleton instance rather than to initialize it in its field declaration?

Page 32: Unit 3 Singleton

32

• Solution 8.2• Two reasons for lazy-initializing singletons are as

follows.• 1. You might not have enough information to

instantiate a singleton at static initialization time.

• For example, a Factory singleton might have to wait for the real factory’s machines to establish communication channels.

Page 33: Unit 3 Singleton

33

• 2. You might choose to lazy-initialize a singleton that requires resources, such as a database connection, especially if there is a chance that the containing application will not need the singleton in a particular session.

Page 34: Unit 3 Singleton

34

• Whether you lazy initialize or not• Construction of the singleton takes place in

the singleton’s class• And access to the singleton is provided

through a public, static method

Page 35: Unit 3 Singleton

35

Singletons and Threads

• CS 320 is not a pre-requisite for CS 304• This subsection depends on understanding

concepts from CS 320, so it is not part of CS 304

• If you have had CS 320, you should be able to read the section and get the idea

• It will be presented in brief here.

Page 36: Unit 3 Singleton

36

• Suppose that you do lazy initialization• The goal of the getFactory() method is to construct

only one instance• Suppose you have two client threads which can call

getFactory()• If you don’t synchronize on the call to getFactory(),

both threads could run the method concurrently, resulting in the construction of two Factory objects

• This defeats the goal of implementing a singleton

Page 37: Unit 3 Singleton

37

• The book proposes a solution that is based on using the lock concept in Java

• Alternative coding solutions are available since Java has lots of stuff in the API related to threads and synchronization

• The book presents sample code, a challenge, and solution code

Page 38: Unit 3 Singleton

38

• None of that will be pursued• If you haven’t had CS 320, you can ignore the

whole topic• It has only been addressed briefly here for the

benefit of those who have already taken CS 320

Page 39: Unit 3 Singleton

39

Recognizing Singleton

• In an overall design, classes shouldn’t overlap with each other in their content and functionality

• In other words, classes are unique• On the other hand, you can generally have

multiple instances of one class

Page 40: Unit 3 Singleton

40

• Each of the objects is distinct and unique• The objects differ according to the contents of

their instance variables• In general, you can say that the individual

objects are only responsible for themselves, based on the code defined in their class

Page 41: Unit 3 Singleton

41

• It may be the case that for a particular application, under certain conditions, only one instance of a given class is needed

• In reality, singletons, where more than one instance has to be prevented, are rare

• The trick is learn how to identify that situation• Consider the following UML diagram

Page 42: Unit 3 Singleton

42

Page 43: Unit 3 Singleton

43

• Challenge 8.4• For each class in Figure 8.1, say whether it

appears to be a singleton class, and why.• Spoiler mode on:• The authors aren’t really satisfied that any of

these classes they’ve given are a good example of a singleton…

Page 44: Unit 3 Singleton

44

• Solution 8.4• OurBiggestRocket: • This class has an inappropriate name. • You would normally model attributes, such as

“biggest,” with attributes, not with class names. • If a developer must sustain this class, perhaps it is a

singleton.• TopSalesAssociate: • This class has the same problem as OurBiggestRocket.

Page 45: Unit 3 Singleton

45

• Math: • This class is a utility, with all static methods and no

instances. • It is not a singleton. • Note that it does, however, have a private

constructor. • [Why? I don’t know.]• System: • This is also a utility.

Page 46: Unit 3 Singleton

46

• PrintStream: • Although the System.out object is a PrintStream object

with unique responsibilities, it is not a unique instance of PrintStream, which is not a singleton class.

• PrintSpooler: • PrintSpoolers are associated with one or a few printers; • it’s unlikely that this is a singleton.• PrinterManager: • At Oozinoz, you have many printers, and you can look up

their addresses through the PrinterManager singleton.

Page 47: Unit 3 Singleton

47

• The authors say that Singleton is probably the best known pattern

• This may be because it is easy to understand• It may also be because, for C style

programmers, it makes it easy to get around the requirements of object-oriented programming

• A singleton object can serve as a global type of variable

Page 48: Unit 3 Singleton

48

• In general, the reason for the existence of a singleton is some restriction in the problem domain

• A singleton shouldn’t be introduced unless a good reason can be found for having one

• Client code, if at all possible, should have no interest in special conditions on the creation of instances of other classes (like singletons)

Page 49: Unit 3 Singleton

49

• If a class is to have subclasses or different versions, singleton won’t work at all

• The restrictions on construction in the superclass will mess up construction in the subclasses

Page 50: Unit 3 Singleton

50

Another Example

• It will be clear that the following example is not taken from some real business application.

• It is given simply as a way of reiterating the idea of a singleton and how to accomplish it in code.

• As you will see, non-book examples in future units will tend to follow this model.

Page 51: Unit 3 Singleton

51

• The code on the following overhead shows a class implemented using the singleton pattern using the coding technique suggested by the book.

Page 52: Unit 3 Singleton

52

• public class MonotheisticGod• {• private static MonotheisticGod oneGod;

• private MonotheisticGod()• {• }

• public static MonotheisticGod getMonotheisticGod()• {• if(oneGod == null)• oneGod = new MonotheisticGod();

• return oneGod;• }• }

Page 53: Unit 3 Singleton

53

• The code on the following overhead shows a call to obtain a reference to the foregoing singleton.

Page 54: Unit 3 Singleton

54

• public class TestGod• {• public static void main(String[] args)

• {• MonotheisticGod myOneGod = MonotheisticGod.getMonotheisticGod();

• System.out.println(myOneGod);• }• }

Page 55: Unit 3 Singleton

55

UML for the Pattern

• The singleton pattern is so simple that there is no particular UML diagram that illustrates it

• You would most likely include it in a UML diagram of a design, or recognize it in a UML diagram of a design, by means of a cardinality value of 1 at the end of some an arc representing a “has-a” relationship (composition)

Page 56: Unit 3 Singleton

56

Summary

• The Singleton pattern means only one object of a given class will be created

• By definition, this means there is a single, global occurrence of the class

• Lazy initialization can be a useful feature of the implementation of Singleton

• In a multi-threaded environment synchronization has to be used in order to make sure that an implementation of singleton works correctly

Page 57: Unit 3 Singleton

57

• Keep in mind that just because there is only one instance of a class in a given application, that doesn’t mean that the singleton pattern is appropriate

• From a pragmatic point of view, this warning is especially apropos if the class has subclasses

• The Singleton pattern centralizes responsibility in a single instance of a class by hiding the constructor and providing a single point of access to object creation

Page 58: Unit 3 Singleton

58

The End