C++ Weekly - Ep 373 - Design Patterns in "Modern" C++ (2023)

Sdílet
Vložit
  • čas přidán 28. 05. 2024
  • ☟☟ Awesome T-Shirts! Sponsors! Books! ☟☟
    Upcoming Workshop: Understanding Object Lifetime, C++ On Sea, July 2, 2024
    ► cpponsea.uk/2024/sessions/und...
    Upcoming Workshop: C++ Best Practices, NDC TechTown, Sept 9-10, 2024
    ► ndctechtown.com/workshops/c-b...
    Books to reference:
    * [C++ Software Design](amzn.to/3RgBJ7n) (from Klaus, mentioned in the video)
    * [Head First Design Patterns](amzn.to/3CQHKmS) (Java)
    * [Design Patterns](amzn.to/3QeoJhd) (Classic Gang-of-Four / Pre-ISO C++)
    * [Modern C++ Design](amzn.to/3AMShgj)
    * [Hands on Design Patterns with C++](amzn.to/3emBqcD)
    Discussion: github.com/lefticus/cpp_weekl...
    T-SHIRTS AVAILABLE!
    ► The best C++ T-Shirts anywhere! my-store-d16a2f.creator-sprin...
    WANT MORE JASON?
    ► My Training Classes: emptycrate.com/training.html
    ► Follow me on twitter: / lefticus
    SUPPORT THE CHANNEL
    ► Patreon: / lefticus
    ► Github Sponsors: github.com/sponsors/lefticus
    ► Paypal Donation: www.paypal.com/donate/?hosted...
    GET INVOLVED
    ► Video Idea List: github.com/lefticus/cpp_weekl...
    JASON'S BOOKS
    ► C++23 Best Practices
    Leanpub Ebook: leanpub.com/cpp23_best_practi...
    ► C++ Best Practices
    Amazon Paperback: amzn.to/3wpAU3Z
    Leanpub Ebook: leanpub.com/cppbestpractices
    JASON'S PUZZLE BOOKS
    ► Object Lifetime Puzzlers Book 1
    Amazon Paperback: amzn.to/3g6Ervj
    Leanpub Ebook: leanpub.com/objectlifetimepuz...
    ► Object Lifetime Puzzlers Book 2
    Amazon Paperback: amzn.to/3whdUDU
    Leanpub Ebook: leanpub.com/objectlifetimepuz...
    ► Object Lifetime Puzzlers Book 3
    Leanpub Ebook: leanpub.com/objectlifetimepuz...
    ► Copy and Reference Puzzlers Book 1
    Amazon Paperback: amzn.to/3g7ZVb9
    Leanpub Ebook: leanpub.com/copyandreferencep...
    ► Copy and Reference Puzzlers Book 2
    Amazon Paperback: amzn.to/3X1LOIx
    Leanpub Ebook: leanpub.com/copyandreferencep...
    ► Copy and Reference Puzzlers Book 3
    Leanpub Ebook: leanpub.com/copyandreferencep...
    ► OpCode Puzzlers Book 1
    Amazon Paperback: amzn.to/3KCNJg6
    Leanpub Ebook: leanpub.com/opcodepuzzlers_book1
    RECOMMENDED BOOKS
    ► Bjarne Stroustrup's A Tour of C++ (now with C++20/23!): amzn.to/3X4Wypr
    AWESOME PROJECTS
    ► The C++ Starter Project - Gets you started with Best Practices Quickly - github.com/cpp-best-practices...
    ► C++ Best Practices Forkable Coding Standards - github.com/cpp-best-practices...
    O'Reilly VIDEOS
    ► Inheritance and Polymorphism in C++ - www.oreilly.com/library/view/...
    ► Learning C++ Best Practices - www.oreilly.com/library/view/...
  • Věda a technologie

