One of the best talks I have ever watched about OOP. Thank you a lot Adam!
@ruslansteiger5 жыл бұрын
Great talk Adam. You are generating fantastic content. You are a real gift to this world 🔥
@emstudios142 жыл бұрын
Adam Wathan , You are a Genius!!!
@reubenarinze44902 жыл бұрын
Thank you Adam. This was very insightful
@HrayrArtunyan5 жыл бұрын
Adam, I loved this talk. It's entertaining and applicable no matter what language you use.
@FabioIngrasciotta5 жыл бұрын
nice talk!. I believe it is basically related to "Tell don't ask" and to the "anemic" models problem
@uxweb5 жыл бұрын
Thanks for uploading your talk Adam. I've waited some time to watch it again!
@stephandevries50693 жыл бұрын
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?
@MrShnaiderTV3 ай бұрын
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`
@lvlupdev5 жыл бұрын
Ok, looks like I've got some refactoring to do. WELL, THANK YOU, ADAM.
@Laflamablanca9693 жыл бұрын
What a brilliant video. Thanks
@tdwesten8 ай бұрын
Thanks for sharing.
@miggiforeignlander86065 жыл бұрын
Wow. Definetely gonna use this technique. Thanks, Adam
@rohitshirke985 жыл бұрын
Absolutely loved your talk.. that artisan command use... I really do it with controllers command though. 😅
@MrFacePeck4 жыл бұрын
Watching this while coding and ending a class name with Strategy.
@catalinstefanovici5 жыл бұрын
Fantastic job Adam!
@ravibastola55825 жыл бұрын
thank you adam for the idea.
@ProgrammingwithPeter5 жыл бұрын
Your talks make me smile and absorb info, wannabe model!
@EminiArtsStGallen5 жыл бұрын
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!
@AdamWathan5 жыл бұрын
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.
@ahallock5 жыл бұрын
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.
@ahallock5 жыл бұрын
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{})` .
@CyanidePierce904 жыл бұрын
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 }
@Mrxr00t5 жыл бұрын
Great work adam.:+1 For me I prefer to dispatch events using the event helper function event(new EventName)
@ricardo.fontanelli5 жыл бұрын
Thanks for share!!
@loverboy2605 жыл бұрын
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?
@AdamWathan5 жыл бұрын
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().
@loverboy2605 жыл бұрын
thanks for the quick reply :) that does make sense..
@mikeziri5 жыл бұрын
good insights!
@mdkawsarislamyeasin40402 жыл бұрын
🖤🖤🖤
@esnunes5 жыл бұрын
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.
@quochandinh39935 жыл бұрын
Wonderful talk!
@roniestein5 жыл бұрын
Sweet!
@gustavovasquezveliz70464 жыл бұрын
is this code example in github?
@B4nks5 жыл бұрын
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.
@QueeeeenZ2 жыл бұрын
Can you give an example of this?
@delamberty5 жыл бұрын
Nice presentation, What do you use to prepare your deck?
@AdamWathan5 жыл бұрын
Just keynote!
@johnbox55404 жыл бұрын
why dhh --> cause its a great gif LOL
@beanboi789 Жыл бұрын
I dunno. I feel like you're un-factoring. Why do people not like objects?
@KubeckiOfficial5 жыл бұрын
I thought you were better than this, Adam. These are some terrible ideas delivered in a nice way - truly terrifying.
@jryd135 жыл бұрын
How is this terrible? Adam spent the time to explain his POV, least you can do is justify yours.
@KubeckiOfficial5 жыл бұрын
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.
@KubeckiOfficial5 жыл бұрын
In case you're seeing a different playlist than I am, I meant this in point 4: kzbin.info/www/bejne/hJa7gniAg7yCa9k
@AdamWathan5 жыл бұрын
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/
@thecrypticace5 жыл бұрын
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.
@krak34365 жыл бұрын
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...
@amcsi5 жыл бұрын
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.
5 жыл бұрын
This explains why Laravel users always make terrible code. You get taught it.
@IsaiahGamers5 жыл бұрын
How is it terrible? Explain
@TheCrispi975 жыл бұрын
Yes, please explain. I would be truly interested in downsides of the approach when it is used as discussed by Adam.
@gamehubby5 жыл бұрын
How? Please enlighen us.
@martinbean5 жыл бұрын
Good to see it’s not just Stack Overflow you’re conceited and have a holier-than-thou attitude.
@QueeeeenZ2 жыл бұрын
@Mārtiņš Tereško - please provide your counter-arguments then instead of saying it's all wrong.