CSC323 2010S, Class 23: Design Patterns (1): Philosophy and Some Basic Patterns Overview: * Aggregation, Again. * Multiple perspectives on software reuse. * The Design Patterns philosophy. * Some Patterns from Scheme. * An example: Sorting. * The Patterns Format(s). * The Design Patterns catalog, abbreviated. * Project Stuff. Admin: * Reading for Thursday: Creational Patterns at http://c2.com/cgi/wiki?CategoryCreationalPatterns * Don't forget Pub Night tonight. * EC for Thursday's convocation. * EC for Friday's lunchtime talk. Aggregation, Again * What is it with the aggregation thing and how does it differ from composition, association, aquaintanceship, ...? * All of these are forms of * Object O includes object U * Aggregation: Restrict knowledge of object U to just object O * O and U have identical lifetimes * Everything else: Object U can be shared * Why would we care to make this distinction? * The authors tell us it helps link run-time to compile-time * Sam told us a week ago can help with memory layout typedef struct U { int i; int j; } U; typedef struct O1 { int x; U *u; } O1; typedef struct O2 { int x; U u; } O2; * Why O2 rather than O1? * Locality: Keeps related things together in memory * Fewer mallocs required * Uses less total memory - don't need to store the pointer * Freeing is cheaper/easier * Why O1 rather than O2? * Changes to the U field propagate differently o1->u.i = 1 o1->u = v * Sometimes sharing is good * Upon further reflection I realized ... * By reading the Web page for today's class, ... * Why aggregate, revisited? * Trees rather than graphs when you're building composite data structures * Might fit analogies better * Can help with analysis f.x.set(1) ... print f.x.get() Multiple perspectives on software reuse * Build pieces that can be easily reused in other contexts * How? What techniques do you know for building reusable software? * Polymorphism * The same code works with multiple objects * Inheritance * Reuse the code of the parent * Encapsulation * Makes it easier to understand what does what * If you don't muck with the code, you can assume it works and will continue to work; if you can't muck with it, no one else will, either * Simpler: You only need to understand the *what* and not the *how* * One Class, One Purpose * You don't have lots of extraneous functionality that you don't need, so you're more likely to use the thing * Generalize * E.g., HOPs * Refactor without mercy The Design Patterns Philosophy * We can reuse designs, too * OOP is a particularly good domain for reusing design * Higher-order procedures can be, too * Design Patterns is a Philosophy in that it's self-referential Some Patterns from Scheme * (map function list) * Apply the function to each element of the list * When you need to apply a function to each element of a list, you write (lambda (lst) (if (null? lst) null (cons (function (car lst)) (recurse (cdr lst))))) An Example: Sorting * Object-oriented world, we want to write a general Sort method. How? * We need a way to compare objects - * How does Java do it? * Require that the objects provide a compareTo method (Comparable) * How do we like to do this in Scheme? * (sort lst comparator) - Java has a Comparator class for the same purpose * Can we solve this using inheritance? * We could inherit an abstract sorting method and override the compare method public abstract class Sort { public int compare(Object o, Object p); public int sort(List lst) { ... compare(lst[i], lst[i+1]) } } public class StringSort extends Sort { public int compare(Object o, Object p) { return String.compare(o,p); } } * Three approaches to: Everything in this method is fixed except what I do for *this step* * Goal of design patterns: Make the implicit explicit * Helps us remember * Lets us share * Lets us discuss * The GoF got this idea by reading Christopher Alexander The Patterns Format(s) * Name (to let us discuss) * Problem (what the pattern addresses) * Stories * Solution * Implications What are the implications to the three solutions to the "I need to compare objects when sorting" problem. Abstracted: I need an operation to vary * The Schemey strategy: Provide the operation as a parameter * Can be used in languages that are not object-oriented, like C * Can use the operation in many contexts * Can lead to a proliferation of objects (comparators/operations) * Java Generics: require the objects to provide the operation * Makes it easier to optimize operations for particular objects * useful if you only want one form of operation for one kind of object * Tends to limit us to a one-to-one mapping between object and operation * May require us to add functionality to objects that isn't obviously part of the object * Inheritance: subclasses override the operation * Can lead to a proliferation of classes Project Stuff: Communication * Groups need to talk to each other * CS students are bad at F2F * CS students don't like to write things down * We can coordinate on a Wiki, because CS students like to Wik * http://opprobrio.us/wiki * Communicate * Info about your interfaces - what operations you plan to provide * Wish lists / Demands - what you need other groups to do * Short history of component / background for others * Doesn't this belong in the SVN repository? * Broader documentation - how parts fit together Project Stuff: Network Play CRC (or whatever the TLA is) * SpeciesDatabase provides * get() Two stories: * Starting a game (setting up the server) * Joining a game (connecting to the server) NetworkGameStarter * s = speciesdatabase.get() * s.loadFile(___) * prompt = new SetupGUI() * speciesdatabase.get().allSpeciesNames() * (width,height,speciesName,serverP) = prompt.runSetup() * if serverP * another_prompt = new MoreGUI() * lotsofjunk = another_prompt.run() * w = new LocalWorld(width, height, s.getSpecies(speciesName)) * s = new ServerWorld(w, lotsofjunk) Story: The central world changes * notifyListeners() * nwserver.update() * Send a message across the network * nwworld.update() * nwworld.notifyListeners() * GUI.update() * nwworld.get(i,j) * Change lists * Now you need to define them * Easy to send change lists with Pickle * Question: Should we send a list of updates, rather than a note that we've updated? * Makes some things easier * But it means that observers/listeners might get some extra data that they don't care about Side note: GUIs might be generalized (or not) * Create SetupGUI * Create GUI