Python Design Patterns 1

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
thank you going like two inches great oh I thought you meant like the level of excitement was just that - that much - hi Brandon tone it down this much so normally what I see on my screen is this an 800 by 600 slide the lower resolution forces me to write them so that they're visible to the audience and then I display that through the screen but secretly down beneath I have a little calculator that tells me given the number of in its left how many seconds I have to finish each slide if I make these big like this then I won't finish on time so that's a just for fun Carl will hate me what happens if I actually go into 800 by 600 mode are you able and see if the AH it doesn't like it and so we are going to do something all right let me try again before let's say a minute ago when I tried this the problem is it fixed it for a second but then the screen was frozen and wasn't following the slides as I changed them here yeah I don't I think it wants in this case and this is the first projector I've encountered this problem with it really really wants 1028 so now and then you're probably going to so I think what I'll do is I'm going to actually what will it really distract you guys to see that number at the bottom or can you mostly can you be the slide at this smaller size I'm not taking up as much of the area as usual all right thank you guys because that's going to let me actually know when to end the talk all right let's start hey my name is Brandon Rhodes I am a frequent speaker at PI Khan's and I did PI Ohio last year because I knew I was moving up to the state later in the year and I did that in December and this year my talk is on Python patterns and I gave it the number one because this is a huge subject this is my first try and when I realize how much I've gotten wrong with this first try I might someday have a Python patterns two or three talk that tackles things it tackles even more of the subject area but you might not have heard of the concept of patterns before depending on what area of the Python community you're in what you're doing with the language and why is that there are programming communities Java comes to mind immediately where people talk about design patterns all the time there was a 2009 talk at PyCon which kind of spurred me to write this talk in which it was suggested that well some patterns are built in to Pyke Python that's true he didn't like that concurrent patterns he felt were poorly supported in Python and he thought that maybe that pointed us at new features that could be added to the language but he besides saying that yeah a lot of patterns are built in so we don't even talk about them he didn't really address why all the patterns that aren't built-in and we're about to go through several of them so you can see some examples why we don't constantly teach those to each other and then use them in our programs I felt it was this big kind of missing question hovering over his talk so the gist of this talk is to tackle why do we rarely talk about them and I'm going to suggest three answers one some of them have become built-in language features so we use them automatically I'm going to argue that some of them are provided by the frameworks we use and so there are two problems that we don't have to tackle but then I'm going to suggest a third reason I think that Python programmers show just don't tackle writing the kind of applications that were in the minds of the people who came up in the 90s with the idea of design patterns so we'll get to that at the end what is a pattern this whole idea came from two books one which is by an architect in 1977 who noted that a lot of problems that that especially he thought Modern architects run into with creating these big concrete museums that like it's impossible to get in and out of without running into people or solvable by solutions that applied at many layers of scale he thought that the problem of getting people to move in and out of a room imagine a room in a gallery that people walk through that preventing people from running into each other might then also teach you how to set up a gas station and I also teach you how to set up a city so that traffic doesn't intersect and have to wait on each other he thought that a pattern or or he defined for his usage a pattern as a kind of trick that you learn that gets a difficult problem any layer of detail and gives it suggests a way to try solving it in your context after he had created this kind of patterns revolution and wrote a whole book about designing houses cities anything you want using some architectural patterns for now very famous people wrote a book for doing the same thing in software they said well you know in software there's these tricks we've learned where if I write it this way it's not going to work but if I turn the problem around my program will will be much easier to maintain and so these four people who became known as the Gang of Four which is an old term from the the time of the Communist revolution in China but was such a great term they applied it to the four authors either because they just didn't want to say I am a big fan of the book by gamma Helen Johnson or it could be they didn't want to pronounce blue CDs I don't know which but they call these people the Gang of Four and this is specifically and these are the patterns I'm going to go through briefly to give you a flavor of their character not all patterns are object-oriented design patterns but these are for instance patterns in Python exist at many different levels here for example is a little-bitty pattern which we often teach new python programmers if you're trying to look for a key in a dictionary that might not be there the first thing you try is testing if it's in the dictionary and if it is grabbing it and if it's not using some default value you're assuming that the administrator owns things that no one else does but we knock this off one point for looking up owner twice which can be expensive depending on the kind of container though not that expensive for a dictionary and it's four lines and no one wants four lines in their program so dictionaries support a get method that takes a second default argument to look up if the key isn't present that's a tiny little pattern a slightly bigger one it would in Python it at the Python Atlanta group I found a lot of people didn't know what continue is for they'd read the Python tutorial or the real anguish reference and they knew that a for loop has this word continue that says just skip doing anything else with this item let's go back to the top of the loop and start with the next one but they couldn't imagine why you would need that and it's typically used and so here's a pattern in a situation where you have to pass a number of tests and checks before you know that you want to operate on the current item and the naive way of doing this leads you into if statements that grow deeper and deeper and I have seen people's code in Python where on my 80 character display the line used up all 80 characters with just spaces and we wrap to the second line before even any content because they had made so many checks on the way down and so one possible pattern that helps make some code clearer not all is to test the opposite of each of your tests rather than asking do I want to operate on this item ask can I skip this item and so you get things like well if this item isn't for sale just continue and we'll try the next one if the cost is more than the money I have just continue with the next one and then the actual point of your loop the purpose the operation that you're trying to do to each item winds up indented a single level of four spaces it's another example of not an object-oriented pattern but a little simpler pattern so not all patterns Roo patterns but the ones we're going to look at today and that we're talked about an earlier PyCon talk are object-oriented design patterns are about putting the big pieces of your application together classes objects and how instances do or don't hold references to the other parts of the application that you've built up in memory how then can a language feature I told you that that guy is talk at PyCon said well we just don't use a lot of design patterns because Python has language features that get rid of them well how can that work how do you just get out of having to follow a good idea because your language is awesome here's an example the very first principle in this book is and this won't make sense unless you've used bad languages in the past but or dunzo which is similar program they advise you to an interface not an implementation these are special words for a phenomena that happens a lot in things like C++ or Java where you you have to when you define a function you have to tell it what kind of object you're expecting you can't just write functions that take any kind of argument and as you see here we have locked this method into always taking a file that it writes to nothing else a file but nothing else and what they're suggesting we do instead is instead write an interface that says well this describes a kind of object with a dot write and write your functions so it takes that not saying has to be a file but it can be anything that has a dot write method if you do this then when the day comes that you want the function to write to a socket or to post the the solution or in an email or to produce the output somewhere else you can just make your new class that writes to a web socket or whatever I writable so it provides a dot write method so that your same rights in function can operate with this new object so do we worry about this in Python and the answer is no so here we're going to see how a language feature gets rid of a big big principle of our design patterns we don't even have to think about that rule because our language simply doesn't require us to use static typing it throws it overboard you don't make any prediction or warning to Python what the type of out is going to be what class it's going to be instead we use duck typing we just accept parameters and we try them out we try calling dot right maybe we'll get a runtime exception but it means that a function can accept anything a language feature Python is a dynamic language and doesn't make you pre specify the types accepted by a function eliminates an entire Gang of Four design principle in other words all Python code you've ever written automatically adheres to the Gang of Four principle that functions shouldn't name the classes that can and can't be passed in you can do it manually and cause trouble for yourself later if you do a bunch of isinstance tests up at the top of your function and people do that sometimes but the language doesn't make you do it it's interesting so in general Java and C++ programmers maintain growing and expensive coding disciplines outlined in books like this to remove a set of handcuffs that in Python simply don't exist to begin with I think it's kind of a damning indictment of C++ and Java that their most fundamental and persistent coding practices all seem designed to make Python more Java more like writing in Python so we've seen how a gang of four principal just like that guy at PyCon claimed disappears in Python what about the patterns themselves do they all really just disappear I'm going to claim that they don't and so let's quickly go through them there's a five creational patterns seven structural patterns and eleven behavioral patterns we'll look at the first few in a little bit of detail and then I'll start just having like one slide per pattern to give you a taste of what the last set of patterns looks like so that this isn't a several our talk the five creational patterns we should especially look at in detail because they are the ones that often kind of disappear in Python now Python is brilliant you might not have realized that it's this much fun to program in your favorite language but Python does not have a separate syntax for object instantiation in C++ Java or interestingly enough JavaScript calling a function as in the top line of code there looks different than creating an object which happens with a special keyword called new if you choose you know to instantiate things right in your code in Python you cannot tell by you know assuming assuming that I can I can choose to capitalize a class name or not you can't tell whether that Python oh I put a semicolon here take it going on like two inches greater oh I thought you meant like the level of excitement yeah was just that - that much - hi Brandon tone it down this much so normally what I see on my screen is this an 800 by 600 slide the lower resolution forces me to write them so that they're visible to the audience and then I display that through the screen but secretly down beneath I have a little calculator that tells me given the number of minutes left how many seconds I have to finish each slide if I make these big like this then I won't finish on time so that's a just for fun Carl will hate me what happens if I actually go into 800 by 600 mode are you able to see if the AH it doesn't like it and so we are going to do something all right let me try again Oh before let's say a minute ago when I tried this the problem is it fixed it for a second but then the screen was frozen and wasn't following the slides as I changed them here yeah I don't I think it wants in this case and this is the first projector I've encountered this problem with it really really wants 1028 so now and then you're probably going to so I think what I'll do is I'm going to actually what really distract you guys to see that number at the bottom or can you mostly can you read the slide at this smaller size I'm not taking up as much of the area as usual all right thank you guys because that's going to let me actually know when to end the talk all right let's start hey my name is Brandon Rhoads I am a frequent speaker at Pyke and I did PI Ohio last year because I knew I was moving up to the state later in the year and I did that in December and this year my talk is on Python patterns and I gave it the number one because this is a huge subject this is my first try and when I realize how much I've gotten wrong with this first try I might someday have a Python patterns two or three talk that tackles things it tackles even more of the subject area but you might not have heard of the concept of patterns before depending on what area of the Python community here in what you're doing with the language and why is that there are programming communities Java comes to mind immediately where people talk about design patterns all of the time there was a 2009 talk at PyCon which kind of spurred me to write this talk in which it was suggested that well some patterns are built into Python that's true he didn't like that concurrent patterns he felt were poorly supported in Python and he thought that maybe that pointed us at new features that could be added to the language but he but besides saying that yeah a lot of patterns are built in so we don't even talk about them he didn't really address why all the patterns that aren't built in and we're about to go through several of them so you can see some examples why we don't constantly teach those to each other and then use them in our programs I felt it was this big kind of missing question hovering over his talk so the gist of this talk is to tackle why do we rarely talk about them and I'm going to suggest three answers one some of them have become built-in language features so we use them automatically I'm going to argue that some of them are provided by the frameworks we use and so they're two problems that we don't have to tackle but then I'm going to suggest a third reason I think that Python programmers show just don't tackle writing the kind of applications that were in the minds of the people who came up in the 90s with the idea of design patterns so we'll get to that at the end what is a pattern this whole idea came from two books one which is by an architect in 1977 who noted that a lot of problems that that especially he thought Modern architects run into with creating these big concrete museums that like it's impossible to get in and out of without running into people or solvable by solutions that applied at many layers of scale he thought that the problem of getting people to move in and out of a room imagine a room in a gallery that people walk through that preventing people from running into each other might then also teach you how to set up a gas station and I also teach you how to set up a city so that traffic doesn't intersect and have to wait on each other he thought that a pattern or or he defined for his usage a pattern as a kind of trick that you learn that gets a difficult problem any layer of detail and gives it suggests a way to try solving it in your context after he had created this kind of patterns revolution and wrote a whole book about designing houses cities anything you want using some architectural patterns for now very famous people wrote a book for doing the same thing in software they said well you know in software there's these tricks we've learned where if I write it this way it's not going to work but if I turn the problem around my program will will be much easier to maintain and so these four people who became known as the Gang of Four which is an old term from the the time of the Communist revolution in China but was such a great term they applied it to the four authors either because they just didn't want to say I am a big fan of the book by gamma helm Johnson or it could be they didn't want to pronounce blue CDs I don't know which but they call these people the Gang of Four and this is specifically and these are the patterns I'm going to go through briefly to give you a flavor of their character not all patterns are object-oriented design patterns but these are for instance patterns in Python exist at many different levels here for example is a little bitty pattern which we often teach new Python programmers if you're trying to look for a key in a dictionary that might not be there the first thing you try is testing if it's in the dictionary and if it is grabbing it and if it's not using some default value you're assuming that the administrator owns things that no one else does but we knock this off one point for looking up owner twice which can be expensive depending on the kind of container though not that expensive for a dictionary and it's four lines and no one wants four lines in their program so dictionaries support a get method that takes a second default argument to look up if the key isn't present that's a tiny little pattern a slightly bigger one it would in Python it at the Python Atlanta group I found a lot of people didn't know what continue is for they'd read the Python tutorial or the real anguish reference and they knew that a for loop has this word continue that says just skip doing anything else with this item let's go back to the top of the loop and start with the next one but they couldn't imagine why you would need that and it's typically used and so here's a pattern in a situation where you have to pass a number of tests and checks before you know that you want to operate on the current item and the naive way of doing this leads you into if statements that grow deeper and deeper and I have seen people's code in Python where on my 80 character display the line used up all 80 characters with chest spaces and rap to the second line before even reaching any content because they had made so many checks on the way down and so one possible pattern that helps make some code clearer not all is to test the opposite of each of your tests rather than asking do I want to operate on this item ask can I skip this item and so you get things like well if this item isn't for sale just continue and we'll try the next one if the cost is more than the money I have just continue with the next one and then the actual point of your loop the purpose the operation that you're trying to do to each item winds up indented a single level of four spaces it's another example of not an object-oriented pattern but a little simpler pattern so not all patterns Roo patterns but the ones we're going to look at today and that we're talked about an earlier PyCon talk are object-oriented design patterns are about putting the big pieces of your application together classes objects and how instances do or don't hold references to the other parts of the application that you've built up in memory how then can a language feature I told you that that guys talk at PyCon said well we just don't use a lot of design patterns because python has language features that get rid of them well how can that work how do you just get out of having to follow a good idea because your language is awesome here's an example the very first principle in this book is and this won't make sense unless you've used bad languages in the past but or dunzo which is similar program they advise you to an interface not an implementation these are special words for a phenomena that happens a lot in things like C++ or Java where you you have to when you define a function you have to tell it what kind of object you're expecting you can't just write functions that take any kind of argument and as you see here we have locked this method into always taking a file that it writes to nothing else a file but nothing else and what they're suggesting we do instead is instead write an interface that says well this describes any kind of object with a dot write and write your function so it takes that not saying has to be a file but that it can be anything that has a dot write method if you do this then when the day comes that you want the function to write to a socket or to post the the solution or in an email or to produce the output somewhere else you can just make your new class that writes to a web socket or whatever I writable so it provides a dot write method so that your same rights in function can operate with this new object so do we worry about this in Python and the answer is no so here we're going to see how a language feature gets rid of a big big principle of our design patterns we don't even have to think about that rule because our language simply doesn't require us to use static typing it throws it overboard you don't make any prediction or warning to Python about what the type of out is going to be what class it's going to be instead we use duck typing we just accept parameters and we try them out we try calling dot write and maybe we'll get a runtime exception but means that a function can accept anything a language feature Python is a dynamic language and doesn't make you pre specify the types accepted by a function eliminates an entire Gang of Four design principle in other words all Python code you've ever written automatically adheres to the Gang of Four principle that functions shouldn't name the classes that can and can't be passed in you can do it manually and cause trouble for yourself later if you do a bunch of isinstance tests up at the top of your function and people do that sometimes but the language doesn't make you do it it's interesting so in general Java and C++ programmers maintain grueling and expensive coding disciplines outlined in books like this to remove a set of handcuffs that in Python simply don't exist to begin with I think it's kind of a damning indictment of C++ and Java that their most fundamental and persistent coding practices all seem designed to make Python more Java more like writing in Python so we've seen how a gang of four principal just like that guy at PyCon claimed disappears in Python but what about the patterns themselves do they all really just disappear I'm going to claim that they don't and so let's quickly go through them there's a five creational patterns seven structural patterns and eleven behavioral patterns we'll look at the first few in a little bit of detail and then I'll start just having like one slide per pattern to give you a taste of what the last set of patterns looks like so that this isn't a several our talk five creational patterns we should especially look at in detail because they are the ones that often kind of disappear in Python now python is brilliant you might not have realized that it's this much fun to program in your favorite language but python does not have a separate syntax for object instantiation in C++ Java or interestingly enough JavaScript calling a function as in the top line of code there looks different than creating an object which happens with a special keyword called new if you choose you know to instantiate things right in your code in Python you cannot tell by you know assuming assuming that I can I can choose to capitalize a class name or not you can't tell whether that Python oh I put a semicolon I hear fix what fix the comment to ash / this is why we go through now this is 1.1 know the dangers of cutting and pasting between programming languages the gum so the in Python you cannot tell from that call whether that is a class or and and by calling it I'm creating an instance or whether it's a function that's making up its own mind about whether to return me a new instance in other languages the new keyword commits you to doing a real instantiation so it could be as you make the call the library author who wrote that class can't just decide to return another class to you instead cannot decide in general just to always return the same instance because the new keyword walks in is part of the syntax that you're going to get a new instance of that particular class in Python we can do just crazy stuff like this we can write a function that just does some tests make some decisions and can just return any kind of class it wants to simply by being a function so most creational patterns these first few the patterns in the first section of the book are indeed contortions to avoid making brittle new calls in your C++ or Java and so there's one called the factory method and a whole other one called an abstract Factory that let you write functions or somehow make the decision at one time about what class gets returned there's another pattern the singleton that always returns in the same instance and a lot of these either disappear or going back to the previous slide just a trivial in in Python because we don't operate under those syntactic constraints in Python you can't tell what's being called here it can be a bound method again a class with a lowercase name a plain old function it can be whatever the author needed and as long as you don't is instance it to and then discover that whole thing is just a function it's not actually the class that this is an instance of you won't know that it happened I should so we're going to kind of wave away the patterns that were used to create classes where the decisions made at runtime but I should talk about Singleton's for a second Singleton's are kind of an alternative to a global variable a global variable is one of the annoying things about them is that you can never later switch up to doing something more dynamic if you've encouraged the people using your code to call like you know my module dot foo this isn't true in a class instance if I give you a class instance and are letting you poke at the dot foo attribute and then later I discover I need to do something more complicated I can make it a property that that that gets to run some code when you try to read the value and run some code when you try to set it you'll never know the difference that is not possible today at least with Python modules modular dot foo just looks up and returns that value without any chance for the module author to get fancier later and you know create the object on the fly or something like that so the most basic Python singleton pattern is to put a function in your module that everybody calls to get the global rather than weather them just dumping the raw value there and letting people get it without your ever having the chance to intervene because now if you need to get fancier later you can just do more inside of the get singleton class then return the the private globe it so note by the way the real singleton pattern people often show this a little bit of code or something similar and say yeh Singleton's in Python that isn't quite because the real singleton pattern in the book provides one other feature which is to let the collar the first time they call specify a different class to get instantiated and now held forever in the place of that singleton rather than just always having it be my class and then the idea here is that if the singleton is your connection to the database or something like that you might need to provide a subclass that does checking permissions checking or something like that on database calls depending on your environment and so the actual way to implement a gang a for singleton in Python would look something more like this where before you create it the first time you give the caller the opportunity to say you know don't use my class use some alternative that I've constructed over here and then you can make things even more complicated if you start looking online at Python singleton patterns but you'll note here I'm still having you call a plain function because I find that the easiest simplest way to do things there are people that warrant a constructor that is also the singletons class where you're not calling a function that gives you a new instance where your calling my class perv in and some parameters and getting back only a single object instance wherever you try to instantiate a my class in your code that wasn't possible in Python until in the 2000s they invented the under the dunder new method I'm not going to have any of those code examples because that's an unusual case if you go to stack overflow you will find more examples than you want because you probably want one and you're going to get three of how to add a new method to a class so that it just keeps returning a single instance to everyone who ever tries to instantiate it instead of returning multiple instances so the singleton pattern actually does get a little interesting you have to know Python pretty well to implement it reliably get very low-level pattern and in some cases they find it very important to the way that you set up an application finally there is a two more creational patterns that now go beyond creating a single object from scratch a prototype is their name for when you have an object that you can just ask it to spin off new copies of itself this is great if you've loaded something from a file and instead of rereading the file every single time you need to do one of these objects imagine an image that someone's using a hundred times in a drawing program you just want to copy the one you've already read in that's the prototype pattern and we actually have in most cases we can just solve it using the copy module in the standard library that because python code can introspect objects it just looks at how your objects built and makes one just like it so this is a pattern that disappears into our standard library not so much into the language of syntax but yeah this is a design pattern that we don't often write ourselves because the languages and the library is powerful enough the final creational pattern is the Builder it's complicated and doesn't go away in Python it was very useful you've probably used one on many occasions it's an object that you add to which you feed instructions about what to build and it hides the details of the big collection of objects that it's putting together on your behalf if you've ever used element tree and builds a little XML document to output the naive way of doing that is to just well create an element called the body and then create an element called heading one and give it some text and a paragraph give it some text and then it pinned those to the the root to the body and here your code is full of all kinds of explicit grungy details about how each REE represents XML with element objects that are connected together but the L XML class moves our package also provides its own builder that is a perfect example of the Builder design pattern notice that this code that creates exactly the same XML document has no knowledge in the code about what classes are going to come out there's no classes named here nor does it tell you what they're going to look like what their attributes are going to be or how those instances are going to be hooked up instead you're simply specifying a recipe for what you want and you're letting the bigger create the network of objects notice this is our this is going to start happening with the future examples but this is a first example of a design pattern that doesn't go away in Python that's still an awesome idea that lets you write really code whose consequence in this case is a bunch of object instantiation x' that don't have to appear explicitly in your code anymore the so but it this does tend to be a kind of framework ething to do very often it's if you're writing a complicated library that you maybe provide a builder that can put together all of your object instances in the right order it might not be something you often write in your own code so just looking at the creational patterns the guy the previous presentation I saw a Python obviously has a point several of these guys disappear or become kind of trivial only one of the patterns the Builder still retains its role as a big heavyweight good idea yes thank you get all of these class names out of my code and let me just issue orders to build things and let the framework worry about how it represents them but now let's see if the same thing happens with the middle section of this book which has what they call seven structural patterns the first one is called the adapter this one I'm going to argue is very important even in Python the idea is you write a class in a wrapper so that it behaves like another class there's actually a good example in the standard library sockets do not have a dot read method if you create a socket I did this if you create a socket and try to just access its dot read method you get an exception because sockets do not read and write they do something that has different semantics can encounter different errors they have something called send and something called receive so you can't treat them like files so the standard library provides a socket file object adapter and it's an object as its sole attribute heads on to a socket that you give it and it offers a read method and write method and an opening area close method all of which turn around and do the equivalent operation to the socket using send and receive and so if I call the constructor for that in the standard library if I get my socket and say makefile I get back a fake file that's not really connected to the filesystem it instead is connected to the socket and can translate things like dot read into things like dot send so this is a crucial pattern for reusing code because so often a routine you or a friend or a library author has written is perfect if only it would write to your web socket instead of to disk how could you get it to write to the web socket and very very often the way to reuse code so you don't have to go back in and change it is to write an adapter that makes the class you need to pass in pretend like and support the features of the class the code was originally intended to work with second structural pattern is called the bridge in the Gang of Four book the way that this is put together is very very Java s core c++ esque actually in this original edition of the book it says the principle says don't use sub classing essentially for two different things because if you get your window class and subclass at three different ways so that you know how to instantiate a window on Mac Windows and Linux and then you say you know sometimes I want windows with borders and sometimes I want them to be plain and not have borders and so you subclass them that way too then you wind up with a a multiplying number of different kinds of windows and you can get stuck doing this in languages like Java we're supposed to do everything by sub classing because you don't have things like mix ends that you do in Python because a lot of people would say oh I'll just have a plain and bordered window and then have a Mac Windows Linux mix in that you can throw at it their solution is more general than that they say add another layer have one class that translates the plain and bordered ideas into primitive window operations then have a whole other class that can either do those primitive operations under Windows or Mac or Linux don't try to fit all that into one class find a place like the idea of primitive window operations like drawing pixels on the screen find somewhere where you can cleave the problem into two and have two layers so that you can mix and match operating system kinds of windows with bordered and unboard windows in any combination you choose now this principle actually applies at many levels in Python Garry Bernhardt at PyCon 2012 was asked at the end of his testing talk someone kind of said look my models are full of business logic so how on earth can I write simple tests that dough right to the database because my models like they're supposed to all inherit from database model which is my frameworks way of saving stuff to the database as I play with my person object but you know the guideline is I'm then supposed to implement my business logic as just a bunch of methods on the person rename for when someone at the bank needs to change their name direct deposit for when I need to send someone an amount and it's just a mess because Garry burn her you're telling me right simple fast tests but whenever I instantiate a person and then try to run rename to see if it really does what I intended it to the thing dries right to the database so I've got to have a database up and running just to run my unit tests please Gary Bernard what do I do and Gary Bernhardt had an answer have models that do nothing but persist information to storage say it louder that's what they're for have models that simply persist information to storage don't try to give them another job and then write a business logic layer that implements the operations you'd been sticking into methods the bridge pattern is or the idea is I'll let me go back to slides the idea here is instead of rename in direct deposit being methods they would just become functions that take a person and do things to it so that in your tests you just give them a fake person that's not really in the database and the tests can run very quickly this pattern the bridge pattern is even I find a good idea at the level of modules these days I tend to write modules that tackle only a single level of impedance match instead of trying to do several the other day I was writing a cherry pie plugin that minutes when it's start method is called creates a thread but then add a bunch of code in it that talks to a big library that I use and I found that writing tests for this created threads like if I wanted to call this code at the end five different ways to make sure it works I got all of these threads that I then had to tear down and take care of so I broke it just like this pattern says into two pieces I have one module that imports the relevant stuff from cherry pie and threading and just talks about how a cherry pie plug-in can start a thread and then my second module knows defines the actual work the thread does so it only needs to import that single third-party library and I find these days that like that this leads to a Brandon rule if a module imports three major libraries or frameworks see if you can refactor it into two modules each of which only imports two libraries and your main program can plug the pieces together in Maine or somewhere else I just generally find that my modules keep trying to get more complicated and important more and more things and that often my code winds up a lot simpler easier to test and reason about if each module has a much more limited task and touches fewer pieces of the system so that's a structural pattern that I really love they have one called a composite or composite a class where the instances are designed to lock together into a tree where a widget SE can have other widgets attached to it that can have even literal widgets inside of them this is a very common pattern the email message class in the standard library can have other methods it messages as attachments inside of it because we can do that in email the XML library that I mentioned before of course as you saw in that piece of Ella code that I showed you elements have other elements as their children so this pattern I would argue doesn't disappear at all in the Python language is in fact all over the place and it's great and we use it extensively the the two common mechanisms for implementing in Python are if you only have a few sub objects and they're kind of play different roles inside of the parent you might just store them as attributes but very often either in email attachments or when you're representing like an XML document the children are just kind of all metric all have the same role and only differ by the order that they're in so you put the sub-objects you know maybe inside of a children list those are two common ways to implement the composite pattern when you're doing it in Python another structural pattern is the facade an object that hides a complex tree or network of other objects you might think wait a minute Brandon you just described this and you called it the Builder but the Builder instantiates a complex network of objects the facade then lets you interact with the live network of objects after it's built but they are very similar an example is that Annie tree element when you're doing XML documents it just gives you like a dot find method that will just go search the entire document for you it has a dot eater method that lets you just iterate over everything in the document without having to write the iteration out yourself these are small examples of a facade of something that a single object that you can talk to in order to ask questions about an entire tree of objects that you would otherwise have to traverse they have the structural pattern of a flyweight small object that's immutable and can be reused in many contexts I don't often see this in Python code that people write it would look something like this maybe you've written a text box that has a list of characters that people have typed into the text box to display them correctly it needs to know their dimensions needs to know the outline that you draw on the screen to make the letter T or whatever and also each letter has an x and y location so that when you finally get ready to display it on the screen with dot draw all the information is there to draw the glyph with that is you have to create as many instances of a letter T as you have T's on the screen because they each have a different X&Y they're each at a different location the flight wait pattern says get that little little bit of information that's different between all of those letter T's their position and pull it out into the parent so that you can just keep referring to the same letter objects over and over here I've moved the coordinates the one thing that differed out into my parent container the textbox keeps up with where they are so that I just have to create one instance of each letter and keep putting it into the list wherever it should appear and that often massively cuts down on the number of objects you need to have in memory and again it's called a flyweight the saves memory at the expense of some noise because note going back one slide note that I now have to give X and y to the draw method because they're not on the instance anymore so it does make your code more noisy because that little bit of information that changes between letters has to be passed into all the letters methods if it's going to act on that information C Python uses the flyweight pattern internally for small integers the number 5 is not created afresh over and over and over and over again every time you hit the number 5 in a loop or assign it to a variable instead Python keeps around I think the first hundred small integers maybe and then maybe a few others and every time you ask for the number 5 it actually gives you the same one back because it's immutable so your program never notices that it's having to share the number 5 every single time it needs that integer stored somewhere finally we're getting down to the last structural patterns a proxy they define that as a object that wraps another object kind of like an adapter but but actually a proxy accepts the exact same set of methods we can do this dynamically it's really nice in Python by defining a getter on our proxy that when it's asked for foo turns around and asks the subject for foo these are actually used in the standard library there's an object called weak ref proxy that keeps a weak reference to another object and all the dot foo and bar accesses you make actually get sent to that object if it still exists and when it is reclaimed from memory they finally start giving an error remote procedure call libraries use this when you say dot foo and dot bar to call methods on a server proxy from the standard library it actually goes and talks over the network to get that call done and actually the zope framework used proxies to enforce security I'm going to get into the details of that because of time they and then finally confusingly enough there is a structural pattern called the decorator which is nothing like our decorators in not like function decorators I mean that we put at the top of functions it's like a proxy it offers the same attributes and methods as the subject class behind instance behind it but instead of being completely transparent it might refuse to pass certain calls or might adjust the parameters on the way through to either protect or to change the behavior of the complicated object that you're talking to they tend to appear in the kind of stuff we write if we're not writing a big framework because they are very often appear in glue code where it's like oh this would be so perfect this file if it didn't have blank lines in it because this framework doesn't know how to program that so you daiquiri right a second class that every time read line is called cause read line on the file but keeps doing it till it gets a non blank line thus making it look like a file exists that lacks blank lines by just sort of filtering for or editing the responses of the actual file class so there you have it I would argue that none of these patterns disappeared approved useless simply because our language is Python the pattern that you thought you saw at the beginning where look you know at the beginning of the book all these patterns are disappearing because we're awesome we're in Python actually then stops as you really start to get into some interesting ideas about how to assemble your application I'm going to devote almost just one slide apiece to the structural patterns with which the book ends because they could be whole talks on their own there are 11 of them chain of responsibilities is the idea of if you you can set up a chain of objects that are all asked do you want to handle this request do you want to handle this request and when someone finally says I can handle it then you stop asking and it's a way to kind of set up default actions and stuff where you normally when you do an action but if you don't know what to do you just hand it to the next guy in the chain and maybe he invokes a default action that can be assembled at runtime there's a lot in gooeys and document object models so that if you click on something it's like I don't know what to do with a click on a text label in the button that the text labels inside F gets the message and says I'm a button I know what to do when I'm clicked as happens in your browser all the time the there's the idea of a command which is the idea that when a user clicks I'm probably going to go three minutes over because of the technical problems at the beginning so don't clap yet' the immediate so the idea is when a user clicks on something to paint a line on the screen instead of just calling paint line to do it you instead instantiate a paint line command call its dot do or go method or whatever you call it and then append it to a history of commands so that when they hit undo later it also has an undo method that knows how to take the line away and this is really often used when writing big applications like image editors another pattern is the interpreter where you read in a little programming language you've defined they're good talks like every year at PyCon about how to write interpreters so I'll refer that for you to those but the idea is you define over the language for people who use your application to write in they write it you and you parse it and then you just have a little program that runs over the parsed representation of the program and does the things that says this is how Python itself is written it's C Python is itself an interpreter that reads in your Python code to an intermediate representation bytecode and then just starts doing what it says I will devote two or three slides to the Gang of Four idea of an iterator because it's built into Python and it's awesome it was introduced in 2001 I consider it the most important Python innovation of the decade of the 2000s see Raymond head injures PI code conf talk from 2011 what makes Python awesome for some really great examples of this it lets you get your own object object by hand as though you're a list or a dictionary or something that can be iterated over you can either it needs to do it and either write a class that knows okay I'm iterating over this other object and I'm at item three now on an atom for now I'm at item five and that every time it's next is called lyvers up the next item from the original container or these days you can simply make the inter method a generator and go back to my slides later if these are new concepts to you because they're good to study but you could actually just make your box iterable like this it's very easy these days it's a very powerful pattern makes it really easy to fit things together it gives us all all of those Python programmers now have a common way to communicate about and to implement this fundamental idea of iteration go look at Raymond's talk it means that this kind of code from JavaScript disappears from your programs because the details of know how do I add a rate over this kind of object again disappear into the iteration logic and all you ever see in our code is pretty for loops now going fast again there's a behavioral pattern called a mediator where instead of having to write a button that knows to go up data value and a value that knows when something is typed in to go do something else you just use generic buttons and text fields and have a single class that takes the click signals and goes and tells the other pieces of your page or your application to update this means that all of your actions wind up in one place rather than scattered through all of these you know slight little changes and improvements you've made to the button so instead of having three kinds of button that each do something different you just have 30 completely generic buttons and another class that receives the actions that they're performing there's a momento it's kind of like a pickle you can ask an object give me a memento of your current state you get this big string or something you can always give it back to it and it will set itself back to that earlier state so it's sort of like a pickle but instead of using it to create new objects you use it on a live object that's already talking to a bunch of objects to kick it back to an earlier state there's an observer where you write models and say instead of saying okay my model has a total and you can set it and when it set it we need to update the title bar and the graph that we have on the screen and the summary because they all mention the total somewhere in them instead of doing that you instead leave the model completely alone it just does its normal thing and you when you have an observer pattern implemented in a library you which is also called pub/sub these days and like JavaScript frameworks everyone who's interested in the value can just listen to it it really appears in Python for the the reason that I'll get to in my conclusion go into the book to look up the idea of a state a strategy and a template and a visitor which is sort of the other end of iteration what does it look like as you're receiving the items inside of a list or tree and I will just summarize by saying the behavioral patterns are big solutions for big problems and most of the patterns work just fine in Python the guise of the patterns I was just going through all kind of work and will help you organize your code they do tend to turn out more in big in popular libraries and in our normal code and the emulator is the one that has disappeared into the syntax of language but the others haven't creational patterns some of them disappeared behavioral some of them disappeared but the structural patterns all pretty much remained intact I will skip the bonus round on dependency injection which is an awesome pattern that's come to prominence after this book and I'll just finish with my my big claim here we rarely meet the bigger patterns not for most of them because any feature or magic that the Python language has let us get rid of them but because of the kind of application that Python programmers tend to write we tend to write small scripts or applications that are lightweight one-shot tasks that is we tend to either write small scripts that do one task or we tell you to write web apps which are really just a collection of small tasks each of which lives at a different URL answering a web request transforming a text file all of these things we tend to do even MapReduce steps tend to just be a little things we read some stuff in there some objects play with them and save a results somewhere the philosophy of unix tools of small targeted tools we barely have time to worry about setting up pub/sub subscriptions so that widgets on the screen automatically update when values change and the other reason is that we do get into that when we do write inks capers you know a big application in Python very often the framework has already implemented the patterns for us we just throw callbacks at it and it's already doing the pub/sub here are some examples if you've ever written a big graphical application we rarely meet the bigger patterns not because of any feature or magic of Python but because of the applications we write I think that's why we often don't wind up doing these in our own code we tend to write glue code because the open-source community has already done the hard parts for us and handed it to us on a platter thank you very much come up to me afterwards if you have questions let me get
Info
Channel: Next Day Video
Views: 116,833
Rating: 4.8590307 out of 5
Keywords: pyohio, pyohio_2012, BrandonRhodes
Id: Er5K_nR5lDQ
Channel Id: undefined
Length: 67min 50sec (4070 seconds)
Published: Sun Sep 02 2012
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.