Created
September 23, 2009 07:12
-
-
Save ngerakines/191804 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> | |
| <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> | |
| <head> | |
| <meta http-equiv="Content-type" content="text/html;charset=UTF-8" /> | |
| <title>Game Programming Patterns / Singleton</title> | |
| <link rel="stylesheet" type="text/css" href="styles.css" /> | |
| <script src="jquery-1.3.2.min.js" type="text/javascript"></script> | |
| </head> | |
| <body> | |
| <div class="nav"> | |
| <h1><a href="index.html">Navigation</a></h1> | |
| <ul> | |
| <li>Getting Started | |
| <ul> | |
| <li><a href="introduction.html">Introduction</a></li> | |
| <li>Working with Patterns</li> | |
| </ul> | |
| </li> | |
| <li>Design Patterns Revisited</li> | |
| <ul> | |
| <li>Decorator</li> | |
| <li>Prototype</li> | |
| <li><a href="singleton.html">Singleton</a></li> | |
| <li>Flyweight</li> | |
| <li>Command</li> | |
| <li>Observer</li> | |
| <li>State</li> | |
| <li>Strategy</li> | |
| </ul> | |
| <li>Game Programming Patterns | |
| <ul> | |
| <li>Sequencing Patterns | |
| <ul> | |
| <li>Game Loop</li> | |
| <li>Update Method</li> | |
| <li>Double Buffer</li> | |
| <li>Dead Pool</li> | |
| </ul> | |
| </li> | |
| <li>Behaving Patterns | |
| <ul> | |
| <li>Split Representation</li> | |
| <li>Metaclass</li> | |
| <li>Sandbox Method</li> | |
| <li>Context Parameter</li> | |
| <li>Virtual Machine</li> | |
| </ul> | |
| </li> | |
| <li>Communicating Patterns | |
| <ul> | |
| <li>Service</li> | |
| <li>Message Queue</li> | |
| <li>Blackboard</li> | |
| <li>Area Effect</li> | |
| <li>Collision</li> | |
| </ul> | |
| </li> | |
| <li>Optimizing Patterns | |
| <ul> | |
| <li><a href="object-pool.html">Object Pool</a></li> | |
| <li>Structure of Arrays</li> | |
| <li>Dirty Bits</li> | |
| </ul> | |
| </li> | |
| </ul> | |
| </li> | |
| </ul> | |
| </div><div id="content"> | |
| <h1 class="book">Game Programming Patterns</h1> | |
| <h1>Singleton</h1> | |
| <div class="feedback"> | |
| <p>You're reading a work-in-progress. If you'd like to help | |
| make it better, please give me some feedback by emailing. | |
| The address is my name (robert) at stuffwithstuff.com.</p> | |
| <p><a href="#" class="hide">hide</a></p> | |
| <p>Thank you!</p> | |
| </div> | |
| <script type="text/javascript"> | |
| /* <![CDATA[ */ | |
| $(document).ready(function() | |
| { | |
| $("a.hide").click(function(event) { | |
| $(this).parent().parent().hide(); | |
| event.preventDefault(); | |
| }); | |
| }); | |
| /* ]]> */ | |
| </script> | |
| <p>This chapter is an anomaly. Every other chapter in this book shows | |
| you how to use a design pattern. This one shows you how <em>not</em> to use | |
| one.</p> | |
| <p>Despite noble intentions, the <a class="gof-pattern" | |
| href="http://c2.com/cgi/wiki?SingletonPattern">Singleton</a> pattern | |
| described by the Gang of Four usually does more harm than good. While | |
| they stress that the pattern should be used sparingly, game | |
| programmers struggling with object-oriented programming took it and | |
| ran with it. Like any pattern, using it where it doesn’t belong is | |
| about as helpful as treating a bullet wound with a splint. Since it’s | |
| so over-used, most of this chapter will be about <em>avoiding</em> | |
| Singletons, but first, let’s go over the pattern itself.</p> | |
| <h2>The Singleton Pattern</h2> | |
| <p><em>Design Patterns</em> summarizes Singleton like this:</p> | |
| <blockquote> | |
| <p>Ensure a class has one instance, and provide a global point of | |
| access to it.</p> | |
| </blockquote> | |
| <p>We’ll split that at “and” and consider each half | |
| separately.</p> | |
| <h3>Restricting a Class To One Instance</h3> | |
| <p>There are times when a class cannot perform correctly if there is more | |
| than one instance of it. The common case is when the class interacts | |
| with an external system that maintains its own global state.</p> | |
| <p>Consider a class that wraps an underlying file system API. Because | |
| file operations can take a while to complete, our class performs | |
| operations asynchronously. This means multiple operations can be | |
| running concurrently, so they must be coordinated with each other. If | |
| we start one call to create a file, and another one to delete that | |
| same file, our wrapper needs to be aware of both to make sure they | |
| don’t interfere with each other.</p> | |
| <p>To do this, a call into our wrapper needs to have access to every | |
| previous operation. If users could freely create instances of our | |
| class, one instance has no way of knowing about operations that other | |
| instances started. Enter the Singleton. It provides a way for a class | |
| to ensure at compile time that there is only a single instance of the | |
| class.</p> | |
| <h3>Providing a Global Point of Access</h3> | |
| <p>Several different systems in the game will use our file system | |
| wrapper: logging, content loading, game state saving, etc. If those | |
| systems can’t create their own instances of our file system wrapper, | |
| how do they get ahold of one?</p> | |
| <p>Singleton provides a solution to this too. In addition to creating the | |
| single instance, it also provides a globally-available method to get | |
| it. This way, anyone |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| h1, h2, h3, h4, p, blockquote, code, ul, ol, img { | |
| margin: 0; | |
| } | |
| body { | |
| /* background-image: url("grid.gif"); */ | |
| margin: 40px 20px; | |
| line-height: 20px; | |
| } | |
| #content h1 { | |
| color: #000; | |
| font: normal 24px/40px 'Century Schoolbook', Georgia, serif; | |
| margin-bottom: 20px; | |
| padding: 0 0 5px 0; | |
| border-bottom: solid 5px #ddd; | |
| width: 560px; | |
| } | |
| #content h1.book { | |
| color: #777; | |
| font: normal 18px/20px 'Century Schoolbook', Georgia, serif; | |
| padding-bottom: 10px; | |
| width: 560px; | |
| border: none; | |
| } | |
| h2 { | |
| color: #05f; | |
| font: normal 18px/20px 'Century Schoolbook', Georgia, serif; | |
| padding: 10px 0 10px 0; | |
| width: 560px; | |
| } | |
| h3 { | |
| color: #05f; | |
| font: italic 16px/20px 'Century Schoolbook', Georgia, serif; | |
| padding: 0 0 0 20px; | |
| width: 560px; | |
| } | |
| h4 { | |
| color: #777; | |
| font: italic 15px/20px 'Century Schoolbook', Georgia, serif; | |
| padding: 0 0 0 20px; | |
| width: 560px; | |
| } | |
| p { | |
| margin-bottom: 20px; | |
| padding: 0; | |
| } | |
| p, li { | |
| color: #333; | |
| font: normal 15px/20px 'Century Schoolbook', Georgia, serif; | |
| } | |
| li { | |
| /* lighten the bullets. this will also have the intended side- | |
| effect of making it apparent when markdown fails to wrap a | |
| list item's text in a <p>, which screws up the formatting. */ | |
| color: #777; | |
| } | |
| ul, ol { | |
| padding: 0 0 0 20px; | |
| } | |
| a { | |
| color: #05f; | |
| text-decoration: none; | |
| } | |
| img { | |
| padding: 0 0 16px 20px; | |
| } | |
| blockquote { | |
| width: 460px; | |
| background: #f4f4f4; | |
| margin: -10px 0 10px 40px; | |
| padding: 8px 20px 12px 20px; | |
| } | |
| blockquote p { | |
| font-style: italic; | |
| color: #777; | |
| } | |
| blockquote p { | |
| margin-bottom: 0; | |
| } | |
| blockquote p + p { | |
| margin-top: 20px; | |
| } | |
| /* make room for the sidebar */ | |
| #content > p { | |
| margin-left: 20px; | |
| width: 540px; | |
| } | |
| #content > ol, | |
| #content > ul { | |
| margin-left: 20px; | |
| width: 520px; | |
| } | |
| #content > pre { | |
| margin-left: 20px; | |
| width: 500px; | |
| } | |
| pre { | |
| color: #777; | |
| font: normal 12px/20px 'Bitstream Vera Sans Mono', Monaco, Consolas, monospace; | |
| background: #f4f4f4; | |
| margin: -10px 0 10px 0; | |
| padding: 8px 20px 12px 20px; | |
| } | |
| code { | |
| color: #777; | |
| font: normal 12px 'Bitstream Vera Sans Mono', Monaco, Consolas, monospace; | |
| } | |
| #content { | |
| margin-left: 240px; | |
| width: 800px; | |
| } | |
| /* sidebar */ | |
| .sidebar { | |
| float: right; | |
| clear: right; | |
| } | |
| .sidebar p { | |
| color: #777; | |
| font: italic 13px/20px 'Century Schoolbook', Georgia, serif; | |
| width: 200px; | |
| } | |
| .sidebar em { | |
| font-style: normal; | |
| } | |
| /* nav bar */ | |
| .nav { | |
| float: left; | |
| width: 180px; | |
| margin-top: 100px; | |
| padding: 20px 20px 20px 20px; | |
| background: #f4f4f4; | |
| } | |
| .nav h1 { | |
| font: normal 16px/20px 'Century Schoolbook', Georgia, serif; | |
| color: #777; | |
| } | |
| .nav li { | |
| color: #777; | |
| padding: 0; | |
| font: normal 13px/20px 'Century Schoolbook', Georgia, serif; | |
| } | |
| /* notes to myself */ | |
| p.note { | |
| display: none; | |
| /* | |
| color: #d00; | |
| font: normal 12px/20px 'Bitstream Vera Sans Mono', Monaco, Consolas, monospace; | |
| */ | |
| } | |
| /* ascii art diagrams */ | |
| pre.diagram { | |
| background: #efe; | |
| color: #080; | |
| font: normal 10px/10px 'Bitstream Vera Sans Mono', Monaco, Consolas, monospace; | |
| } | |
| /* pattern links */ | |
| a.pattern, | |
| a.gof-pattern { | |
| border-bottom: solid 1px #acf; | |
| } | |
| a.pattern:after, | |
| a.gof-pattern:after { | |
| } | |
| a.pattern:after { | |
| content: "\00A0\2192"; | |
| } | |
| a.gof-pattern:after { | |
| content: "\00A0(GoF)"; | |
| } | |
| /* feedback on content */ | |
| .feedback-btn { | |
| float: right; | |
| margin: -26px 240px 0 0; | |
| font: normal 11px Verdana, sans-serif; | |
| } | |
| .feedback-btn a { | |
| color: #d80; | |
| padding: 3px; | |
| text-decoration: underline; | |
| } | |
| .feedback-btn a:hover { | |
| background: #fec; | |
| } | |
| .feedback-box { | |
| margin: 0 0 20px 20px; | |
| padding: 5px; | |
| width: 530px; | |
| background: #fec; | |
| } | |
| .feedback-box p { | |
| font: normal 13px Verdana, sans-serif; | |
| color: #a60; | |
| padding-bottom: 5px; | |
| } | |
| /* feedback box */ | |
| .feedback { | |
| margin-right: 240px; | |
| background: #fec; | |
| padding: 19px 20px 1px 20px; | |
| margin-bottom: 20px; | |
| } | |
| .feedback p { | |
| color: #a60; | |
| } | |
| a.hide { | |
| float: right; | |
| font: normal 11px Verdana, sans-serif; | |
| color: #d80; | |
| padding: 3px; | |
| text-decoration: underline; | |
| } | |
| .feedback a { | |
| color: #630; | |
| text-decoration: underline; | |
| } | |
| /* footer */ | |
| p.footer { | |
| text-align: center; | |
| font-style: italic; | |
| margin: 20px 0 20px 0; | |
| padding: 15px 0 0 0; | |
| border-top: solid 5px #ddd; | |
| width: 560px; | |
| } | |
| /* thanks */ | |
| p.thanks { | |
| margin: 40px auto; | |
| padding: 20px; | |
| width: 400px; | |
| background: #cfc; | |
| color: #080; | |
| } | |
| /* outline */ | |
| .outline-note { | |
| margin-right: 240px; | |
| background: #fdf; | |
| padding: 19px 20px 1px 20px; | |
| margin-bottom: 20px; | |
| } | |
| .outline-note p, | |
| .outline h2, | |
| .outline h3, | |
| .outline a, | |
| a.outline { | |
| color: #a0a; | |
| } | |
| a.outline { | |
| font-style: italic; | |
| } | |
| a.outline:before { | |
| content: "(" | |
| } | |
| a.outline:after %7 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment