CSC323 2010S, Class 24: Design Patterns (2): Creational Patterns Overview: * Creational Patterns 1: Factories and Related Things * Creational Patterns 2: Builders and Singletons * Project Fun! Admin: * Lunchtime talk tomorrow. Who is coming? (about 4) * Picnic on Friday the 7th! Sign up with Weinman * EC for Weird Musical Event in gallery tonight * For Tuesday, read about the Structural Design Patterns in Wikipedia http://en.wikipedia.org/wiki/Structural_pattern * Shoot for nine hours of project work in the next week. * New groups! Common problem one: Creating things, somewhat generically * You want to create things while the program is running You don't want to specify precisely what you're creating * Why? (Examples?)a * The standard GUI issue: * We need to be able to create buttons, windows, etc. * We can switch GUIs by switching the the underlying implementation of the createButton, createWindow, etc. methods. * Drawing programs: * Add new kinds of shapes to draw "on the fly" * Translation: Use a different factory for different languages * In our project? * For the GUI * For creatures * For the world? (probably not) * Three design options for handling this problem * Abstract Factory * There is an abstract class (effectively, an interface) that specifies the createButton, createWindow, etc. methods * There are multiple subclasses (implementing class, concrete class) that gives the details of the methods * When we have a method that needs to create these components, we pass it a factory * Factory Method * Class provides its own methods for building parts * Subclasses override the methods * See the picture for more details * Prototype * Pass around "prototypical" instances of the parts we need * Use a clone method when we need more Why choose one pattern over another? Which is "best" for which kind of project? (Your answers can rely upon examples.) * Abstract Factory * Advantages * Prevents misuse, need to instantiate the interface * Ensure that the various components all go together * Disadvantages * Force someone instantiating factories to instantiate all of the methods, even if they don't all apply * E.g., what if the client doesn't need windows; should we really require the factory to make windows? * Factory Method * Advantages * Inheritance is pretty (and beauty is truth) * Prevents misuse, need to instantiate the interface * Disadvantages * May create a painful hierarchy, may even cause trouble with desiring multiple inheritance * Prototype * Advantages * Cloning may be cheaper, particularly if there's computation or I/O involved in the creation of the object * Can provide multiple versions of the same kind of "object" - more options for customization * Less need to subclass (?) * Well, a button will be in something lke the MacButton class, which is a subclass of the Button class * But none of the other subclassing * Disadvantages * A careless programmer may not choose the right combination (e.g., a Mac window and a Windows button) * Other ways of approaching the problem A question: Suppose you want to distribute on .jar for use on multiple platforms, which would you use? * The main method would differ depending on the group * Abstract Factory if (osX()) runTheGame(new MacGUIFactory()) else if (windoze()) runTheGame(new WindowsGUIFactory()) else if (ifone()) runTheGame(new IPhoneGUIFactory()) else runTheGame(new TextGUIFactor()) * Factory method if (osX()) new MacGame().go() else if (windows()) new WindowsGame().go() ... * A big win of all three: The client programs to an interface Suppose we want to add another GUI component. Which of these is easiest to extend? * Prototype: Only have to build one prototype; The other two require us to not only change the superclass, but also *all* of the subclasses * Suppose we want to add another GUI. Which is easiest? * AbstractFactory, because we just make a new subclass * Factory Method, because we just make a new subclass Builders Singleton New Teams! * Networks: Dylan and Nathan and Nora and Jeff * World/Model: Ravi and Alex and Dennis and Josh * GUI: Jordan and Aaron and Terrian and Jesse World/Model * Added support for listeners (thanks Ravi) * Attempted to add support for reading species from files * Using really ugly regular expressions (Scheme should be easy to parse) * Need to make it work! * The basic model works * Demonstrated using the unit tests ../Examples/designers/model/ConflictResolutionPolicy.py Handles what happens when multiple things try to go into the same space ../Examples/designers/model/Direction.py Simulated enumerated type North, South, East, West, Etc. ../Examples/designers/model/__init__.py Puts everything into a package. (Hard to understand.) ../Examples/designers/model/Instruction.py Processed rules return a list of instructions, which tells the model what to do next, passed to listeners ../Examples/designers/model/LocalWorld.py Obvious ../Examples/designers/model/Predicate.py All the predicates: And, Or, Not, directional, etc. ../Examples/designers/model/Rule.py Binds a predicate to an instruction or instructions ../Examples/designers/model/SpeciesDatabase.py A singleton database of species Provides the non-working parse file method ../Examples/designers/model/Species.py Obvious ../Examples/designers/model/Test2.py Old test. Run with from Test2 import *. Do not run with python3 Test2.py ../Examples/designers/model/Test3.py Old test - Draw boards and see them moving See above ../Examples/designers/model/Test4.py Old test - Draw boards and see them moving See above ../Examples/designers/model/Testand.py ../Examples/designers/model/Testing.py ../Examples/designers/model/TestOR.py ../Examples/designers/model/UnitTests.py * Think about distributing these * High-priority tasks * Reading species Sample species S(Kind1:000000) R{P(OR (QUANTITY Kind1 000000 3) (QUANTITY Kind1 000000 2)) I(D:NE s(Kind1:000000) C(2,2))} * No. * Design question: Who chooses the colors? The GUI, the player, ... * Do we need the colors all over the place? * Compromise solution: There's a color in the file, but it's advisory * Fails the S expression test ((S Kind1 0000000) (R ...)) GUI * Can create the main menu * Some problems with consistency * Threw away lots of stuff and started again * Cannot draw a board yet. HIGH PRIORITY * Needs to implement listener interface soon * The danger of new programmers: "I couldn't understand your code, so I threw it away." * The danger of old programmers: "We started with nice modules, but it worked best if we just kind of threw everything together." BoardScreen.py * Supposed to hold the grid, but doesn't BoardSetup.py * Setup GUI - Input all the values ButtonCreator.py * An easy way to create buttons Menu.py * The main menu, separated out for nice modularity Test.py * Test methods, provides three different tests menuTest - test the main menu setupTest - test the setup window screenTest - tests the thing that holds all of the things displayed * These are not unit tests Network Group * Client and server * Client implements world interface * Server implements world listener interface * Server can listen to a local world * They can throw pickles back and forth * Need to figure out how to pickle enums * pickle is a verb and a noun for "serialize object" or "serialized object" * client and server select on port so that they can read or write * Priorities! * Test * Integrate with the world * Make the setup thing work * Figure out what we're doing