Classic Design Patterns: Where Are They Now - Brandon Rhodes - code::dive 2022

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
yes so I'd like to welcome you to our first technical malfunction that we have now so swiftly dealt with which only shows the professionalism of our team so without further Ado I'd like to introduce our first Speaker Brandon Rhodes now Brandon is happy to be back in Poland for his sixth conference here normally Brandon lives in Indiana where he has a 128 year old house and the house needs so many repairs that it's a project in itself and Brandon set up an Instagram account to his house and it is so popular that it now has over 300 followers now classic design patterns where are they now let's have a round of applause for Brandon Rhodes [Applause] thank you very much I am delighted to be back in Poland I am delighted that code dive is um back in person and uh yes as just announced I am here to talk to you about the classic design patterns where are they now design patterns was a book they came out back in the 90s it was a long time ago but I still see questions about it online and so I thought it would be interesting to review whether any of the book is still relevant today it uh came out in 94. it was a book on on a fad at the time called object-oriented programming was by four people that no one could remember the names of so they just called them the gang of four because um there weren't any other programming books written by four people it described 23 design patterns they called them that had become common solutions for the problems with these newfangled object-oriented languages my goal for this talk is to make a brief survey of the 23 patterns asking these questions can we learn anything from the ones that survived can we learn any things from the ones that did not there will be limitations to this talk I'm going to have to cover 23 design patterns in in under an hour there will not therefore be much time for nuance or Corner cases it reflects my experience programming a lot of python less C and C plus plus not your experiences which might be different and it will not be entirely Fair towards the visitor pattern for which I apologize in advance it's okay the relevant patterns is diff icult than mine by the time we finish the talk the goal is for these old patterns to help us reflect on how we program today happily the design patterns book is online so you can review the patterns yourself later to develop your own opinions if you don't like mine if you look up design patterns gang of four this Dot unc.edu site from a CS Professor should be high in the results and has the full text of the original copy of the book with all the code examples mostly in a small talk in C plus plus uh some of my own ideas on design patterns as they apply to python or online if you want to check those afterwards as well so are you ready here we go 23 patterns that they grouped into three and what should we go with first the ones that maybe survived or the ones that did not first Let's cross off the patterns that didn't really wind up being relevant if your programming language offers first class functions what our first class functions I hear you cry those are functions that can be passed as an argument to another procedure a routine and placed in a data structure and associated with data you might think what language doesn't allow that small talk was the language available in 94. the Pioneer language of object orientation didn't let you pass functions or procedures so there were a number of design patterns that we're just kind of trying to get around this problem with small talk and some of its descendant languages let's look at them quickly the factory method said all right well what if we need to give a piece of code to um a big class like application big classes like that were popular back then because just to bring up a window on the screen could take 100 lines of code in 94 and windows or on a Mac you want to wrap that up in an object so the idea was oh well if once the application object is up and running if it needs to know how to create your document it doesn't know whether you're programming a spreadsheet or a word processor it's going to need to know how to call a create document procedure that builds and returns an instance of your document class well how could it do that if we can't pass functions uh so their idea was that you would subclass application yeah yes make your entire own subclass of application just to add one line of code not only does that sound hopelessly awkward today even design patterns itself back in 1994 offered a better approach two chapters earlier they had already described the abstract Factory the abstract Factory says let's not make a subclass of application let's instead design application so that it takes as a Constructor argument a little bitty class that has your special line of code in it that knows how to build your particular subclass of document why should we prefer that second pattern the abstract Factory over the first one the factory method because of a fundamental design principle from the introduction chapter of the design patterns book itself in fact it was so important that they didn't bury it in a paragraph they put it on a line by itself just like this in italics just like this favor object composition over class inheritance one of the fundamental principles of the book what is composition you have in their terms composed two objects when you give one of them a reference to the other so if I create F A my document Factory and then pass it as a Constructor argument to the application that it saves as an instance variable I have composed those two objects favor object composition over class inheritance why go read the introduction uh to read the Full Slate of reasons but a quick one I'll mention is because putting objects together dynamically at runtime is simply more flexible than writing a bunch of extra classes at compile time and so they always favor object composition Factory method well it's class inheritance the abstract Factory as we saw a minute ago does the same thing with object composition and so it is the better pattern by their own rules so you might ask well then why did design patterns include the factory method why write an entire chapter on it if a better alternative already existed and this is something important to understand because they wanted the book to be a complete catalog of all common object-oriented practices they did not limit themselves to best practices they wanted you to be able to find all the patterns you were likely to encounter in 1994 programming and the factory method despite its awkwardness was in widespread use in their own words Factory methods pervade tool kits and Frameworks and they were able offhand to give a long list of Frameworks that were always having use subclass in order to specialize so they had two different ways to parameterize object creation but neither one is a pattern that we tend to use in modern languages I go years at a time without seeing either of those patterns because our languages today have first class functions and in that case you don't need to pass application an instance of a class that you've attached a method to you just pass in your Constructor function so some languages even have first class types and you can just pass the class itself to be instantiated and so those two patterns have largely fallen out of use among people that use modern especially Dynamic languages all right what about some of these other patterns let's go ahead down in the lower right and look at template method template method should look familiar it should look like the uh one of the two patterns we just looked at this asks what if application needs you to give it three procedures not one well then you should have to write a subclass and override the three abstract methods with three concrete procedures by the logic of the book Zone introduction that we should favor object composition over class inheritance I think it's clear that rather than uh getting a huge object that you don't understand the internals of and trying to write three new methods for it it would be much clearer if you just had a separate type that you subclassed and built off of to provide the three methods that this fictional application needs you as the programmer to provide to it so uh by the book Zone logic let's also go ahead and cross off template method all right up to the left prototype pattern that was actually kind of interesting imagine they say in their chapter that we're writing a music composition application that wants to let users create four kinds of object here they are notice and this is the challenge they're of different classes different subclasses of some parent class rest and note and some of their Constructors need arguments and some don't so it's kind of a mixed bag the rules by which you create these now how could you explain to say a menu widget that's going to be on the screen how to create these objects when you menu items are selected when some of them have different classes and some of them have different Constructor arguments now in a modern language of course you're already thinking you could just pass a data structure the people who designed the menu system probably just want a plain data structure with the names of some menu items the callable the function the type that needs to be invoked and then any arguments that they need all right but the gang of four 1994 have to ask what if your language isn't that powerful are you going to need as many factories as kinds of objects that you want to create not just one per class but even one per individual kind of note the Prototype pattern said ah no simply create examples of the four objects and give them each a clone method the idea here is that if you give a collection of objects a clone method where what happens when you call clone well it builds and returns to you a new instance using the same Constructor arguments as were used to construct the object you're calling then if I have three kinds of note I just instantiate them I pass them to the framework and it calls clone to get new copies of notes with the same Constructor argument you've replaced needing to have a whole slate of separate Constructors with just needing a clone method on each uh class thanks to the Prototype patterns clone method we can give plain object instances to the menu instead of separate factories it's an interesting solution to a problem I don't actually dislike it I've just never seen it before I have never seen that problem come up in modern languages because we just don't get into that situation though I have to admit I like the solution and find it elegant at a level that I don't for these first few patterns that we crossed off all right the next one's the Singleton I'm not going to spend much time on this Singletons are those annoying Global objects that code seems to need access to but you don't want to pass everywhere um do we need Singletons sometimes maybe that's a big topic of its own and people give entire talks about Singletons but do we need the Singleton pattern if you go look at their chapter they have this whole elaborate story about how you can tort the class itself to force it to be used as a Singleton it refuses to build multiple copies of the class so that it can only be used as a Singleton do we need that pattern even if we need Singletons in my experience no and in fact I've been in in million line code bases before in some of my work and never seen the Singleton pattern just write the class normally build a single instance and provide a global name or a global function that returns that instance from the python standard Library you call logging.getlogger and everyone who calls that gets the same object back so you're all logging to the same file it works fine without the pattern why avoid the Singleton pattern again it's a whole technical discussion of its own but one hint of why is reason it's easy to explain is that testing becomes hard and tests of the Singleton become coupled if you really truly can't create a fresh instance so that all of your tests are having to share that's just one reason not to follow their contorted pattern for delivering Singletons and so I don't encounter it in practice and so we cross it out ah we're making progress all right one last one that tends to disappear because of the power of modern languages is the strategy pattern strategy pattern all right their example is what if you had an object that needed to be given a specific paragraph breaking routine at runtime out of three that are available at runtime right so you can't specify it when it compiles because it might be a config file or something that selects it strategy pattern says well put the three versions of the routine in three single method classes build an instance of each and pass them as Constructor arguments at runtime to the routine that needs them this is their diagram from the book by the way all of the diagrams I'm using are theirs from the book the official ones uh showing how if you need a compositor that can split paragraphs into lines on a page you might write three specific subclasses of the compositor and then can build an instance and pass it to the composition object at runtime when it is ready to call compositor compose we today can solve this more simply in any modern language you solve this problem by just writing three functions and passing one in as an argument done once again we don't have to wrap up a procedure as a method of a class of which we build an instance we just pass procedures around when we need them so in my experience the strategy pattern never comes up in modern languages and so for my purposes I cross it off all right in powerful modern languages these six patterns disappear because they aren't needed so we're down to 17. making some progress what should we tackle next well since we're on the topic of programming languages there are two patterns that are also disappearing from our code but it's because they're so useful they're now getting built into our languages these are the iterator and the visitor pattern we'll describe them briefly both of them involve a producer object which is going to build or retrieve items and a consumer object that wants to iterate over those items without needing to know the details of how they're being produced or stored patterns are opposites of each other the iterator pattern says well let's write the producer to offer a callback method very often it has a name like next the consumer then Loops calling next over and over until the producer is done delivering objects visitor visitor pattern is the opposite the producer is in control iterating across a tree or other data structure and calling the consumer which offers one or more callback methods that are used to deliver the next item in Legacy languages you have to choose one approach or the other either way someone's class has to suffer from callback style programming the solution to this which was actually invented in the 70s is called generators they were in a pair of obscure languages and were revived to the pattern generators were revived in 2001 when python added them uh they were so popular they've now now been added to c-sharp JavaScript and Ruby what is this idea and and why did it uh is it taking the world my storm well before generators you had to write up the iterator pattern yourself you had to make a little class with a next method this is just Counts from one to ten and you had to have a convention for building objects and then signaling when you were done delivering them you had to write it yourself after generators have been added to your language you get a new keyword control flow keyword called yield you now just write a normal Loop and uh yield each time you have a new item that's ready for delivery to the consumer each time the consumer asks for an item the producer runs enough code to reach its next yield and deliver the item so the consumer's requests for more items gradually cause the producer one step at a time to run all the way to completion so both the producer and consumer can be written with normal control flow statements like if and for and while things we're all familiar with neither is forced to Define methods or endure callbacks here they can both just use a simple for Loop passing a producer to a consumer works exactly as though you had implemented the iterator pattern by hand and written a class with a next method that returns a lot of objects except I'm going to go on a tangent for one moment if you will allow me don't actually let a consumer talk to a producer here I just want to touch briefly on an important aspect in application design as opposed to object design to different things if you have the consumer Drive the producer directly by passing it in and letting the consumer cause the producer's code to be run well your main thread loses control all of the action happens in that last line of code with the main thread being out of the loop literally I call this Domino programming and it really really uh dominated object orientation especially back in the 90s I don't mean the game dominoes I mean as a kid did you ever set up a line of dominoes standing up on end trying to get it where when you press the first one everything else would fall over but you were out of control once it started happening Domino programming is where instead of just doing a uh and your main threat of control a series of actions you instead are setting up a bunch of classes that all know about each other so that when you tip over the first Domino everything out of your control everything that's supposed to happen does this is Domino programming and I believe in many cases it's an anti-pattern for your main threat of control to surrender to other classes the question of what happens next here's an idea instead run the producer to completion and save the output in a plain flat data structure maybe a list get the producer done then pass the list to the consumer a flat data structure this idea may sound silly when we're only talking about one producer and one consumer but as an application grows you should always prefer shallow call Stacks to deep ones it's a good day when you can draw a bright line across your code and say everything above this line has finished running and the only thing Crossing this line is a simple inert data structure here's where we can draw the line if we're the one that runs the producer to completion now yes sometimes you want them to talk together right because if it's a video streaming service you want to go ahead and be getting data on the wire you want the main Loop to stand aside and let data start flowing but if you're not in a situation where you're going to run out of ram from the size of the list and you don't need live streaming think about making sections of code independent of each other where it's only a data structure that passes from one piece of your main routine to the next where you're able to draw that bright line where execution of everything above it has finished the objects have gone inert or bendy allocated and plain data that you can look at and debug is the thing passing uh to the next phase of your program why there are a number of reasons and it would be a talk of its own for me to go into all of them but at the core of what I'm trying to say is this that data is easier to reason about than control flow an old book from 1975 on why software projects are always delivered late it was called the mythical man month by Fred Brooks and he said show me your flowchart the diagram that shows how control flow will pass in your code and conceal your tables and I shall continue to be mystified but show me your tables your data structures and I won't usually need your flowchart it'll be obvious he found as I do data easy to read about code and control flow more difficult so that's one reason to prefer keeping control and using data to link parts of your program rather than verbs and actions love your data part your data in Unicode um be jealous of getting to see your data and not just having it pass anonymously between routines things are easier to control and debug and expand later if your main routine is in control of as much data as it can all right end of tangent iterator and visitor great patterns but I don't write next methods anymore because the languages I use have now built both of those patterns into the language so they're still there they're powerful and they're working but as design patterns they disappear from my code because I no longer have to implement them so for the purposes of this talk of what I actually write as classes these days I'm crossing them off the list all right only 15 left are there any more that we can eliminate I think there are three proxy Memento and observer what are these proxy actually has several branches several uses but I will limit myself so the talk doesn't go long to the remote proxy which was the most famous and widespread use of the pattern where the methods of a class send requests across the network it looks like you have a user class right in memory but in fact every method call is actually going to another server to get the return value second the memento Memento is a object State saved as a binary string so right your big application is about to exit but you want to be able to rebuild its state when it comes back up the momentum the Memento pattern says well teach the object to write itself out as bytes and then when you run the application again you can read the bytes back in and the object will be recreated The Observer pattern finally is where an object can offer subscriptions to its changes and other objects called subscribers can receive callbacks when the data in the object changes so why am I putting these three patterns together I will explain it by explaining what are their sins what did they each do wrong the proxy pattern hides how data's passed across the network somehow the method calls are getting crossed passed across the network network but you don't know how the Memento pattern hides how data is persisted to disk it's just a binary blob that you don't know how to introspect and the Observer pattern scatters data a bunch across across a bunch of objects that communicate now about changes rather than unifying it in other words all three patterns do something wrong with data and you should love your data you want to see it you want to be in control of it you don't want it to disappear and be an obscure private format that you don't understand so in the uh jobs I've had over the last 10 or 15 years the code base is large and small I've worked on I don't see the proxy pattern in the projects I've been on network apis between Services should use a data format you understand and can document there's many good options today and be hand crafted to make sense over a high latency Channel good object methods for things that are in memory tend to be small orthogonal and numerous good remote procedures tend to be comprehensive Aggregate and few and as an example a class might offer Getters and Setters for all of its 11 instance variables separately but a network call would probably want to return all 11 at once and set as many as you want to provide when you do a right whole different set of design decisions when you're going remote overdoing method calls to things in Ram second the Memento pattern data should be persisted in a format that's independent of your programming language and that you can access directly using other tools and there's a lot of good options today open source uh even um like they weren't in 94 for storing information so that you can get to it later and so that if you're having to debug something at three in the morning there are other tools besides uh maybe the the you know broken code that was pushed late at night for getting into that data and finding out what's going on finally The Observer pattern should we really be building forests of objects that are subscribed to each other's State changes turns out the answer is no I don't have time to tell the long sad story but go look on YouTube for any recent Facebook talk about their react library and about how hard it was to make the Facebook page you see on the web stay consistent if they were a single piece of data that let's say a notification that could be several places on the screen at once react today is the most popular JS Library as of a few months ago it's actually not to jQuery which felt like would be there forever off of the throne and it's now being used in more current projects um than any other JavaScript library why is it so popular what is the secret to react success data it says that instead of your data being uh living on a bunch of live objects that are trying to send each other updates your data should be simple it should be inert and essentially you get all of the data the application uh page knows about so your facebook.com everything you're seeing all the information you're seeing is sitting in a plain Json data hierarchical object clicks keystrokes and server events are not allowed to go touch views and uh objects on the screen they have to write to that inert data structure updating its hierarchy and overriding things then react actually diffs the object or what the views should be with what they were uh previously and goes and updates the screen for you so a simple well perhaps a very large data structure but but a hierarchical inert data structure that it's easy to view and reason about is the only place where events can coordinate with views and it's uh become the most popular JavaScript library because it's so much easier than having objects trying to update each other by putting data in the center so react makes a single data structure the foundation of your application the proxy the momento and the Observer all three of these patterns fail to put data first and you should heart your data and that I think is why in the last decade of programming I cannot remember seeing a single one of those patterns once so we get to cross three more of them off all right we've essentially eliminated half we've knocked out 11 of them leaving a dozen left and at this point I think I can't go farther at this point I think that I've run out of uh patterns that I can easily knock down as being irrelevant or anti-patterns so let's get the ones that have survived and let's look at them in groups and see how they work first we will look at these four because they all have something in common Bridge decorator mediator and state they are each fairly complicated and alas I can only summarize them very quickly the bridge is the idea that one real world object like a window on the screen on your computer might be implemented best by two classes some of the people writing the very first application Frameworks found that you want to specialize the window according to whether it's a little pop-up window or whether it's showing icons because that affects its layout and behavior but you also need to subclass window because we have more than one operating system we want to support and the low-level windowing routines on each os are quite different and that requires you to subclass in two directions at once and then have a large number of subclasses unless you split the window into two so they had this idea when the Apple when your application code asks for a window it actually builds two objects um the window object that you see is the high level one that knows how it should behave and how its data should be laid out but secretly it creates a low level window imp object behind it that knows how to talk to the operating system one real world object but two classes that was the bridge pattern all right second decorator the idea here was to write a wrapper class with the same interface as the object wrapped they were thinking what if you have a text View class that knows how to draw text on a bitmap we want to add scroll bars to it but you don't want to make it more complicated well they thought what if you write so text view you know has a draw method knows how to draw text what if you made a scroll decorator a class that when it's asked to draw turns around and asks the text view to draw gets the resulting bitmap cuts out a portion of it will fit on the screen and draws a pair of little scroll bars around it now you can have scroll bars and the text view doesn't even know they're there it doesn't know that only part of it is showing on the screen and once you've come up with that idea that the scroll decorator accepts the same interface or offers the same interface as it uses for the view behind it you realize that you can stack these endlessly you could have them do logging you could have them on some kinds of objects do different kinds of protection you can stack decorators as deep as you want because they offer the same interface they accept so a decorator is a valid thing to wrap with another decorator of the same interface all right that's that pattern third the mediator now here we have a list box and an entry field and I know what you're going to tell me Brandon you just told me to use react but some in this imagines it's just a very simple interface a list box and an entry field so we'll go with it and the idea here is you know sometimes in a dialog box if you edit one thing the options available on the other one change and this pattern simply says that you shouldn't put that code in either the list box or the entry field in other words you shouldn't do a pair of observers watching for changes in each other how about you split that out into a separate procedure lower left here widget changed that when either any of the either of them is edited calls a single procedure that then tries to get everything straight again instead of a bunch of objects that talk to each other have another layer on top that's the idea of a mediator finally and this one was a little interesting I'd never seen it before they had one called State what happened is they implemented a TCP connection using object orientation they noted that every single method had to start with the same if statement if the connection is open do one thing otherwise return nothing or raise an error next method check if it's open if it is do one thing if the connection's closed return nothing or raise an error and they notice that every single method had to have is it open already well they reasoned that maybe we could get rid of all those if statements if we had some secret objects in the background where we could Define the stack of what the methods do if it's open and then a separate object that had the stack of methods that get called if it's closed that idea that the TCP connection you're using is one object might swap out a back end object depending on its state it's called the state pattern it replaces if else Stacks with what are simply separate objects Bridge decorator mediator state what do they have in common why did I put them together they all break the old object-oriented assumption that one real world object should become one object in your code some of the people who invented small talk and reusing it in the late 80s early 90s thought that this would be the solution to how we organize code because code right it always gets Tangled and they thought that if they made the rule that if everything that can happen to a window is on a single window object if everything that can happen to the database row is in a single object our code wouldn't be Tangled anymore turns out that's not true and all four of these patterns are saying are breaking that assumption and are starting to say you know maybe it makes sense to split behaviors out into several classes even for what is conceptually a single window on the screen all of these classes three of them are are essentially kind of pulling behaviors uh off and and layering it on top of what might have been a single object and then the state is getting behaviors and secretly behind the class you're using pulling uh behaviors out but you can see that all of these classes are breaking apart the old object-oriented pattern of every single thing that can happen to an object living as a method on it these four patterns essentially all begin a disassembly of object orientation right in the middle of the most famous book on that subject and start using classes to organize procedures into layers rather than to represent data in the same way that as we went through our first patterns we were talking about getting data out and giving it a life separately from objects these patterns are getting actions getting behaviors and pulling them out and giving them a separate life as well and that's an interesting enough move in the world of object orientation especially in the 90s that I'm going to keep them even though I honestly have rarely used these four patterns I think they're Keepers because if I did wind up in one of those exact situations I think I would be likely to use them I know what you're about to say Brandon isn't that Domino programming isn't this setting up classes so that you call one thing and then automatically another thing and another thing gets called twitch I have to say that's an interesting point and I think you're right and it is indeed to some extent Domino programming knock over the first decorator and calls start happening automatically but they are elegant enough and constrained enough that I think I could live with them I think I would still understand what my code was doing so for the purpose of this talk they are staying all right next we'll just look at three small sort of Standalone patterns that uh are all in widespread use today the Builder pattern says provide a single object whose API builds and returns an object hierarchy for us right why make you if a bunch of objects need to exist worry about how they need to be instantiated connected together if someone else can do it for you example the matte plotlib library for drawing diagrams under python it has an axis object that has a down in the lower left here you can say axis plot this data axis annotate and put some annotations on the the chart and you don't have to worry about what plot objects look like or annotation objects or what references they need to each other if they're going to render successfully when the time comes the axis object handles that for you Builder pattern when it works and when it fits an API is really really great because your code neither has to worry about nor become coupled with how back-end representations are being built second the adapter pattern when a class doesn't offer the interface you need write a wrapper class that does and have its methods call the underlying object a python standard Library sockets have a DOT make file method that returns an adapter that looks like a file object but whose read and write methods really call the sockets receive and send methods so if if someone on your team is written code thought it would be writing to a file can pass it this object and now the data will go across the network without needing to edit your friend's code that's the adapter pattern the flyweight pattern finally says that small read-only data can be shared between object instances this came up a lot when they were writing the very first versions of presentation libraries they noticed that if you put the letter A on the screen in two places that the X and Y coordinates will be different but the dimensions of the letter are the same yet you're copying that information into all of these different glyphs why not have a read-only so that it can be safely shared little data object that keeps the information that's constant and shared between all instances of the letter a and pull off into the glyph only the X and Y that differ between them pulling off read-only data like this is called again um the flyweight pattern the um as an example the integers negative 5 through 256 in Python are flyweight objects right python everything is an object well that's going to be so inefficient you're going to have to build integers all the time well they actually avoid some of that expense by going ahead and pre-building sort of the most popular integers so that each time a calculation in Python returns an integer in that range like 17 or something it's the same object that gets returned every time that again is called a flyweight so I encounter all three of these patterns fairly frequently they from 1994 wound up being keepers all right are you ready now we're going to look at the really big patterns the ones that have wound up uh uh governing the way our main applications operate today the composite the chain of responsibility the command and The Interpreter what are these well the composite pattern oh by the way I call these the framework patterns because they're not ones that I tend to sit down and write they are ones that I tend to sit down and use composite says give all nodes in a hierarchy the same interface instead of giving um uh the middle nodes one interface and the leaf nodes another the idea here is that if you're doing a hierarchy of items in a drawing lines and rectangles and things like that go ahead and make the aggregate object the picture an instance of graphic as well that way pictures can hold other pictures and your hierarchy has a all the way down to the bottom has a consistent interface I know many of you instantly are thinking of the Dom the document object model that underlies all web programming because it uses the composite pattern a div can hold things inside of it an image cannot and yet they both have the same object interface in the Dom not only do they both have a tag name which of course they both have but even image has a DOT children list even though it is always empty because it makes programming simple you can run across all of the objects in the Dom asking about their dot children and you don't have to have an if statement and remember the rule that images can't have any they offer the exact same interface all the way down to the bottom makes programming simple it's called the composite pattern next the chain of responsibility in a composite UI hierarchy in the browser or elsewhere there was this pattern in 1994 where you pass unprocessed clicks and keystrokes up to your parent this is universal and is called bubbling in the browser so you click on the piece of text and it's like I don't care I don't want to be clicked on what but it gets passed up to the button that the text is inside of and the button now knows it's been pressed again that is universal and it is used everywhere the command pattern said to represent user actions as a list of objects that have both do and undo methods because it's so tempting when you're first programming and the user hits the letter A to just add the letter A to the buffer command pattern says no no no instantiate a typed a object and call its do method to add a to that text field so that when the user then hits Ctrl Z undo you can run the undo method on the action and step backwards this is universal in browsers and GUI Frameworks today it turns out that the command pattern is also useful in other contexts I saw I don't use Django a very popular web framework but I saw a talk on it a couple of years ago about their new migration system Django lets you define what your database tables should look like using a declarative syntax and as your application evolves your models change as your models change Django saves those database migrations using the command pattern so that you can both apply each migration in production to move forward but also undo a migration to recover and move back so it remembers the modifications you've made over your application lifetime you can undo them later because of the command pattern finally The Interpreter it uses the composite pattern to represent an abstract syntax tree and make it executable by giving each node a method what do I mean if you want in a spreadsheet or something else a user to be able to type in plus one you parse in plus one and traditionally build an abstract syntax tree that says oh we have an ad operation with two arguments in many places The Next Step would be to then compile that to bytecode or machine code but that requires a lot of extra Machinery this pattern says just give them an eval method don't bother compiling don't bother inventing or adopting a byte code just give each node in your abstract abstract syntax Tree in a vowel method that goes ahead and grabs the value of n or Returns the value one and then the add method can add those together and return the result so abstract syntax trees become executable and you can let users type Expressions on the fly or you can let Expressions live in config files without having a compiler around and so those four patterns have become absolutely huge and have really moved to the center of how user interfaces um are implemented today I don't Implement browsers so I don't sit down and write them but I am constantly a user of those patterns as in some form are we all Nate winds up in an odd little position and we'll finish with it facade says hide a complex system when you can behind a single API class that way as objects come and go the caller doesn't need to know they just call methods on the facade problem it actually doesn't wind up working in practice to qualify as a facade pattern in API per the way they wrote the chapter must live on only one object but real world apis almost always use several here's two quick examples in jQuery well it has this single you know dollar sign that you keep calling to do searches for elements is that a facade no because the rest of the API is the query objects that you get back with the list of the elements you selected and every query results in a different object so it's a little collection of objects that jQuery is using to let you talk about the Dom one of the most popular libraries today is the pandas data frame object where you can read CSV and write their second line you can with a single line of code read in a big data file and it almost at first looks like a facade you can ask the size and the columns on that one object but it's not a facade because once you start wanting to go do math using the individual Columns of the CSV file like name and amount it's returning smaller series objects which are a second layer of object you're talking to so it's not strictly speaking of Assad facade has to be one object and are really really real world popular apis today are typically several objects also the design patterns example of a facade they don't set that set this as a rule but it provides no access to the underlying subsystem but real world apis are usually happy to let you access the lower level uh you can ask jQuery for the underlying Dom element you can ask numpy for the pandas for the underlying array they're not trying to hide the details they're just trying to make them convenient but want to let you drill down when you need to so that facade winds up in a kind of a Twilight Zone where it sounded like a great idea it just rarely works out so we've made it we've completed our survey six patterns useless if you have first class functions two have become language built-ins and three are real anti-patterns that obscure our data but half of them I would say survived four were rare but useful for decomposing big classes three small but useful if four are huge and dominate our Frameworks and finally one final pattern was ambitious but fatally Limited that's my Tally you might have your own thank you very much for your attention during this Whirlwind tour I'm Brandon Rhodes thank you very much [Applause]
Info
Channel: code::dive conference
Views: 12,094
Rating: undefined out of 5
Keywords:
Id: pGq7Cr2ekVM
Channel Id: undefined
Length: 51min 30sec (3090 seconds)
Published: Tue Dec 13 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.