CSC323 2010S, Class 19: Architecture Overview: * Admin [1:15-1:20] * About the Class * Sam's lecture [1:20-1:35] * Your questions [1:35-1:50] * Architecture Summary [1:50-2:10] * Break [2:10-2:15] * What should we do first? [2:15-2:25] * Python Style and Beyond [2:25-2:40] * Architecting Our Game of Life [2:40-3:05] Admin: * Cookies! * Don't forget that you should have completed at least six hours of documented work this week before Thursday's class. * Reading for Thursday: HFOOAD, Chapter 8. About the Class: Sam Perspectives * Software Design is INTENTIONALLY different than other CS courses * What are some criteria I can use to analyze code * What are some processes I can use to build big projects * Sam's goal: You exit this class with the ability to * Draw upon a variety of strategies * Think about different strategies you can use * Reflect on your own preferences Grading: * There's a reason that readings are 20% * Assigned hours of work: at least a B * Some assessment of weekly or biweekly milestones Final: * Here's some code. Critique it. * Here's a part of the project. Explain it. * Here's a problem, design a solution. * Here's some code, document it with UML. It's too late to fix now, but ... * More detailed labs (and more labs) would have been good * More design would have been good * Implementing things with the level of detail we have is hard * What else should the UML diagram have had (or what other documentation would have been good)? * A scenario or use case that describes some steps * Just more time designing or discussing * E.g., the conflict resolution policy * Conclusion: We need to go through the UML diagram and some missing parts on Thursday (first activity for next class) * The Web site sucks (not too late to fix now) * Didn't know that the current outline gives the current reading Big Projects and Architecture Summary (Goal: Finish by 2:10) * [Lesson: It's good to summarize what you've read for yourself, particularly since you know that I'm going to ask.] * Use Case Diagrams provide a helpful high-level overview of a project * Gives you a sense of the big components of the project * Gives you a sense of the main "actors" in the project * Provides a framework for thinking about features * A way to communicate with your client * OOAD requires that you turn features into use cases and requirements and beyond * Lots of "think about it" and then represent in a form in which it can be discussed (we hope) with others * To solve a big problem, you break it into smaller pieces * In my experience, while small pieces are helpful, choosing and joining them is hard * Do the risky stuff first * It's done, and not so worrisome, or you failed, and you can then try a different approach * If you don't understand how something works now, when you finally understand it, you may have architected the rest in an incompatible way * If you just try it a bit, you can put it aside and think about it in the back of your head * Might help you with estimates of the other stuff, or at least help you think about your deadlines * The three keys of architecture: Figure out the "essence", Figure out the meaning of each component, Figure out how to approach the problem (a big point of chapter 7) * Commonality and variability * Discussed before, but reemphasized * A focus on thinking about this carefully in advance (Contrast with XP view of getting something there and then generalizing) * Scenarios are useful to help gather requirements quickly * They seem to be a bit less detailed than use cases * Broader moral reinforced: We can think about issues through stories * Including what procedures to provide * Terminology: Domain analysis * Identify and organize information * MVC and other design patterns * "Avoid writing code as long as possible" XP^-1 * Reinforcement: First: meet the customer's needs, Then use OO principles, Finally generalize We learn more of this with specific code (and we either need more code or less code). What should one do first - simple or risky or ...? [2:15-2:25] * We've just seen reasons to do risky stuff first? * Why should we do the simple stuff first? (In particular, why in GrinLife or whatever are we doing the simple stuff first?) * Sometimes it's the "essence" of the system * XP philosophy: It's best to have something working quickly that you can talk about * Easier to test if you build the other stuff first. (Or maybe not: We could certainly design and implement the network protocol w/o anything else working.) * It gets you started on the project. (Helps you understand flaws in your design.) * If the odds are that you're not going to finish everything, think about what's most important to finish. * What else is risky? * The GUI - We have no concept of how to do it * But people won't play it without it ... so it's part of the "essence" * Using Python * We took this risk already * And it's a reason to start with simple stuff ... you'll learn Python better by doing the simple stuff first Python Style and Beyond [2:25-2:40] * "Real Python programmers don't use setters and getters. Why are we?" * "accessors and mutators" Consider class Point(): def __init__(self, x, y): self.x = x self.y = y Why is it potentially "bad" that the client can access the x and y fields? * We might want to have bounds checks when the fields get assigned. * We might want to have type checks when the fields get assigned. * We might want to change the name of the fields. * While search-and-replace makes it easy, you don't necessarily have access to the client code * We want to hide aspects of the implementation (e.g., we might want to represent points as radius + theta, rather than x and y) * We might want to keep internal state consistent * We might want to have read-only objects * Note that even when you use fields, you have an implicit set and get. self.x = 23 is an implict set lineto(self.x, self.y) is an implicit get * In Python, you can override the implicit setters and getters * In this case, we call x a "property" of a class Another issue x = 0 while (x < 10): dosomethingwith(x) x = x + 1 vs. for x in range(0,10): dosomethingwith(x) Architecting Our Game of Life [2:40-3:05] * Things to talk about * New predicate system (now with buzzwords!), Rules, Actions, etc. * Conflict Resolution * We need a consensus on Species vs. States vs. Creatures * GUI stuff (but this can be the last thing we talk about) * Instructions class Tell me a story. * The player places a piece on the board * One "generation", in the project designer's view * The LocalWorld iterates over all the Creatures in the board (dead and alive creatures, if necessary) * For each Creature, c, it calls i = c.species.next(c.state, neighbors) * next returns what the creature does in the next turn * neighbors could be implemented as location + board * The next procedure iterates through the rules associated with the species until a predicate matches. It then returns the corresponding set of instructions. * I'm too lazy to describe predicate matching. * It then follows the instructions to place all the creatures on new cells. * If two or more creatures end up in the same cell, it calls victor(Creature, ...) to determine which one survives. * It places the "Dead" (blank slate) creature in any remaining positions * One "generation/cycle" passes on the board The board iterates over each Cell * It calls the getChange method on the cell, passing the coordinates of the cell and the board * Cell contains either * Dead/Nothing *