Great video! Loved how every word was packed with meaning. Definitely worth a rewatch (or three) to catch everything. Thank you Zoran.
@goldmund67Ай бұрын
0:09 "This class is nothing in particular." ... Me, still after 25 years of OOP.
@delicious_seabassАй бұрын
It's because OOP is a terrible idea that needs to die.
@jeremychristman1515Ай бұрын
@delicious_seabass I think you missed the line before that where he said "this class is NOT object oriented"
@delicious_seabassАй бұрын
@@jeremychristman1515 I think you missed the part where he said "this class".
@zoran-horvatАй бұрын
@@delicious_seabass How would you approach explaining to a bigot that word "class" does not imply OOP in 2024?
@delicious_seabassАй бұрын
@@zoran-horvat Typical dogmatic reaction - take it personally. Your premise is wrong. In the context of programming languages, the word "class" does in fact imply OOP. Classes are the most fundamental part of OOP, as they're use to describe objects, and functions attached to classes, I mean what else is that if not OOP? Orienting your entire program around objects is just a dumb idea. Most things, especially in the abstract, don't map to objects, yet the language forces you to do so. That's why you have stupid concepts like a singleton class. I've done the whole OOP roundabout with C#, C++, and Java. It's a complete waste of time. Working with simple data structures and functions to operate on them is much easier to reason about and follow, and also makes the overall code much smaller.
@MaxonepieceАй бұрын
Hi Zoran, as always great video... what I have a hard time understanding when seeing these videos is how you make it work at the database level. It would be interesting to have this information to have a clearer model in mind. Thanks for all the work!
@zoran-horvatАй бұрын
@@Maxonepiece There are a few videos in recent time where I have shown mapping with EF Core and the corresponding database schema for this object model. More videos on EF Core are in preparation, covering queries, denormalization, and a few other topics.
@sebastianbusek2087Ай бұрын
Hi, excuse me, where are the links to the entire series? I can't find them in the description.
@zoran-horvatАй бұрын
I have added the list of videos to the description now. Thank you for drawing my attention to that!
@petrmalecik5661Ай бұрын
Wow, what a great video. Do you plan to create a course for OO modeling and also a Functional style modeling? Could you maybe recommend some books, which could help me get better with this? I already read Functional Programming in C# by Enrico Buonanno, is there a similar book for OOP design? Thank you :)
@zoran-horvatАй бұрын
@@petrmalecik5661 The best book on OOD I know of is the Object-oriented Software Construction by Bertrand Meyer.
@Cyber_LankaАй бұрын
Great video as always. Wish you all the best. I do have a question though. What's the goal of all of this complexity? I have been studying more functional and modern approaches and languages such as Go, and i find myself asking this question every day. What was the point of all those Java classes and C# i wrote in the past? It could have been much more simpler.
@zoran-horvatАй бұрын
@@Cyber_Lanka You would have all those types - and even more of them - in a functional model. You would also have all the functions defined as in this model, too. There is no complexity intrinsic to OO. It's only the question where the code is. In the corresponding FP model, the types would be defined in one place and each function possibly in its own file, or a few of the related ones together. Anyway, every single line of code I wrote in this demo would exist in a corresponding functional model.
@adambickford8720Ай бұрын
Agreed. The 'accidental' complexity of OOP often outweighs the essential complexity of the problem. The nice thing about records and functions is, they are obvious. Have a new requirement? Just implement it, no need to force it into some hierarchy/model that already exists. Or god forbid, have to change the entire model to accommodate the newly needed abstraction... with 1 current use case. The bar for good OOP is just too high in practice. (If you have a team of zoran level devs, any paradigm will work.)
@obinnaokafor6252Ай бұрын
Go is quite arcane and ugly, though
@kenji3955Ай бұрын
Thanks for the video. I do see benefits of doing this. However, somewhere between the client and these new interfaces, the if-else will still exist, because at some point, it must be decided which implementations of those interfaces to instantiate. My frequent solution is to wrap that into a factory, but maybe you have a better suggestion?
@zoran-horvatАй бұрын
@@kenji3955 If you are speaking about selecting a constructor, then such logic will only exist on the edges of the system where the model is constructed from the database or deserialized from a network request. Either way, it hardly warrants a factory, because those pieces of code are always one-off. Any other portion of code that plans to produce a polymorphic model instance would probably know precisely what it is producing.
@kenji395528 күн бұрын
@@zoran-horvat If the data is supplied via user input, then the function which processes the supplied data does not know, whether a day is missing or month and day and therefore does have to inspect it and select the appropriate constructor with a couple if-else statements. Still, you can now encapsulate that logic in such single function instead of spreading it everywhere, which is great.
@zoran-horvat28 күн бұрын
@kenji3955 That behavior belongs to the outer application layer, such as the UI. It is part of the input sanitation. No other part of the application should be affected by that, nor be aware that it exists.
@serviceengineАй бұрын
One line brought my attention. Is the "book.Publication.Relese". Why? There is a Law of Demeter that states more or less to talk with your neighbours only, but this would lead us to the square one and to polute the model with confusing "IsSomething" methods only to wrap the Publication.Release. I am wondering your opinion about the reasonable use of the law of Demeter and what might be the acceptable level of reaching the object inside the objects inside the object... For me, more than 3 looks suspicious
@zoran-horvatАй бұрын
@@serviceengine There is no law of Demeter. The code you have quoted here is in fact: var a = book.get_Publication(); var b = a.get_Release(); Any better this way? The law of Demeter was a fairly unsuccessful attempt at resolving the issues at the times when people massively neglected encapsulation. It was dead at the time of its release, so far as I know, because programming moved in a different direction entirely. Here, you are trying to apply it to property getters, forgetting that properties do not imply structure, let alone state.
@serviceengineАй бұрын
@zoran-horvat thank you. It made me think differently now. I learned once at the beginning of my path that reaching objects from other objects is bad practice. It is hard to maintain, debug, and read. Demeter was a great way to keep the code clean...then. Now it looks old-school and overuse sometimes. Appreciate it!
@juancarlospizarromendez3954Ай бұрын
how to get current date properly and put this current date for comparison at published and planned methods?
@funnyface487Ай бұрын
Hey Zoran! Really love your vids! I was wondering how would you deal with enforcing the usage of valid subtypes when creating the Published PublicationInfo. Let's say that the only valid IPartialDates for Published are FullDate and YearMonth. Is there a nice way to do that in C#? As an example, in typescript you could use Union Types.
@zoran-horvatАй бұрын
@@funnyface487 You can use marker interfaces, though that might look silly at times. You can also define two methods, each receiving one concrete class. Those could internally delegate to one private method with common logic.
@nickbarton319120 күн бұрын
Hold the phone, I didn't even know that you can write an implementation in an Interface. When did that happen?
@zoran-horvat20 күн бұрын
@@nickbarton3191 Default interface methods were introduced in C# 8. It is not such a prominent feature, since C# already has extension methods with similar purpose.
@nickbarton319120 күн бұрын
@zoran-horvat Our codebase started at C#3, now C#12. A fourfold performance improvement, doubled again on Linux, all with feature upgrades. Still working through the ball of mud, with the help of your videos.
@JonathanPeelАй бұрын
solutions to better OOP is very similar to solutions for better DDD. I don’t think this is a coincidence.
@funkdefied1Ай бұрын
Surely you mean “solutions,” right?
@JonathanPeelАй бұрын
@@funkdefied1 What did I say? 🤣 I have edited it.
@Robert-yw5msАй бұрын
That trick with the Func at the end feels almost (but not quite) monadic. I don't know how to explain what I mean. Edit: Actually I know what I mean. It's just that there's a map method which you usually have with monads. That's all.
@zoran-horvatАй бұрын
@@Robert-yw5ms That method *was* monadic, and implemented the Option monad needlessly specialized to that interface alone. So, your feelings were right.
@Robert-yw5msАй бұрын
@@zoran-horvat Aha of course! Funny (and not surprising) that a video about how to do OOP better ends up with FP components.
@goldmund67Ай бұрын
Further proof of the generally accepted theory that when you finally understand monads, you lose the ability to explain it to others!
@zoran-horvatАй бұрын
@@goldmund67 Why would you say so?
@xennox26824 күн бұрын
@zoran-horvat, it's a common meme stated in functional programming memes, which goes something like this: "The moment you finally understand what a monad is and how it is used, you lose the ability to explain the concept to someone else who is unfamiliar with the concept." The original poster, initially at least, couldn't explain why the subject appeared to be monadic in nature, hence the reference to the joke. Yes, I am fun at parties.
@luc9voltsАй бұрын
Neat !
@vincentcifello4435Ай бұрын
Calling this "more object oriented" while exposing a method to allow clients to inject functionality is odd and contradictory. Shoe-horning this into an object, apparently to make it appear "rich", directly led to the bizarre "do nothing" ProcessDate grafted on to NotPublished. Why not just embrace the fact that this problem is better solved with "types" and functions, not pseudo-encapsulated objects?
@zoran-horvatАй бұрын
@@vincentcifello4435 Funny enough, the Option monad also does nothing in the case of a None... Would you find that bizarre, too?
@HarleyPebleyАй бұрын
> directly led to the bizarre "do nothing" ProcessDate grafted on to NotPublished. Interesting. I didn't find this "bizarre" but a great example of the Null Object pattern.
@zoran-horvatАй бұрын
@@HarleyPebley That is another view of it. Thank you for reminding me of that.
@janhendrikschreierАй бұрын
Hey Zoran, Your video is automatically translated and the title displayed in German if your KZbin is German. Can you turn off the automatic translation? It is horrible: wrong translations and nowhere near your authentic tone. I know that I can turn it off but maybe not all your viewers do
@zoran-horvatАй бұрын
Thanks for this feedback. That is a new feature and I am still collecting the data about it.