Komentáře • 51

  • @VincentZalzal
    @VincentZalzal Před rokem +12

    One thing to consider when implementing design patterns in C++ in my opinion: most patterns originates from OO languages and rely on inheritance, but it is often possible to implement them using type erasure instead, giving you an alternative implementation that doesn't require inheritance. You briefly touched on that in the video with your solution using std::function, but I wanted to emphasize this point, as sometimes, you don't have control over all classes involved.

  • @cppweekly
    @cppweekly  Před rokem +17

    The point of this video is to show two things 1) resources for books you might consider to research more about Design Patterns and 2) modern considerations for using Design Patterns in C++. I use Observer as the baseline example for these topics.
    Books to reference:
    * [C++ Software Design](amzn.to/3RgBJ7n) (From Klaus)
    * [Head First Design Patterns](amzn.to/3CQHKmS) (Java)
    * [Design Patterns](amzn.to/3QeoJhd) (Classic Gang-of-Four / Pre-ISO C++)
    * [Hands on Design Patterns with C++](amzn.to/3emBqcD)
    * [Modern C++ Design](amzn.to/3AMShgj)

  • @velho6298
    @velho6298 Před rokem +8

    Please do a follow up, I think there are many valuable perspectives on how to design modern C++ and these design patterns. There are many old implementations available perhaps not using the most modern implementations, perhaps not going into detail but rather some key take aways. Thanks!

    • @cppweekly
      @cppweekly  Před rokem +1

      It's simply too big of a topic. It would take the rest of my year to do an exhaustive look into the possibilities!

  • @TNothingFree
    @TNothingFree Před rokem +3

    Good episode!
    Implementing the observer pattern may be the easiest thing or the hardest thing you can ever do with your code.
    We use the infrastructure of ACE which implements the observer pattern in various ways.
    The most common observer pattern is actually a 1:N async loop which nowadays go by the name of "Event based system".
    The other common observer may use simple lambda or function bind to create a 1:1 subscription.
    ---
    Head first design patterns was my favorite book of all times to design patterns , recommended!
    ---
    Something I missed in the episode is talking about generics and how they can help us to mitigate some C++ issues.
    Like CRTP, or using C++ 20 concepts to mimic interface behavior.
    This can help us to create design patterns in a compiled time manner instead of relaying on virtual inheritance all the time.

  • @teenspirit1
    @teenspirit1 Před rokem +3

    My go-to pattern is signals + slots (or any pattern that uses queues/direct interchange to communicate between instances)
    decouples dependencies, decouples virtuals from ctors/dtors, overall fixes C++ in a good way. Wish we had something like that within the language.

  • @Omnifarious0
    @Omnifarious0 Před rokem +5

    I always end up using shared_ptr and weak_ptr with the Observer pattern in C++. There are specific cases where that might not be needed. But,, in most cases where that pattern would be useful, these tools are necessary to deal with lifetime issues.

    • @ChrisCarlos64
      @ChrisCarlos64 Před rokem +2

      I remember when learning about weak_ptr back when it was coming out, "Why would I use that?" Then when I saw a demo with it in the Observer pattern, it clicked and made sense. I too like to use them for Observer style patterns.

    • @ratgr
      @ratgr Před rokem

      I also do something like this, I add a shared control block with the functor/functors to be called, depending on the issue I either implement my own refcount or just embed 2 layers of shared_ptr

  • @nicholaskomsa1777
    @nicholaskomsa1777 Před 19 dny

    When I write performant cutting edge code, I use "OOP" less than I use "DOD". Fundamentally different hemispheres of code concepts.

  • @oracleoftroy
    @oracleoftroy Před rokem +12

    One piece of advice I like to stress is: if the best name for your class/function/whatever is the name of the pattern itself, double check that you actually want to be using that pattern or if you are just cramming it in for no real reason. I think design patterns are best when you use it to recognizing the shape a solution is taking, as that gives you a name to look up for design ideas and implementation trade-offs etc. But where the pattern is applicable, there is often a more domain specific name that captures the purpose of your code.
    For example, if you have an object that essentially creates queries for a database, usually this is not called a DatabaseQueryFactory, it's called a DatabaseConnection. It is an application of the factory pattern, but its purpose is to connect to a database and help you communicate with it through queries. It's pretty rare that the name of the pattern is the best name for your implementation of the pattern, and any instance of it ought to be regarded with suspicion. And this also helps to highlight times when a dependency should be inverted or other api changes, like maybe designing query functions that take a connection instead of hanging them off the connection object. By putting the pattern name in the implementation, you are committing yourself to the pattern you are using, not the problem you are actually trying to solve.

  • @jplflyer
    @jplflyer Před rokem

    Good episode. Thank you, Jason.

  • @VioletGiraffe
    @VioletGiraffe Před rokem +2

    I have written a signal / slot implementation that's been in production for years and heavily used in our commercial software. It's great and convenient (took some time to debug and optimize for multithreading, though).

    • @gregdee9085
      @gregdee9085 Před rokem

      Yeah ur last line is why signals/slots should be avoided,

    • @VioletGiraffe
      @VioletGiraffe Před rokem

      @@gregdee9085, nope.

  • @quentinquadrat9389
    @quentinquadrat9389 Před rokem +1

    The libc++ used in gtkmm (the GTK+ for C++) is small and easy to use.

  • @nextlifeonearth
    @nextlifeonearth Před rokem +2

    It also is worth mentioning that some fairly popular design patterns, or implementations thereof, should be avoided in most cases or have a better alternative that may be less known.
    For instance Boost's MSM state machine thingy in some metrics is worse than a state pattern with pure STL (inheritance or variant), but is still very popular though it's mostly superseded in practicality and performance by the SML proposal.
    That's one reason I'd like to see a comparison of some design patterns with pros and cons. Some of which may solve a problem in a way that we may not have thought of.
    Though I get you're no expert in those, neither am I, so I shouldn't be barking up the wrong tree. You already went above and beyond with this video for all I deserve.

  • @jonohiggs
    @jonohiggs Před rokem

    Slightly surprised it hasn't been mentioned already but this pattern is exactly what rxcpp deals with, and Kirk Shoop / Lewis Baker and some others have been working on the sender/reciever part of the executors proposal; tldr it is super complicated to get correct

  • @nicholaskomsa1777
    @nicholaskomsa1777 Před 18 dny

    so yeah, you can use patterns from networking server/client model for instance in #include which I did, and then a thread-safe message std::deque. Throw in some templates, job basically done. btw, these messages can also transverse the ol' internet.

  • @kyneticist
    @kyneticist Před rokem

    Apple's been a proponent of the Observer model for many years. They put in a lot of work to support it, I think a lot of that came from Steve's direction/influence and the initial development of OS X. My earliest memories of Objective-C are of technical talks addressing the use of the Observer model, specifically references, memory management and messaging. I like it, but it does seem to need to be used within an environment built very deliberately for it.

  • @broken_abi6973
    @broken_abi6973 Před rokem

    Thanks for not just converting an example of the observer pattern written in Java/C# to C++. There are already way too many observer pattern presentations, which don't consider the nuances of C++ object lifetimes.

  • @PaulMetalhero
    @PaulMetalhero Před rokem

    How about connection.add(sender, make_receiver(....))

    • @ajinkyakamat7053
      @ajinkyakamat7053 Před rokem

      That would cause use after free. Unless connection owns the receiver which is weird.

  • @peterfeatherstone9768

    GNURadio uses something similar to signals and slots.

  • @brucerosner3547
    @brucerosner3547 Před rokem

    Design pattern like things - meta patterns?

  • @eskevv446
    @eskevv446 Před rokem

    Would really like a modern short video on writing more readable c++. It shouldn't have to be so in depth, I'm thinking more of syntax and conventions. An opinionated video is fine coming from you.

    • @cppweekly
      @cppweekly  Před rokem

      I keep track of all topic requests here if you want to add yours: github.com/lefticus/cpp_weekly/issues/

  • @PedroOliveira-sl6nw
    @PedroOliveira-sl6nw Před rokem +15

    I totally understand why you are not going into Design Patterns but the video is all about the Observer (Signal/Slots) design pattern. The title is misleading.

    • @cppweekly
      @cppweekly  Před rokem +15

      My intention was to make the video about the C++ things you need to consider when implementing *any* design pattern, using Observer as the baseline example.

  • @BatManWayneCorp
    @BatManWayneCorp Před 6 měsíci

    Awww man, I came for the fish, not to learn how to fish 😂

  • @nacnud_
    @nacnud_ Před rokem

    Good video, but I think the name is misleading a bit. Shame you're not going to do a series though. Basic ground work is always good to put on show.

  • @dagoberttrump9290
    @dagoberttrump9290 Před rokem +1

    Am I too dumb or why do i need all this overhead just to register a callback? Can't you just throw a lambda at an object and have it registered to be called when an event happens? Basic dependency injection

    • @poetryflynn3712
      @poetryflynn3712 Před rokem +1

      Design patterns are classifications to prove to a teacher, academic, or business that they can have control over the tasks they need to do. They are completely worthless to anyone actually doing the job. They make far more problems than they actually solve.

    • @cppweekly
      @cppweekly  Před rokem +2

      Generally you cannot just "throw a lambda" at an object, no matter how much we'd like to, because you then have to have some way to store that lambda.
      If the types are known at construction time, then sure, and that's one of my examples.
      Generally speaking you end up wrapping that lambda in a "std::function" object, and now you've just implemented your own sender/receiver!

    • @dagoberttrump9290
      @dagoberttrump9290 Před rokem +1

      @@poetryflynn3712 I'm actually trending towards your view the more i program

    • @dagoberttrump9290
      @dagoberttrump9290 Před rokem +1

      @@cppweekly but assuming that the object has to keep state anyway and givem we know beforehand that we will need event dispatching, isn't it easier to just have std functions lying around in your object to catch the lambda? I'm just asking because my colleague suggested this to me and earlier in my days i actually built something quite alike myself, but the fact that the object relies on a non standard api just never felt right whereas stdfunction and lambdas can be assumed from any Api

    • @broken_abi6973
      @broken_abi6973 Před rokem

      @@poetryflynn3712 The observer pattern is used in production very often.

  • @JohnB5290
    @JohnB5290 Před rokem

    Probably this whole topic should be reflected on in view of Sean Parent's "no implicit data structures". Not sure what might come out of such an exercise.

  • @gregdee9085
    @gregdee9085 Před rokem

    Author's monolog at 11:00 is why signals/slots should be avoided, seriously unreliable architecture (pattern) not to mention debugging difficulty ( more proof of bad architecture). New doesnt mean better. Oh its banned in our shop.

  • @aloluk
    @aloluk Před rokem +1

    Eeeek, i've never heard Qt pronounce Cute before. Its always been 'q' 't'.

    • @cppweekly
      @cppweekly  Před rokem +1

      "cute" is the officially correct pronunciation en.wikipedia.org/wiki/Qt_(software)

  • @simonfarre4907
    @simonfarre4907 Před 9 měsíci

    For signals - isn't it better to just use raw pointers because the responsibility is so very clear, especially compared to other problems involving life times and ownership, i.e. one side is "handing off" something to another side (i.e. describing the ownership perfectly)? Why would one want to complicate that (and make it slower/worse), by using smart pointers?
    I guess I could see a use case where one connects and disconnects observers often, but as far as I know, this is generally frowned upon.

  • @nicholaskomsa1777
    @nicholaskomsa1777 Před 19 dny

    all of this seems outdated by instead using concepts of BOOST/STL/algorithms/lambdas/std::function/views. I don't know, I think this methodology that you use may be outdated.

  • @cgerman
    @cgerman Před rokem +1

    Recently I watched this video
    czcams.com/video/pSvSXBorw4A/video.html
    which claims that Rust is like 3 times faster than C++. This is a huge gap, I mean what, if I rewrite my program in Rust it will run 3 times faster? Maybe you would like to dig into what's going on here?

    • @cppweekly
      @cppweekly  Před rokem +10

      It's a cherry-picked case and possibly a flawed test based on other emails I have received on the topic.

    • @poetryflynn3712
      @poetryflynn3712 Před rokem +2

      As a further explanation - know that C++ has a complexity to the point that it's hard to learn how to squeeze out the speed. From what he showed in the video and what little I know of what he's actually doing, he uses a lot of the STL. Anyone with significant experience should know the STL is not particularly fast compared to what C++ can do - it offers a basic implementation that should work in most use cases, not necessarily the fastest option in every case.

    • @anon_y_mousse
      @anon_y_mousse Před rokem +1

      I like Dave, but that is a highly flawed test. Using the same design for each language would net zero differences in an ideal scenario, and as Rust generates code with LLVM, you can test this and prove that it can't possibly be faster than C or C++, at best it can be equal to, but never faster. This is the nature of compiled code when it's written like for like.

    • @gregdee9085
      @gregdee9085 Před rokem +1

      Perfect example of how much bs is out there now..