Design Patterns: Facts and Misconceptions - Klaus Iglberger - CppCon 2021

Поделиться
HTML-код
  • Опубликовано: 7 ноя 2024

Комментарии • 30

  • @josephlunderville3195
    @josephlunderville3195 Год назад +2

    16:35 RAII does indeed deal with dependencies -- it helps to reduce the amount of explicit memory management code, which decouples all of your modules from the memory manager, which can be viewed as a module itself.
    This is more apparent when you have different memory managers, which is a situation most application developers aren't familiar with, but is apparent in e.g. embedded systems, OS development, or engine programming for games.

  • @oschonrock
    @oschonrock 2 года назад +12

    I like your talks more and more Klaus. Well done.

  • @Omnifarious0
    @Omnifarious0 2 года назад +17

    20:10 - The value of `make_unique` is that it gives you the ability to enforce a standard like "You may not use new.", which I think can greatly improve the way people write code. Too many people are taught to use new and pointers in ways that are very error-prone. And telling people to use make_unique adds some training wheels so people can be told to not use bare pointers or new at all and still be able to write code.
    I'm not convinced that having a category called "design patterns" and then kicking make_unique out of it is particularly helpful. But, I'll listen to the remainder of the talk and I may be proven wrong.
    Hmmm.... this is a good talk. Using make_unique as an example of an implementation detail so you can distinguish what a design pattern is isn't a bad idea. But it leaves people thinking that you've just beaten up on make_unique and that you shouldn't use it. If that was your intent, I disagree with you.
    OTOH, showing people how design patterns show up, and how they're a timeless concept is an excellent idea. And analyzing the standard C++ library for its use of various design patterns is a really good way to illustrate what a pattern is and why the idea of a pattern is useful.

    • @chandrasekharpbg
      @chandrasekharpbg 2 года назад +1

      Couldn't agree more.

    • @klausiglberger566
      @klausiglberger566 2 года назад +7

      Thanks for your comment. Just to clarify: I do not, in any way, intent to diminish the value of make_unique. It's high value is out of question and yes, you should use it! I just claim that it is not a design pattern, but an implementation pattern. Managing ownership is just not something that you deal with on the same level as managing dependencies. This is an important point that unfortunately too many people miss in the discussion about software design and design patterns.

  • @jatvarthur
    @jatvarthur 2 года назад +9

    Imo the main difference between Command and Strategy is that a Command usually has a STATE associated with it, as command parameters, and this state is stored alongside it, and used, Command never accepts parameters during execution. This specifically enables having undo. Actually, the example from the talk stores implicit state (number 10, the second operand) within the lambda. On the other hand, Strategy never has any state, as it represents a pure algorithm, and always accepts parameters during the call.
    In this sense we usually want to handle commands as objects, like storing them in the undo/redo list. And we hardly ever store strategies, as they represent a polymorphic function pointer.
    This example is actually a bit ambiguous, as in general there is no difference between “plus” and “plus 10”. We can safely say that both here are strategies.

    • @flisboac
      @flisboac 2 года назад +4

      There's nothing preventing a Strategy implementation from having a state.
      The difference between a Command and a Strategy is that a Strategy establishes a set of implementations, each being able to fulfill what the Strategy represents and is tasked to do. At a higher level, implementations are fully interchangeable.
      Whereas a Command is generally unique in its implementation (i.e. you can't replace a Command with another, even if they have the same interface, because conceptually they'll execute different operations, and the operations are somewhat relevant at the higher level). You can establish a base interface to define a minimal or common API for the Commands of your domain, but that doesn't mean they'll each execute the same conceptual command.

    • @MsHofmannsJut
      @MsHofmannsJut 2 года назад +1

      I'm a noobie, so correct me if I'm wrong, but a command seems local, specific to a request, while a strategy seems more global, a general practice associated with a type of request.
      Like different food delivery services. In the end, they do the same thing, deliver food, but some use bikes, some use cars.
      A command would say "deliver with car" or "deliver with bike" for each driver and each delivery; or pass it on to a driver who delivers with a specific type of vehicle.
      While a strategy would just say "deliver", and the "with car" and "with bike" will be implicit in the request, because it's been decided beforehand.
      So with command pattern, the client could ask what kind of delivery he might want.
      With the strategy pattern, the server decides on how they would carry out their function.

    • @ruslany28781
      @ruslany28781 Месяц назад

      Yes, exactly. Loved the talk. Just to your and other's points. For me, Command decouples what exactly needs to be done from when this will be done (action and time). For example, 'here what exactly needs to be done when a user pushes this button'. And Strategy is a way to decouple the dimensions of an algorithm or processing logic from each other and allow extending options for each dimension separately, e.g. ' you can save it to a file, memory, database, network, or to anything that has this interface'.
      So Command is 'detachable' and usually already fully configured, but Strategy is the way to configure actions. With 'for_each()' both examples are closer to strategies since the array and the function to apply is not packaged in a way that would allow it to execute at some other point in time.

  • @andreasfett6415
    @andreasfett6415 2 года назад +3

    Great talk. I share your opinion on the difference between design and implementation details. Nonetheless I do think the true merit of the GOF book was that it finally provided us with names for certain structures and concepts. They are widely known today - which is not the case for most of those that where coined afterwards. So I do not see any problem with calling std::make_unique a factory function. Yes, it's not design - but when we talk about an implementation detail the word also conveys its concept. And I find that very helpful. After all in a world where any sufficiently advanced program cannot be maintained by a single person alone anymore being able to efficiently communicate about code as well as design is crucial.

  • @yutubl
    @yutubl Год назад +3

    @29:05 Guideline "design pattern are neither limited to oop nor polymorphism": How many patterns might be invented before oop existed by who and where? I recognized oop iterator pattern as previous learned when calling a procedural implementation GetFirstFile, GetNextFile of Turbo Pascal Dos unit/modul/library.

  • @ultimatesoup
    @ultimatesoup 2 года назад +2

    I can't believe someone thought that design patterns are archaic....definitely wouldn't want to work on a team with that person.

  • @xealit
    @xealit 4 месяца назад

    I'd say the important part of the Factory pattern is in the top, the separation between the Product and the Creator. I.e. it is important that the Product is separated from the Creator, and each role is encapsulated. You do not have to construct some basic version of the Product, then check some status, then initialize the Product more, then check something else, etc. Yeah, sure, there is also the bottom part with the implementation detail. But, I'd say the important thing is to encapsulate the construction of not trivial objects, with not trivial invariants and relations/dependencies with the rest of the program.
    In this sense make_unique is just a simple case of Factory: it returns a Product with one specific additional feature, the unique_ptr-ness, which encapsulates the relation between the object lifetime and the runtime scopes. I'd say, it is an "implementation" pattern just because it does not deal with the _business logic_ aspect of the program. But, in principle, implementation also needs design.

  • @MrAbrazildo
    @MrAbrazildo 2 года назад

    6:45, yeah, I agree to that: 1 class may does many things towards only 1 goal; it may also has many f()s, 1 for each step. And yet each of those f()s can has many small technical internal steps. Of course, if the class goal has internal use cases, that some users would like taking them apart, it may should be split in other classes.
    11:00, it saves the user from 3 things: the 'new' keyword, which is less meaningful than 'make_unique'; saves from remembering to use () or [] _(according to Kate Gregory, a bug stood for years because of this)_ ; and it makes the std::forward for you. And all of this makes it a syntax sugar too.
    If you want good examples of bad practices, look for Java. There are plenty of those, like pseudo encapsulation, objects inside object, unnecessarily bloating it, and so on.
    16:25, it decouples the annoying task of _"I have to get rid of this (resource) before something" (typical of f()-languages like C)_ , from programmer's list of tasks, by blending it to something automatic, like the lifespan of an object. So if you have to do something, this task would be attached to it, but by using this pattern, you detached it. It's 1 thing less to worry about. If we take 'dependency' as something to deal with, it managed a dependency - _at least in the mind of its user_ . 17:10, same thing regarding to Singleton: it decouples another potential nightmare from the user, when appears another object of a critic class, like a hardware handler. It's infamous because of the way it uses to be put in practice, costing too much, from performance to its horrendous design - ok, it's creative at least.

  • @sevenbit
    @sevenbit 2 года назад

    Amazingly helpful! Now I know that what I implemented earlier today was a known design pattern since 1996 :)

    • @CppCon
      @CppCon  2 года назад +2

      Glad it was helpful!

  • @almightysapling
    @almightysapling Год назад +2

    I think you treated that comment unfairly. User didnt say "Design patterns in 2021?" They said "Design Patterns in 2021?" The capital P makes a huge difference. Are design patterns important? Yes. Should we have a more modern reference than "what we happened to notice in use in 1994?" Also yes.

  • @sjswitzer1
    @sjswitzer1 Год назад

    I submit that make_unique exists mostly in parallel with make_shared, which permits better memory organization and locality. Furthermore since neither unique nor shared pointers use delete, the odd appearance of new in only the construction of unique pointers is irregular. make_unique allows a regular pattern of “never” writing delete OR new manually, and that’s useful enough in itself.

  • @josephlunderville3195
    @josephlunderville3195 Год назад

    28:40 If you only look at the most bare-bones elements of the Command and Strategy patterns of course they will look very similar. The point made about intent is of course valid, but also I think to really understand what these patterns are getting at you have to look at prototypical implementations -- the Command, for example, typically carries a bunch of state which can be applied (or saved stat for undo), it is typically kept in a queue or sometimes tree, it has a relationship to its sibling commands (must be executed in order), etc. All of those properties are individually optional, but if you don't have any of them you haven't really captured the spirit and value of the pattern. Also, none of those properties are relevant to the Strategy pattern, which has its own set of typical properties (there should be multiple, they may carry some configuration state or none at all, etc).

  • @Chris-yw5is
    @Chris-yw5is 2 года назад +1

    Great talk!

  • @ocean_color
    @ocean_color 2 года назад +1

    Fascinating!!

  • @jhbonarius
    @jhbonarius 2 года назад +1

    I get the points. But imho according to the definition in the book "design patterns" by the four, make_unique would definitely be a factory method. The knowledge of creating a new unique_ptr object is encapsulated in it. It's much more object oriented focused in the old book, but the fundamental idea is the same.
    And while you might disagree that object creation methods are not factories, but I think you're fighting against windmills. Most programmers (at least in C++,c#, Java,etc) now use the name "factory" for object generation methods. That's the "new" consensus. Communication evolves over years.

    • @klausiglberger566
      @klausiglberger566 2 года назад +6

      Thanks for your comment. I get the impression that you misunderstood the point. Quoting the intent of the Factory Method design pattern from the GoF (emphasis is mine):
      Define an interface for creating an object, but "let subclasses decide which class to instantiate".
      Wikipedia expresses this similarly (again, emphasis is mine):
      The Factory Method design pattern solves problems like:
      * "How can an object be created so that subclasses can redefine which class to instantiate"?
      * How can a class defer instantiation to subclasses?
      Based on that I would argue that the Factory Method design pattern is all about enabling customization of the instantiation process (via subclasses or other means), not only about creating an object. Therefore make_unique is not a Factory Method.
      make_unique is a factory function, though, which is the common term used for functions that create objects. Please see Wikipedia for a short summary of the terminology: en.wikipedia.org/wiki/Factory_(object-oriented_programming)#Terminology. For that reason I don't think that I have to fight against windmills, but only help to remind developers about the established terminology.

  • @lefteriseleftheriades7381
    @lefteriseleftheriades7381 2 года назад

    It feels like the factory method as presented looks like an abstract factory and not a factory method

  • @Solarbonite
    @Solarbonite 2 года назад +2

    Really? Design patterns in 2022?
    Lol just kidding.
    I think it can get blurry especially when languages implement different features.
    I'm pretty sure templates or duck typing or delegates are what makes it difficult to distinguish from Command and Strategy patterns.
    In languages that don't or didn't have them before (cough cough Java's lambdas) these two were easy to distinguish.
    As soon as you have lambdas distinguishing becomes harder.
    Design patterns are relevant still, even though languages gain new features that make older patterns be seen less.
    Re singletons: they're probably not patterns as much as tools to replace a missing feature in a programming language.

  • @MrAbrazildo
    @MrAbrazildo 2 года назад

    I guess this whole talk was a waste of time. As long as I remember, all software discussions aim to solve a problem. Analysing patterns just to name things is pointless. It would be useful to reason about if "Should that pattern be replaced by that other?", "Isn't there a better solution for singleton?", and things like that, towards solving an issue.
    We could say that a software design pattern is a software strategy (a design proved in practice) to solve an issue, thus destined to be repeated throughout projects - thus becoming a pattern.

  • @Igor-Korablev
    @Igor-Korablev 2 года назад +1

    I have to admit when Mr. Igleberger suggests his own definition of Software Design he didn't state any goal of Software Design. There is no goal in his definition of Software Design making it useless. Then relying on this definition Mr. Igleberger proves that nothing fits his definition of Software Design. If anything good this lecture does it's prove that Mr. Igleberger definition of Software Design is just wrong.

    • @klausiglberger566
      @klausiglberger566 2 года назад +9

      Thanks for you comment. Since you don't agree with the definition, I would have hoped that you enlighten us with your definition. Would you please be so kind to do so?
      I get the impression that you define things the other way around: you seem to define make_unique as a design pattern, hence a definition of software design must include it. I would have hoped that you see the wisdom of distinguishing more clearly and more strongly between design patterns and implementation patterns.

  • @greob
    @greob 2 года назад +5

    Another excellent presentation. Klaus is such a great teacher!

    • @CppCon
      @CppCon  2 года назад

      Glad you think so!