We're sorry but this page doesn't work properly without JavaScript enabled. Please enable it to continue.
Feedback

Mastering Design Patterns: Crafting Elegant Solutions with a Confidence

00:00

Formale Metadaten

Titel
Mastering Design Patterns: Crafting Elegant Solutions with a Confidence
Serientitel
Anzahl der Teile
131
Autor
Mitwirkende
Lizenz
CC-Namensnennung - keine kommerzielle Nutzung - Weitergabe unter gleichen Bedingungen 3.0 Unported:
Sie dürfen das Werk bzw. den Inhalt zu jedem legalen und nicht-kommerziellen Zweck nutzen, verändern und in unveränderter oder veränderter Form vervielfältigen, verbreiten und öffentlich zugänglich machen, sofern Sie den Namen des Autors/Rechteinhabers in der von ihm festgelegten Weise nennen und das Werk bzw. diesen Inhalt auch in veränderter Form nur unter den Bedingungen dieser Lizenz weitergeben
Identifikatoren
Herausgeber
Erscheinungsjahr
Sprache

Inhaltliche Metadaten

Fachgebiet
Genre
Abstract
Join us for an illuminating 30-minute journey into the world of design patterns at EuroPython 2024. Design patterns aren't just abstract concepts; they are the architectural blueprints that empower developers to create elegant and maintainable software solutions. In this session, we bridge the gap between theory and practice, offering practical insights for developers of all levels. We'll delve into a curated selection of design patterns, from foundational creational patterns to advanced behavioral patterns, showcasing their real-world applications and transformative impact on Python development. Through a blend of theory and practice, attendees will gain a comprehensive understanding of how to identify common design problems and apply appropriate patterns to solve them efficiently. Using engaging examples and hands-on exercises, we'll equip attendees with the knowledge and skills needed to architect cleaner, more maintainable codebases. Whether you're a seasoned veteran or a curious novice, this presentation offers a comprehensive roadmap for mastering Python design patterns and architecting software solutions with grace.
Prozess <Informatik>BereichsschätzungBSP <Computerarchitektur>EntwurfsmusterComputeranimationVorlesung/Konferenz
OktaederSoftwareObjekt <Kategorie>EntwurfsmusterAutorisierungElement <Gruppentheorie>Objektorientierte ProgrammierspracheSoftwareComputeranimation
Faktor <Algebra>InstantiierungSichtenkonzeptMultiplikationThreadKlasse <Mathematik>Singularität <Mathematik>Produkt <Mathematik>Interface <Schaltung>AbstraktionsebeneClientSoftwareImplementierungEntwurfsmusterPhysikalisches SystemDefaultSoftwareentwicklerMusterspracheFaktor <Algebra>Objekt <Kategorie>Bridge <Kommunikationstechnik>Prozess <Informatik>MultiplikationsoperatorTemplateInstantiierungWiderspruchsfreiheitKlasse <Mathematik>DifferenteFehlermeldungCodeZahlenbereichMereologieSoftwarewartungFormale SpracheMultiplikationKomponente <Software>Charakteristisches PolynomProdukt <Mathematik>Framework <Informatik>DatenstrukturProgrammbibliothekKategorie <Mathematik>SelbstrepräsentationVererbungshierarchieEinfach zusammenhängender RaumPunktDatenbankAbstraktionsebeneStochastische AbhängigkeitInterface <Schaltung>Attributierte GrammatikPaarvergleichOpen SourceEinfache GenauigkeitZweiRechenschieberKartesische KoordinatenFokalpunktMechanismus-Design-TheorieExogene VariableFamilie <Mathematik>BitIdeal <Mathematik>Interaktives FernsehenTypentheorieMathematische LogikLoginKonfigurationsraumRefactoringDigital Rights ManagementComputeranimation
Faktor <Algebra>AbstraktionsebeneInterface <Schaltung>Produkt <Mathematik>ClientObjekt <Kategorie>KreisbogenKlasse <Mathematik>PASS <Programm>SystemprogrammierungHochdruckDatenstrukturInteraktives FernsehenKomplex <Algebra>Interface <Schaltung>Mechanismus-Design-TheorieHochdruckClientMaßerweiterungLaufzeitfehlerAbgeschlossene MengeBetriebssystemGeheimnisprinzipCodeObjekt <Kategorie>Offene MengeErwartungswertRechter WinkelFunktionalParametersystemKartesische KoordinatenKlasse <Mathematik>SystemplattformBildschirmfensterInstantiierungKategorie <Mathematik>ZahlenbereichSchnittmengeNichtlinearer OperatorUmwandlungsenthalpieImplementierungDienst <Informatik>Physikalisches SystemAbstraktionsebeneEntwurfsmusterMusterspracheWrapper <Programmierung>Notebook-ComputerDateiformatPortabilitätDifferenteStrukturierte AnalyseFaktor <Algebra>BitCASE <Informatik>Anpassung <Mathematik>Formale SpracheQuaderVarianzSoftwareentwicklerProdukt <Mathematik>Graphische BenutzeroberflächeCharakteristisches PolynomComputeranimation
ImplementierungAbstraktionsebeneBridge <Kommunikationstechnik>Interface <Schaltung>OISCOpen SourceTelekommunikationKlasse <Mathematik>Personal Area NetworkOktaederSehne <Geometrie>AggregatzustandProzess <Informatik>Dean-ZahlStrategisches SpielKontextbezogenes SystemSichtenkonzeptKategorie <Mathematik>AbstraktionsebeneLeistung <Physik>ImplementierungTelekommunikationSpezifisches VolumenBridge <Kommunikationstechnik>AdditionMAPInterface <Schaltung>DatenkompressionMusterspracheFokalpunktExogene VariableEntwurfsmusterLaufzeitfehlerPopup-FensterZahlenbereichObjekt <Kategorie>TypentheorieDatenbankPortabilitätHochdruckDifferenteDatenstrukturFernwartungEchtzeitsystemSoftwareentwicklerApp <Programm>Mathematische LogikAggregatzustandMailing-ListeE-MailKartesische KoordinatenClientStrategisches SpielProzess <Informatik>AlgorithmusKontextbezogenes SystemFamilie <Mathematik>Klasse <Mathematik>Luenberger-BeobachterMathematikCodeModelltheorieEreignishorizontPhysikalisches SystemGraphische BenutzeroberflächeCharakteristisches PolynomCASE <Informatik>PlastikkarteNichtlinearer OperatorParametersystemSchnittmengeLoopStochastische AbhängigkeitRegelkreisComputeranimation
MultiplikationsoperatorMusterspracheKartesische KoordinatenEntwurfsmusterFaktor <Algebra>PufferüberlaufVorlesung/KonferenzBesprechung/Interview
MultiplikationsoperatorEntwurfsmusterEinsLesezeichen <Internet>GruppenoperationKontrollstrukturMusterspracheImplementierungVorlesung/Konferenz
Besprechung/InterviewComputeranimation
Transkript: Englisch(automatisch erzeugt)
So hello, and welcome everyone to this talk about the design patterns. So I didn't expect that too many people will come here to this talk. And this is my first talk on the big conference like this, so bear with me, please.
Okay, so let's start with a simple question, what are design patterns? And one does not simply explain design patterns without introducing the gang of four. So who is actually the gang of four? So those are the four authors of the book written about 30 years ago, with the name
design patterns element of reusable object-oriented software, which is like the bible of design patterns. But what design patterns are? So design patterns are the standard solutions to the common problems in the software design.
So they represent the best practices that developers have refined over the time, and offering the proven way to tackle reocurring solutions for such a design. So what is the purpose for the design patterns?
Firstly, design patterns enhance code readability. So by using the well-known patterns, we create a common language which the experienced developers understand, and this is kind of the shared vocabulary which makes it easier to teams to communicate ideas clearly and quickly.
And when the developer sees the familiar pattern, they immediately understand and see the purpose of the code, which is reducing the time needed for the understanding. Secondly, the design patterns promote code reuse. So patterns provide kind of the templates or the blueprints for solving specific problems,
which means you don't have to reinvent the wheel all the time, you face a similar challenge or the issue. So by reusing the well-defined patterns, we can leverage some pre-tested solutions
and saving time and reducing the errors during the implementation. So this reuse leads to four more efficient code development processes and helps maintain the consistency across different parts of the application. And last but not least, the design patterns improve the maintainability.
So well-structured code is easier to debug, extend, and modify. Patterns encourage developers to think about the bigger picture and design systems that are flexible and adaptable. In summary, design patterns are an invaluable tool in the developer's toolkit.
They provide standard solutions that enhance code readability, promote reuse, and improve maintainability. So we have three categories or types of the design patterns. So the first is the creation of patterns. These patterns focus on the object creation mechanism.
As an example of this design patterns category can be singleton, factory, or the builder design pattern. Secondly, we have the structural patterns. Those deal with the object composition. As an example, it can be adapter, bridge, or facet. And last but not least, we have behavioral patterns.
Those focus on the object interactions and the responsibility. Let's dive a little bit into the creation of patterns. And here we have some characteristic of this category. So they abstract the instantiation process and making systems independent of the object
creation, composition, and representation. They use inheritance to vary the instantiated class or delegate instantiation to another object. These patterns offer flexibility in determining well, you know, what gets created, who creates
it, how it's created, and when it's created. And they also encapsulate and hiding the knowledge of the concrete classes used and provide the creation and assembly process of these instances.
Let's start with one of the most common design pattern belongs to this category which is a singleton. So what's the purpose of the singleton design pattern? It ensures that the class has only one single instance and provide the global point of access to that instance. Where we can use such design patterns, let's say we have some resource management where
we have, for example, the database connection, what was the previous talk about. And we need to have the single connection open all the time for the whole application. So we can use the singleton here.
Or let's say configuration setting where we have one single object by the whole application where we can access our configuration values. Or it can be used in the logging when the single logger is used by the multiple components of our application. So let's have a look at the structure of the singleton design pattern.
So as you can see under number one, we have the singleton class which holds the reference to the instance itself. And it has some get instance method which you can imagine is a method where we are checking
if the instance already exists. If not, we are creating it. And if it exists, we just continue to return that value. I wanted to mention that I used this illustration from the refactoring.guru which I really recommend you to check out. It's a really, really good source for the design patterns.
So let's have a look at some Python example how to implement the singleton. So you can see we have a singleton class which has the attribute underscore instance which is set to the none by default. And we have overwritten the new method for the creation of our instance where we are
checking if the class already has the instance. If not, it's creating it and then returning back to the user. And as an example of the usage, you see we are creating singleton one and singleton
two and then we do some comparison, we see that it's the same object. I just wanted to mention that it was also on the previous slide. When you use threading in your application, you should handle the locking here because otherwise you can get to the situation that these two objects will be different.
Second design pattern of this creation design patterns category can be abstract factory. This provides an interface for creating the families of the related dependent object without specifying their concrete classes.
It's ideal for a system that needs to be independent of how their products are created. As an example, it can be UI frameworks supporting multiple teams or UI components or different teaming libraries and manufacturing systems and so on.
So if we have a look at the structure of this design pattern, so on the left side you see we have some product interface defined. This is kind of a blueprint which defines what all products should look like and any product created by the system should follow this kind of blueprint.
Then above and below under the number two, you see we have some concrete products. So those are the actual products that are created and each of these following the product interface but differing in the specific details.
Then in the middle you see we have the abstract factory class or the creator class. This class has a method for creating products and this product method written the type which is matching the actual product interface.
The creator class focuses on the business logic and the factory method helps to separate the logic from the details of the creating specific products. And then under number four, above and below, you see we have some concrete creators.
These subclasses of the creator class provide their own specific way of the creating of these specific products. And then you can see on the number five on the right side, we have the client code. The client code remains flexible and independent of the specific product variants as it communicates with the objects via the abstract interface.
If we have a look at an example in the Python code, you see we have some abstract UI objects like the button and the checkbox.
Then we can have some concrete implementation of these objects like the Linux button and Linux checkbox and for the Windows we have the Windows button and Windows checkbox. Then we define some abstract factory which is called let's say GUI factory
which defines our abstraction for the creation of these objects like the create button and create checkbox. And then we have the concrete factories which actually follows this interface of the abstract factory which is called let's say Linux GUI factory and the Windows GUI factory which creates these objects buttons
in that specific way creating that specific concrete product like Linux button, Linux checkbox, Windows button and Windows checkbox. And then we have some client code. Let's say we have the create GUI method or the function
and it takes the factory as a parameter. So then we are creating the button and checkbox object just by calling the factory create button which is already well-defined interface which your client understand and expect. And then on the right runtime of the application you see we don't know the operating system.
We are checking what's currently running platform. If it's Linux we are setting the factory let's say for the Linux GUI factory and then using that specific factory or the Windows if you are running on the Windows
and creating the instances of our button and checkbox object via our create GUI function. So the second category of the patterns are the structural patterns. So the structural patterns have some characteristics like the composition.
So those patterns emphasize how object and classes can be combined to form a larger more complex structure. Interface simplification, structural patterns often focus on the defining straightforward
and efficient interface for the complex subsystem and this makes the interaction more manageable. And flexibility and extensibility, they provide a mechanism to extend existing structures without altering their original code, thus supporting the open-close principle.
And of course encapsulation and abstraction. This pattern encapsulates detailed implementation and abstracts the interactions. So let's have a look at the first design pattern from this category
of the structural design patterns which can be adapted or which is adapted. The adapter design patterns allow the object with incompatible interface to work together by providing something called a wrapper. It's converting the interface of a class into another interface that client expects.
Imagine you are traveling abroad and from the US to Europe and you have a charger for your laptop. So then you cannot probably connect it directly to our electronic outlet here. So you need to have some middle guy, the adapter,
so which is basically the same principle here. As an example where we can use this pattern can be the integrating the legacy code with the new system or when we need to working with the different data formats or again some cross-platform development. So if we have a look at the structure of the design pattern,
so we have client under the number one which is the code that uses the client or the target interface to interact with the objects and it remains unaware of the specific implementation details of the adaptee and the adapter.
So then under number two we have a client or target interface. It defines the interface expected by the client which the client understands too. It represents the set of the operations that the client code can use.
And then on the right side you see we have the service. This service can be called also the adaptee and which can be the existing class or the system with some incompatible interface that we need to integrate to our new system.
And then in the middle we have that mentioned adapter. Adapter is a class that implements the client target interface which a client understand and internally uses an instance of the adaptee to make it compatible with the client target interface. So let's have some example how it can use.
So we have some user as a client and we have some printer interface. So user would like to probably print something, some data. Then we have some adaptees which can be let's say laser printer or the inject printer.
And then we need to make the client to be able to communicate to those two different printers. So let's say we define the laser printer adapter which has a reference to the laser printer and speak with the same language, the client interface
which is well defined and calling its method print data. This print data method can do something to prepare the data for the laser printer and then call the print laser method from the object of the laser printer. If we have a look to this example written in the Python code,
you can see we have some adaptee like the inject printer and the laser printer. Each of these have the different methods like the print inject, print laser and doing something, printing. And we have some target interface for a printer.
So you see this printer interface has a well-known method by the client, print document and it needs to be implemented by any other concrete adapter. Let's say we have the inject printer adapter which has a reference to that specific object of our adaptee, in this case inject printer.
Then it implements the print document and doing some magic with the data for example to prepare it for the inject printer and calling the print inject method, sending the data in the right format for the printer.
And the same we can do a little bit differently for the laser printer. Okay. If we have a look at the client code, how it can be used. So we have some user which needs to know about the specific printer which needs to use,
which is in our case will be our adapter and it will just call the print document on that adapter. And that's it. So in the example you see we need to make an object of our printer's adapter and then just use it.
Another design pattern from this category can be the bridge design patterns. So some basic characteristic of the bridge design patterns, it separates an object abstraction from its implementation so that they can vary independently.
It's useful when both of the abstraction and the implementation needs to be extensible independently. As an example, it can be used again in some cross-platform development or let's say again, some example from the database abstraction where we need to support the communication
to different type of the databases let's say or some device control systems. If we have a look at the structure of the bridge design pattern, you see we have the definition on the number one of our abstraction,
which has a reference to our specific implementation and it provides some features, feature one, feature two. Then we have some specific implementation which is a different method, method one, method two, method three and then the number three so you see
that we can have specific concrete implementation. And under the number four, we can even have refined abstraction which provides some additional feature. So let's have a look at some example of the let's say remote control
and that we need to let's say communicate with some devices. So as our abstraction can be the remote control and it holds the reference to our specific device and it has some features like the toggle power, the red button on the remote control which turn on or turn off the TV for example,
volume up and volume down. Then we have some interface for the device which implements own method how to do the things like the power on, power off, set volume to some specific level and so on. Then we have the concrete implementation like the TV or the radio
and then we can have some advanced remote control which provides some additional feature let's say mute button which if you press that it will call on that specific device the method from the device which will be
for example set volume to zero. So last category of design patterns are the behavioral patterns. Those define the patterns of the communication between objects. Those focus on how objects interact and distribute responsibilities.
It encapsulates the behavior in classes and promoting the flexibility and traceability. It also facilitates the changes in behavior without need of the altering of the existing code. So as an example of this design pattern category behavioral,
so we can have the for example observer. It defines one too many dependency between the objects so that one object if it change its state all its dependents are notified and updated automatically. So it's used in the implementing event handling system mostly where a change
of the state of a model notifies and updates the other objects. As an example it can be used in some event handling pre-applications or real-time data feed systems or the logging and monitoring systems.
As a structure of this design patterns you see under number one we have some publisher which holds the list of our subscribers and it has its own main state. And then it provides some method for the subscribing or unsubscribing
and then have some notified subscriber methods and some other main business logic. So then under number three you see we have some well-defined interface for the subscribers which the subscriber understand and needs to implement.
So under number four or five you see we have some concrete subscribers definition. Let's say imagine the application which needs to notify its user it can be via email so it can be one kind of the subscriber or if we have a mobile application it can be the pop-up window
which will appear in our cell phone. And if the change or if the state will change of the publisher then you can imagine under number two that we basically loop over the subscribers
and calling the update method which is a well-known defined interface which each of the subscriber needs to implement in its own way and providing some reference to the publisher which holds some data which the subscriber can use.
And last design pattern is strategy. It defines a family of algorithm which encapsulates each one and makes them interchangeable. So this allows the algorithm to worry independently from the clients that use it.
And one of the use case it can be used in the payment processing system where different payment methods like the credit card or PayPal can be selected and interchanged at the runtime without altering the client code.
So another example of the usage can be the sorting algorithm. For example, when the user needs to pick up a specific algorithm to sort the data or the compression algorithm which user can pick if it will using the zip or the gzip or the tar or whatever.
And if we have a look at the structure of the strategy design pattern you see under number one we have some context which again holds some reference to our specific strategy and has some method like the set strategy
and then can do some operation with the do something method. Then on the right side you see we have the strategy interface defined which has the execute method and taking the data as argument. And then we have some concrete implementation of the strategy
as we mentioned already the payment system. So it can be let's say pay by card or pay by PayPal or pay by Bitcoin. And then we have the client which basically setting our context and setting the specific strategy there and calling to something operation
which at the end calling the execute method passing the data which the strategy should understand and do the operation for us. Yeah, and that's it. So thank you very much.
Yeah, thank you, Peter. Actually, we have a little time for a Q&A. I'm sure a topic like this invites many questions. There are many people here in this overflow room. Does anybody have a question and want to step up towards the microphone?
Don't be shy. Many people here. Of course, obvious question is do you have something like a favorite pattern that you like to use all the time? I think it's mostly single tone or the factory method. Not that abstract factory but you can evolve
by using the factory method to the abstract factory later on as well. So those are like the most common which I'm using. But yeah, I think that it's good to know about these design patterns in general. And if you are developing the application then you see some,
you know, problem which you already maybe saw was tackled in the design pattern to have a look to concrete implementation and to use it. Yeah, it's always the same. Of course, a favorite pattern doesn't really make sense, right? The pattern has its use and, you know. Okay. There are no questions. I think people are just shy to ask.
Would you be available for some like small group discussion? Maybe we can switch it for a few minutes. You can continue here. I'm sure there are some people. And you have your contact here. You can also as a reminder for those of you, even for the ones who are remote, ask questions in the channel for this room
which is Terrace 2A. And I'm sure you will probably at least take some time to read there today if there are questions. All right. Let's ask a speaker again. Thank you.