"Resisting Complexity" - Adam Wathan - Laracon US 2018

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

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

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

    Adam Wathan , You are a Genius!!!

  • @FabioIngrasciotta
    @FabioIngrasciotta 4 года назад +1

    One of the best talks I have ever watched about OOP. Thank you a lot Adam!

  • @ruslansteiger
    @ruslansteiger 6 лет назад +3

    Great talk Adam. You are generating fantastic content. You are a real gift to this world 🔥

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

    Thank you Adam. This was very insightful

  • @HrayrArtunyan
    @HrayrArtunyan 6 лет назад +1

    Adam, I loved this talk. It's entertaining and applicable no matter what language you use.

  • @Laflamablanca969
    @Laflamablanca969 3 года назад

    What a brilliant video. Thanks

  • @stephandevries5069
    @stephandevries5069 4 года назад +5

    So how do you deal with littering your model with these methods? I like my models to be concise and have a clear overview of their relationships. Do you just stuff these methods into traits instead of having them in the services you have before?

    • @MrShnaiderTV
      @MrShnaiderTV 6 месяцев назад

      Personally, I solved this problem this way. I leave only relationships in the model, only what is related to the database. I wrap the model itself in my own class, and use the methods already on it. For example, I hide the `User` model behind the `UserEntity` class, and call methods like `save` or `authorize` already on `UserEntity`

  • @uxweb
    @uxweb 6 лет назад

    Thanks for uploading your talk Adam. I've waited some time to watch it again!

  • @FabioIngrasciotta
    @FabioIngrasciotta 6 лет назад +2

    nice talk!. I believe it is basically related to "Tell don't ask" and to the "anemic" models problem

  • @tdwesten
    @tdwesten 11 месяцев назад

    Thanks for sharing.

  • @lvlupdev
    @lvlupdev 6 лет назад +6

    Ok, looks like I've got some refactoring to do. WELL, THANK YOU, ADAM.

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

    Watching this while coding and ending a class name with Strategy.

  • @ravibastola5582
    @ravibastola5582 6 лет назад

    thank you adam for the idea.

  • @miggiforeignlander8606
    @miggiforeignlander8606 6 лет назад +2

    Wow. Definetely gonna use this technique. Thanks, Adam

  • @rohitshirke98
    @rohitshirke98 6 лет назад +1

    Absolutely loved your talk.. that artisan command use... I really do it with controllers command though. 😅

  • @catalinstefanovici
    @catalinstefanovici 6 лет назад

    Fantastic job Adam!

  • @CyanidePierce90
    @CyanidePierce90 4 года назад

    Just thinking about this, how would you work printing or emailing a list?
    Say you have a statement that could be emailed or printed off.
    Email::($statement, $recipients);
    Print::($statement);
    or
    $statement->email($recipients);
    $statement->print();
    So often I get caught running this sort of logic in the controller because of the view data needing passed through.
    $statement = $statement->getDetails($dateRange, ....);
    if ($format == 'print') {
    // build print code
    } elseif ($format == 'email') {
    // build email code
    }

  • @mdkawsarislamyeasin4040
    @mdkawsarislamyeasin4040 3 года назад

    🖤🖤🖤

  • @loverboy260
    @loverboy260 6 лет назад +1

    i wonder how you would turn a service into this.. for example when I create a product, i might be adding prices (separate table), images, product variants.. and so putting it all into MODEL product doesnt feel great?

    • @AdamWathan
      @AdamWathan  6 лет назад +2

      I often create "Form Objects" for this sort of thing, as typically all of that data is coming as a single form submission from the user and needs to be split out to multiple models on the backend. So maybe something like (new NewProductForm($request))->save().

    • @loverboy260
      @loverboy260 6 лет назад

      thanks for the quick reply :) that does make sense..

  • @ProgrammingwithPeter
    @ProgrammingwithPeter 5 лет назад +1

    Your talks make me smile and absorb info, wannabe model!

  • @EminiArtsStGallen
    @EminiArtsStGallen 6 лет назад

    Thank you very much. I like your talk very much and it makes me think about my own code. Definitely going to think more about my code in this way. What I'd do differently: I would directly use the LicenenseCode::generate() method instead of calling an invokable class in the LicenseCode class... this is where I would simplify it one more step. Besides that, brilliant talk!

    • @AdamWathan
      @AdamWathan  6 лет назад +4

      Thanks! The only issue with just using that method directly is that you couldn't bind a different implementation to the container for tests, so you are back to the exact same scenario as if you had just used `str_random(32)` directly.

  • @ahallock
    @ahallock 5 лет назад

    The fundamental problem, in my opinion, is conflating real-world objects with software "objects." This is why I moved to a more functional approach, where data and data flows are more central to the architecture than objects sending each other messages. Also, stateful objects are a nightmare and OOP encourages state mutation. If you don't think state is hard to manage, think about why frameworks like React came about and also the easiest way to fix systems is to restart them.

    • @ahallock
      @ahallock 5 лет назад

      As an example, look at how Elixir's core modules are organized. You have domains with functions basically, so you don't need to worry about OOP gymnastics. For the split example in the beginning of the talk, Elixir has `String.split("foo bar")` which just means, for the domain of Strings there's a function split which operates a string data. This is inline with affordances, but expressed in a much simpler way, IMO. For plants, Plant.water(%PlantStruct{})` .

  • @Mrxr00t
    @Mrxr00t 6 лет назад

    Great work adam.:+1 For me I prefer to dispatch events using the event helper function event(new EventName)

  • @ricardo.fontanelli
    @ricardo.fontanelli 6 лет назад

    Thanks for share!!

  • @delamberty
    @delamberty 6 лет назад

    Nice presentation, What do you use to prepare your deck?

  • @gustavovasquezveliz7046
    @gustavovasquezveliz7046 4 года назад

    is this code example in github?

  • @mikeziri
    @mikeziri 6 лет назад

    good insights!

  • @johnbox5540
    @johnbox5540 4 года назад

    why dhh --> cause its a great gif LOL

  • @B4nks
    @B4nks 5 лет назад +1

    I think why Adam is taking heat is when he's making jokes about the "Service" classes. I think the take away from this talk was to promote encapsulation. "Service classes" are still necessary to perform many of the decisions about what your app should be doing when there is no active Actor.
    Personally, I don't call those classes "Service" classes any longer, but rather Tasks. Where now a service dictates external activity.

    • @QueeeeenZ
      @QueeeeenZ 3 года назад

      Can you give an example of this?

  • @roniestein
    @roniestein 6 лет назад

    Sweet!

  • @quochandinh3993
    @quochandinh3993 6 лет назад

    Wonderful talk!

  • @esnunes
    @esnunes 6 лет назад +1

    In my opinion there is a better way to design the Gardener + Plant relationship ( gist.github.com/esnunes/f0e16b83511355b4cc7a89b4ed9f286a ). IHMO the methods of a model should be responsible only to change or retrieve the model state. Another class should be created to implement the irrigation feature.
    I also disagree with the idea of changing model state + dispatching a job in a model's method, it compromises the Single Responsibility Principle.
    I totally discourage people to directly access Laravel's container as well as using stateful Facades (Queue is going to push the job to a Redis/SQS/etc, it has a side-effect), they end up hiding dependencies. You should be able to write a test to a method without knowing its internals, the knowledge about the input, output and business logic should be enough, that's clean code.
    Last but not least, if you are going to create one method for each action that is related to the model, you are going to end up with god objects for every model that plays in important / central role in your application.

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

    I dunno. I feel like you're un-factoring. Why do people not like objects?

  • @KubeckiOfficial
    @KubeckiOfficial 6 лет назад +12

    I thought you were better than this, Adam. These are some terrible ideas delivered in a nice way - truly terrifying.

    • @jryd13
      @jryd13 6 лет назад +4

      How is this terrible? Adam spent the time to explain his POV, least you can do is justify yours.

    • @KubeckiOfficial
      @KubeckiOfficial 6 лет назад +11

      I knew I'd regret that comment. But fair enough - here's the justification of my point of view.
      1. I agree that creating a gardener object for the purpose of watering a plant seems unfortunate but the solution proposed by Adam makes the design rather worse. A plant should have no notion of performing the process of watering. A plant needs watering but it cannot water itself.
      2. Talking about promoting encapsulation in one second, and in the next acting on a class through public properties is hypocrisy (acting itself isn't a violation but having them public in the first place is.)
      3. Talking about violating basic design principles with a funny voice doesn't make things any better - it's pathetic.
      4. Again, I agree that a PurchaseFullfillerService class with a purchase method is ugly but the way Adam reverses the dependencies there makes things worse. Ironically, the next talk on this playlist is from Bob Martin (also from Laracon!,) the author of Clean Architecture (and few others,) where he explains in detail practices, patterns, and principles, witch Adam so lightly violates in his talk.
      5. If you need a function, why not just create a function instead of a class with an invoke method? Adam's argument for easier namespacing is incorrect - you can namespace functions exactly like you would classes.
      6. Another hypocrisy in this talk is how Adam talks about conquering god objects while having explicit calls to a service locator in his code - the biggest god object of them all. Not to mention that incorrectly reversing dependencies is exactly how you would end up with god objects in the first place.
      I'm not trying to convince anyone here, just felt responsible for justifying my criticism. However, I do suggest to everyone to try looking beyond laravel (and maybe even php,) and be more critical about the things you are told from a stage.

    • @KubeckiOfficial
      @KubeckiOfficial 6 лет назад

      In case you're seeing a different playlist than I am, I meant this in point 4: ruclips.net/video/NeXQEJNWO5w/видео.html

    • @AdamWathan
      @AdamWathan  6 лет назад +11

      Should an array have the notion of reversing? A string the notion of splitting? A date the notion of formatting? This is OO 101 man, behavior belongs with the data it acts on. An object having a method doesn't mean we are saying that "a plant can water itself", we're saying "a plant can be watered".
      Here's another article for you to read: verraes.net/2014/09/objects-as-contracts-for-behaviour/

    • @thecrypticace
      @thecrypticace 6 лет назад +10

      If I may, I see this comment a lot: "…it cannot X itself”
      This is a misinterpretation of OOP. $object->action() does *not* mean that the object is performing the action. It means that an action is being performed where the object is available to it as one of the parameters (in this case, implicitly $this). This is why Adam says methods are affordances and not abilities.
      Also, this statement violates the message-passing intention of OOP. It implies that methods on an object can only access or modify internal state OR act on state of another object. In addition to breaking encapsulation, this notion requires the creation of do-er objects to perform any action in an application. Do-er objects should only be created when either your domain requires them or when it can actively produce cleaner, more manageable code. And in such cases methods should be added to objects that delegate to the do-er objects. They're meant to hide complexity by grouping related code. Not introduce it.

  • @krak3436
    @krak3436 6 лет назад +10

    There were couple things done badly in this talk:
    - Author is trying to squeeze too many topics in really short time just to show off
    - Author is encouraging developers to depend on globally available state of framework comparing it with globally available libraries in PHP language. Why this is bad comparison? Mostly because frameworks code is changing more often than build-in php libraries which are proven to be more stable, additionally those libraries are stateless and facades in laravel are not.
    Couple more things as well but I am not getting paid here to fix the world...

    • @amcsi
      @amcsi 6 лет назад

      One of the points of the author was that built-in php libraries are more stateful than you think: 12:10
      But in any case I myself would want to avoid using facades in random classes or models when possible, and I don't agree with the style of which classes to put the methods on to accept which arguments; so I don't really agree in the things presented in the talk.

  •  6 лет назад +10

    This explains why Laravel users always make terrible code. You get taught it.

    • @IsaiahGamers
      @IsaiahGamers 6 лет назад +8

      How is it terrible? Explain

    • @TheCrispi97
      @TheCrispi97 6 лет назад +2

      Yes, please explain. I would be truly interested in downsides of the approach when it is used as discussed by Adam.

    • @gamehubby
      @gamehubby 6 лет назад

      How? Please enlighen us.

    • @martinbean
      @martinbean 6 лет назад +7

      Good to see it’s not just Stack Overflow you’re conceited and have a holier-than-thou attitude.

    • @QueeeeenZ
      @QueeeeenZ 3 года назад

      @Mārtiņš Tereško - please provide your counter-arguments then instead of saying it's all wrong.