Always Use Interfaces

  Рет қаралды 42,788

Christopher Okhravi

Christopher Okhravi

Күн бұрын

How to follow the principle of Couple To Abstractions, Not Concretions, and how to avoid tempting others to break the rule.
🎓 Get the book: geni.us/hNDE
Watch before: • The Only Time You Shou...
Watch next: • Depend on Abstractions...
FURTHER RECOMMENDED READING:
- geni.us/zzlx (Dependency Injection: Principles, Practices, and Patterns)
- geni.us/IBhtLnh (Clean Architecture)
- geni.us/k8KhT3 (Refactoring)
- geni.us/nlbA6 (Head First: Design Patterns)
00:00 Intro
00:26 The rule
01:10 Problem 1
02:29 Problem 2
03:44 Solution
05:33 Motivation
07:05 Summary

Пікірлер: 241
@judas1337
@judas1337 Ай бұрын
My issue is that I often fall for coupling to distractions.
@ChristopherOkhravi
@ChristopherOkhravi Ай бұрын
Underrated comment 😆😆
@clamhammer2463
@clamhammer2463 Ай бұрын
I snorted
@dripcode2600
@dripcode2600 Ай бұрын
Lol!
@bugtank
@bugtank Ай бұрын
my man
@sandyj342
@sandyj342 Ай бұрын
People are too eager to learn syntax and code...... but the "why" behind choices are not clear. You are giving clarity to the "why". Love your energy and presentation.
@ChristopherOkhravi
@ChristopherOkhravi Ай бұрын
Thank you for sharing your thoughts. Much appreciated. And thanks for watching 😊
@funkenjoyer
@funkenjoyer Ай бұрын
it's pretty hard to learn about abstractions before having any chance at learning about the concrete stuff, even in math you dont start with algebra but you count on your fingers, once you have some idea on what you're dealing with and possibly have encountered a number of problems/issues then learning about the abstract concepts and patterns makes sense
@timothy6966
@timothy6966 Ай бұрын
I missed you my man. I’ve grown quite a lot since your previous series.
@jsmunroe
@jsmunroe Ай бұрын
Keep growing. Get better and better and better. And most importantly have fun!
@artemvolsh387
@artemvolsh387 Ай бұрын
I'm so glad you're doing more content. Best simple explanations on compex topics.
@ChristopherOkhravi
@ChristopherOkhravi Ай бұрын
🙏🙏
@jason_v12345
@jason_v12345 Ай бұрын
The only thing is, please don't overengineer by defining an abstract interface when you only have one concrete type. All that does is obscure the names of your fields and methods unnecessarily and, by extension, what exactly it is each of them represents.
@adambickford8720
@adambickford8720 Ай бұрын
100%. Nothing more obnoxious than a code base of 1:1 `IFoo` and `FooImpl` everywhere. "Just in case" isn't free.
@silberwolfSR71
@silberwolfSR71 Ай бұрын
I agree that we should avoid over-engineering, but I don't think the number of concrete implementations should be the only thing we consider. Arguably just as important should be whether the type in question leaves our area of influence. If other modules/people/teams/products depend on our type, it can become quite unpleasant if that type is concrete and needs to change. Another thing to consider is that when other components depend on our type, and we want to test those components, we could argue that we have, in fact, more than 1 concrete type: the default, full implementation, and a stub we create to enable testing of the components that depend on it. I'm not sure how extracting an interface out of a concrete type obscures the names of its methods or what said methods represent. In fact it should communicate exactly that information precisely, while letting us ignore any unnecessary stuff like, for instance, names of fields (these should rarely be exposed to users of our type). In OOP, most types have behavior that defines them. If we share them around, we might as well explicitly declare that behavior in the form of a contract (interface) so that using the types is simple and consistent. One general exception are simple data objects that have no behavior: there's no need to hide those behind an interface, as there isn't much of a contract to speak of.
@adambickford8720
@adambickford8720 Ай бұрын
@@silberwolfSR71 Every level of indirection has a cost, they don't all bring value and certainly not by just existing.
@silberwolfSR71
@silberwolfSR71 Ай бұрын
@@adambickford8720I agree. I was trying to argue that the indirection of an extra interface can bring value even if there currently exists only one concrete implementation of said interface in the system. I also argued that the cost of this indirection is not as high as seems to be implied.
@jasonparker9957
@jasonparker9957 Ай бұрын
This comment should be pinned
@silberwolfSR71
@silberwolfSR71 Ай бұрын
I think one upside of having "always code to interfaces" as a rule of thumb is that it gives you an opportunity to stop and really think through the API of your component. It nudges you in the direction of creating useful abstractions rather than just code snippets. Of course, only sith deal in absolutes, and I think it's fine to sometimes code to plain old classes, especially if you did first think about extracting an interface and concluded that there's no value in doing so. To limit the "temptation" for other components to depend on this "raw" class, you can contain it using your language's component-level encapsulation facilities (e.g. make it package-private in Java). If you end up wanting to break that encapsulation, you might want to once again ask yourself if there's an abstraction asking to be born.
@AgodzillaFace98-yj5nq
@AgodzillaFace98-yj5nq Ай бұрын
That's the problem with this approach - you stop and you think. Might seem like a good idea, but not in reality. You might feel like abstraction lord, but neither you nor other people would understand it, and the problem would still not be addressed at that point
@silberwolfSR71
@silberwolfSR71 Ай бұрын
@@AgodzillaFace98-yj5nq I'm not completely sure what you're saying. My best guess is you claim that having to stop and think when _using_ your components is generally not good. If that is your point, I agree. We want to have neat components that are straight-forward to use and that have unsurprising behavior. I believe that having a think while designing them lends itself well to this goal. If you're instead implying that the act of thinking through the design of your components is inherently detrimental, as any solution you come up with is bound to be more complex and difficult to understand than your first impulse (e.g. a straight-forward class), then I disagree. Granted, at face value, class + interface seems more complicated than just class (though I'm skeptical of the difference in complexity warranting the claim that suddenly no one is able to understand the component). But ideally, only a very small number of components should care about both the interface and the class. For most components, all they care about is the interface, which I'll argue is much simpler than having to know about the full blown class and its implementation details. Moreover, one would hope that taking a moment to think will also steer you in the direction of the simple class, if that is in fact most appropriate for the given situation. If you don't believe that is the case, you should argue for _better_ thinking, not less. You say the problem would not be addressed by coding to interfaces. As I see it, there is more than one problem. One is a system that is difficult to change. Often this is the result of tight coupling between components, meaning if one component needs to change in order to meet changes in business requirements, many other components (that are not conceptually affected by the update in business rules) also need to change. Coding to interfaces, together with dependency injection, can help reduce this coupling, making change less painful. Say you have a few dozen components spread over several different modules that all depend on class C to do some work. Now your requirements state that for the components in one of the modules M, C should have different behavior. What you would likely do at this point, is create a new class C2 that functions in this new way, and then modify all the components of M that depended on C to use the new C2. If the components depended on an interface IC instead, none of the components would need to change, you'd simply wire up your dependencies in such a way that all components of M now get a C2 instead of a C. M's components shouldn't have to care that the IC they're getting is behaving differently, as long as it still adheres to the contract of an IC. Another problem is testability. If a component X depends on a class C, it is difficult to test X in isolation, because you can't substitute a dummy for C (without relying on reflection or similar hackery). Additionally, the behavior of X is tied to that of C. So you're really testing X(C) rather than just X. Now if C changes, your tests of X may need to change as well.
@Domi214
@Domi214 Ай бұрын
I just love how you explain things. Sometimes i used your design pattern videos over the GoF book, because they are just so good. Really love the new content you‘re creating 👏
@ChristopherOkhravi
@ChristopherOkhravi Ай бұрын
Really happy to hear that. Thank you for watching 😊🙏
@siddharthkothari007
@siddharthkothari007 Ай бұрын
awesome stuff Chris. thanks for making these videos.
@CezarWagenheimer
@CezarWagenheimer Ай бұрын
Awesome video, man! I'm a developer with over 25 years of experience, and your video still taught me a lot! Now I'll have to watch all of your videos! Thanks!
@fedor108
@fedor108 Ай бұрын
I'm so glad to see you again!
@marceloleoncaceres6826
@marceloleoncaceres6826 Ай бұрын
Thanks for the lesson,
@TheSilverGlow
@TheSilverGlow Ай бұрын
Wonderful videos, Christopher!!
@guilhermecampos8313
@guilhermecampos8313 Ай бұрын
The concept is very good, the lesson is very good... the way that the letters and icons where draw on the whiteboard...oh my! Its gorgeous!
@sachithra
@sachithra Ай бұрын
Its good to see you again, with great explanations.
@kkiimm009
@kkiimm009 Ай бұрын
If you do not find a good and obvious abstraction then it is better to keep it concrete. Bad abstractions are usually a much bigger pain to deal with than concrete classes. Just remember to inject your concrete class so it is easier if you need to change it in the future. (if you need to mock it in tests then you of course need to do whatever your language requires to be able to mock it.)
@ChristopherOkhravi
@ChristopherOkhravi Ай бұрын
100%. We agree. I like the Sandi Metz quote: Duplication is far cheaper than the wrong abstraction.
@zachomis
@zachomis Ай бұрын
Gold, instructive. Thank you for your time.
@ChristopherOkhravi
@ChristopherOkhravi Ай бұрын
Likewise. Thank you for yours 🙏😊
@mhamdmarch8709
@mhamdmarch8709 Ай бұрын
Man your content can easily be addicted,i love ur way so much Keep going 🎉🎉👍🏻😁
@ChristopherOkhravi
@ChristopherOkhravi Ай бұрын
Thank you 😊
@weissbrot-rg9hd
@weissbrot-rg9hd Ай бұрын
Your videos are really helpful man. Thank you so much
@tekforge
@tekforge Ай бұрын
I love your teaching approach :)
@PhysicsITGuy
@PhysicsITGuy Ай бұрын
I love reading Yegor's articles, because he's so extreme. This is a pretty good idea. Thanks for sharing.
@emanoelfaria2930
@emanoelfaria2930 Ай бұрын
you are inspiring! very happy to ser you again here! wish you the best thank you for everything 🎉
@georgesealy4706
@georgesealy4706 Ай бұрын
Chris -- Thanks for your videos. As an old OOP developer, I enjoy listening to your lectures. When I was writing lots of corporate code I had very few people to discuss these concepts with. So I did the best I could reading many books. I would very much like to hear your thoughts regarding the 'Factory Method' design pattern. I implemented it in various ways, but I never had guidance from an academic point of view, LOL. It would be great to hear your perspectives. Thanks.
@lucasprins8895
@lucasprins8895 Ай бұрын
Glad you're back on KZbin :D
@danielnovakovic9639
@danielnovakovic9639 Ай бұрын
Wow what a throwback! The first videos I watched from you were your vids about SOLID. You helped me ace some exams back then. Good to see you back! :)
@ChristopherOkhravi
@ChristopherOkhravi Ай бұрын
Happy to hear that 😊
@makeit_studio
@makeit_studio Ай бұрын
I'M SO FREAKING HAPPY LOVE YOU THANK YOU
@jon_batista
@jon_batista Ай бұрын
that would be great to see your explanation on more common use cases like an e-commerce for instance. I really enjoy your teaching style man. Thanks for the content!
@Tsadey
@Tsadey Ай бұрын
Great content, plus nice style. Congratz and keep discussing such nice topics.
@navaneethagastya
@navaneethagastya Ай бұрын
Glad, you are back! All the best! :)
@ChristopherOkhravi
@ChristopherOkhravi Ай бұрын
Thank you 🙏
@ashtheevil
@ashtheevil Ай бұрын
I missed your content. Enjoing it, even not being programmer myself. Glad to have you back!
@ChristopherOkhravi
@ChristopherOkhravi Ай бұрын
Thank you 🙏😊
@patrickstephen7885
@patrickstephen7885 Ай бұрын
Excellent content as always
@NoahNobody
@NoahNobody Ай бұрын
Thanks for introducing me to Elegant Objects. It looks really interesting.
@thatssatya
@thatssatya Ай бұрын
Great Content
@CatalinCovrig
@CatalinCovrig Ай бұрын
love to have you back
@user-zp1dv4yh5e
@user-zp1dv4yh5e Ай бұрын
Thanks
@YaraslauSauchanka
@YaraslauSauchanka Ай бұрын
Thanks for the video. Yegor Bugaenko sometimes makes a bit extreme statements, but overall the book is great.
@ChristopherOkhravi
@ChristopherOkhravi Ай бұрын
I agree 😊 But I think the exercise of pushing an idea to its limits just to see how far we can take it is tremendously valuable. So I very much appreciate the extremes 😊 Thank you for sharing your thoughts. 🙏
@aldebaranakos
@aldebaranakos Ай бұрын
Thank you for your content :)
@ChristopherOkhravi
@ChristopherOkhravi Ай бұрын
Thank you for watching 😊🙏
@pseudofacts4356
@pseudofacts4356 Ай бұрын
Seeing your video after 3 years.. I followed your solid principle closely
@eets4you
@eets4you Ай бұрын
what if I'm not expecting any variation? Interfaces are costly: they make the code more complex, and sometimes I am 100% certain my interface/abstraction will forever match a unique concretion. Then it doesn't make too much sense to use interfaces here?
@PhilipStCroix
@PhilipStCroix Ай бұрын
probably wasteful still, but it often helps with unit testing since you mock the api instead of the concretes dependencies
@user-ev9jg6ts6e
@user-ev9jg6ts6e Ай бұрын
@@PhilipStCroix This way you end up with tons of useless mocks and tigly couple your tests to your code. Mocking eveerything is bad practice.
@jason_v12345
@jason_v12345 Ай бұрын
bingo. Don't overengineer. You can always "extract interface" if and when the need arises
@mhandle109
@mhandle109 Ай бұрын
Yeah. Some classes don’t need abstractions. BigDecimalInterface would be a joke.
@ivandrofly
@ivandrofly Ай бұрын
Thanks :)
@user-ev9jg6ts6e
@user-ev9jg6ts6e Ай бұрын
Hi Chris. Brilliant as always and I highly appreciate. But this time I completely disagree. "Always use interfaces", "Couple to abstractions" these two definitely lead to premature abstraction and are extreme statements. They also lead to meaningless IDoSomething and DoSomethingImpl : IDoSomething. In my opinion one should couple to abstracton (or use interface) only if there is more than one implementation of the abstraction. Otherwise coupling to implementation is the only right choice. I also think that one should start with just an implementation and later abstract things out when needed.
@aoidev3809
@aoidev3809 Ай бұрын
I think abstractions must be carefully thought out, since they are better to not be leaky, for them to be useful and stable... that means you better work them out upfront, which means you need to see the variations of data clearly. The abstractness of the example doesn't give the impression of being carefully thought out. Like, here we assume an endless possibilities of variation. In reality those possibilities are more concrete. You cannot program what you cannot even imagine to exist, there's even no place for speculation (or some people may find endless possibilities for speculation, but we want to get a job done as fast as possible) There are known knowns, known unknowns, and unknown unknowns. The last one we don't even touch until the time comes. And it is more of an architectural thing, than designer
@aoidev3809
@aoidev3809 Ай бұрын
So, to sum it up, I agree that example and the message are misleading, but I don't agree in suggested way of work, when you refractor design out of concrete code
@user-ev9jg6ts6e
@user-ev9jg6ts6e Ай бұрын
@@aoidev3809 It's impossible to design-first all the abstractions. It's an iterative process. YAGNI.
@InforSpirit
@InforSpirit Ай бұрын
I think common problem with these kind of imperative statements is that these are not spesific enough to close of other user cases where example is useless (simple programs). This example is mostly valid for complex pipeline programs. Rendering and game engine are good examples, because there is oneway of abstraction towards hardware. For renderer there is no distinction between player or Npc, both are just blobs in screen, but in higher level those had meaningfull difference.
@mahmoudelazb8028
@mahmoudelazb8028 Ай бұрын
Keep going❤️
@grrlgd3835
@grrlgd3835 Ай бұрын
Love your channel
@ChristopherOkhravi
@ChristopherOkhravi Ай бұрын
I’m happy that it’s useful. Thank you for watching and engaging. 😊🙏
@dripcode2600
@dripcode2600 Ай бұрын
Yes and yes.... Great video!!! Programming Design Patterns => SOLID Principles => Coding to an Interface. If you code to an interface you will find yourself following most of the SOLID principles and can easily read and understand most design patterns. But why do this? Simple: you are creating code that can be changed, while being less likely to break (like a strong tree) and is testable. Why is this important? If your code is low prone to error and more flexible, changes will be more robust and quicker. For a busines this means lower cost. For the developer, justification for their job and rate. Don't believe me? Ask Southwest Airlines how much it cost them when their ticket system went down.
@tarabhushan1733
@tarabhushan1733 Ай бұрын
finding your videos may be after half a decade. Welcome back :)
@ChristopherOkhravi
@ChristopherOkhravi Ай бұрын
Half a decade. Yikes 😀😬
@philipphortnagl2486
@philipphortnagl2486 Ай бұрын
never leave again. Best OOP design channel
@ChristopherOkhravi
@ChristopherOkhravi Ай бұрын
Thank you for the very kind words. And thank you for coming back 😊🙏
@wangshuntian
@wangshuntian 13 күн бұрын
dude is the best!
@cuddlefish1000
@cuddlefish1000 Ай бұрын
How applicable do you find these videos/concepts to languages that have added OOP after their creation or through frameworks(Angular)/langauges(Typescript) as opposed to those that have had them from the beginning?
@arminium56
@arminium56 Ай бұрын
Thanks for another amazing vid 🙏. PS: a full course would be awesome if that'd be possible to you :)
@ChristopherOkhravi
@ChristopherOkhravi Ай бұрын
Thank you very much for the feedback. What topic did you have in mind? OO design in general?
@arminium56
@arminium56 Ай бұрын
@@ChristopherOkhravi right now I'd really appreciate an algorithm and data structure course but anything you share is a blessing :)
@andre-marcondes-teixeira
@andre-marcondes-teixeira Ай бұрын
Very good content. Would you be open to create a video about the Expression Problem?
@GiuseppeRicupero
@GiuseppeRicupero Ай бұрын
Apart from helping to respect the open/closed principle the interfaces are also needed to unit test using mocks. To paraphrase an adage: "No class is an island" and when you use them in another one you need the interface to mock them.
@jacobsalois3987
@jacobsalois3987 Ай бұрын
cool vids !
@yegor256
@yegor256 Ай бұрын
Many thanks for mentioning my book :)
@CouchProgrammer
@CouchProgrammer Ай бұрын
👏👏👏
@SirBenJamin_
@SirBenJamin_ Ай бұрын
Love your content man. You remind me a little of Mr Bean.
@nullx2368
@nullx2368 Ай бұрын
I agree with the theory and this is the way. Love the way you explain it as well. My problem with it is in practise you end up doing lot of abstractions and don't get the benefits. Like if you have the hard rule of "Any public properties or methods should be interface" lot of the the time you end up with only one use case of the abstraction and of course more bullet proof for changes later.... if they happen ... but usually they dont. I think these rules apply much better to something like items, moves etc... but other cases in programming becomes just tedious work? Really curious to hear your thoughts if we should just default to abstraction like this or think about it first.
@ChristopherOkhravi
@ChristopherOkhravi Ай бұрын
I completely agree that “always” is too strong. But in my estimation it’s better to shoot for “always” than not because otherwise we’ll skip doing the right thing too often. Thank you very much for sharing your thoughts.
@Moonz97
@Moonz97 Ай бұрын
Great video. Could you cover how to handle mirrored hierarchies such as that in ML libraries (a config class and the model class are tightly coupled) => for each config you need a model class and vice versa. Or is this a valid use of mirrored hierarchies?
@AlanMitchellAustralia
@AlanMitchellAustralia Ай бұрын
Great video, however would love if you could do a follow-up video on this, perhaps providing 4-5 different examples, showing how the structure is similar and/or different in each. I think I understand the theory, however with just a single example in this video (move/attack/thunderbolt), I'm not 100% sure of the mental rules I need to apply when deciding when to use classes VS interfaces, ie what is regarded as data VS behaviour, when is creating an interface a waste of time etc. Having more examples of this would really reinforce the concept.
@avidrucker
@avidrucker Ай бұрын
Agreed
@theo_st
@theo_st Ай бұрын
Did anyone here bother reading the book though? Because even if you scan the content for 30 minutes, it's full of bad advice, overthinking and pointless rambling. That said, it makes some good points.
@maxpricefield7586
@maxpricefield7586 Ай бұрын
my man making banger videos again. this means he is taking a sabbatical from his studies lmao (as someone taking postgrad as well)
@ChristopherOkhravi
@ChristopherOkhravi Ай бұрын
😊 Best of luck with your postgrad. In my case it’s that the kids are getting old enough for it to work and that I’m starting to get the hang of my teaching job 😊😊 Thank you for caring 😊
@mirrorimage9193
@mirrorimage9193 Ай бұрын
Return of King
@sahilsiddiqui3210
@sahilsiddiqui3210 Ай бұрын
it would be great if you cover system design someday
@michaldivismusic
@michaldivismusic Ай бұрын
I'd say it depends. For example, the project I'm working on currently is an API where most of the classes and interfaces have a 1 to 1 relationship. For each interface there's exactly one class and not expecting more. In which case I think it only makes sense to use an interface if you need to mock it in tests. Otherwise it's a useless additional file you need to maintain.
@alexstone691
@alexstone691 Ай бұрын
Will you ever do functional programming in the same way you do OO, i feel like you could teach me and many others what monads are :D
@professorfontanez
@professorfontanez 21 күн бұрын
Classes should indeed be used for data variations. But, more than that, classes should be coded for immutability. Objects created to encapsulate data, should be immutable (like String class in Java). Coding for immutability has some advantages, one of which is being inherently thread-safe. This in turn, makes you code perform better because, among other thigs, you don't have to block processes by using synchronization. This is a good thing to keep in mind.
@adamv5219
@adamv5219 Ай бұрын
Is an interface (as in a class with only virtual methods and no data) the best option in this scenario? It seems like any kind of Move would want to get and/or set data in a Player. If you were to do this using interfaces, every implementer of the interface would have to fill in some getter or setter method. Seems like a base class would be better, but correct me if i’m wrong. Still nice video though 😊
@heyyrudyy404
@heyyrudyy404 Ай бұрын
This is what happened, when you don’t have in the language features : functor, applicative and monad (free monad) to compose classes nicely without the need of interface. Either you have these nice Functor abstraction or you get yourself nice with interfaces.
@NostraDavid2
@NostraDavid2 Ай бұрын
Knowing FP is a boon to the OOP and procedural programming paradigms. Though of you make a game you MAY (big may) want to stick to OOP for performance (though that might not matter for your game). Outside gamedev FP may be better suited for one's needs.
@LarryGarfieldCrell
@LarryGarfieldCrell Ай бұрын
I mostly agree. Usually this is true. However, there are, in my experience, cases where there's really nothing to abstract from a data class. It really only applies to data classes, not to service classes. But I've absolutely worked on systems where we built an interface for a given data object and... the interface ended up doing nothing but making life more complicated, not less, since there was no logical alternate implementation. There was never another implementation, ever. But we still had to deal with the interface, and that meant double work every time we added a method. Now, there are cases where you'd want to have multiple interfaces the data object implements. That's an under-rated concept. One issue with your example on the board: IMove as written assumes all moves involve another player. "Player A attacks player B" and "Player A moves forward 2 spaces" would, I expect, have different interfaces. So the model would have to be further abstracted in some way.
@susseduud
@susseduud Ай бұрын
Are you going to bring back videos relating to fp?
@risingforce9648
@risingforce9648 Ай бұрын
GREATE GREAT!
@sayo9394
@sayo9394 Ай бұрын
What happened to Thunderbolt and Scratch? How are they implemented?
@adambickford8720
@adambickford8720 Ай бұрын
People should take Yegor's ideas as thought experiments, not advice, as he takes them to far beyond pragmatic.
@tomwimmenhove4652
@tomwimmenhove4652 Ай бұрын
This might be a good idea in some cases, however, the difficulty that it introduces when it comes to navigating your source code/execution flow is often overlooked. I think this is a very important aspect of programming that can make debugging and understanding execution flow much more time consuming. It should not be a rule. Rather, it should be a trade-off.
@judas1337
@judas1337 Ай бұрын
But on a serious note, does this “rule” carry over to the other languages which doesn’t have the workaround “interface” for multi-inheritance but have pure virtual classes instead?
@adambickford8720
@adambickford8720 Ай бұрын
I definitely agree that the core 'domain' should be modeled with interfaces but sometimes a class is just a class. Don't cargo cult, ask yourself what the actual (not future/theoretical) value of the code is. I don't need my 'utils' class to implement an interface. (I'm well aware of the OOP dogma around util/manger classes and remain completely unconvinced) I'll ignore that in languages like java, interfaces can have a default implementation further blurring the line of (abstract) classes and interfaces.
@dripcode2600
@dripcode2600 Ай бұрын
Create example: I use interface to describe behaviors not data.... (true the behavior acts on the data.... e.g. getters and setters). One last comment... this is at the heart of OOP (along with Events/Messaging .... don't want Alan Kay to think I didn't hear what he said about OOP).
@CyberMarshall
@CyberMarshall Ай бұрын
@ChristopherOkhravi do you mean that? public class Attack : IMove { private readonly int _damage; public Attack(int damage) { _damage = damage; } public void Use(IPlayer target) { target.Health -= damage; } }
@ChristopherOkhravi
@ChristopherOkhravi Ай бұрын
Exactly. Something along those lines 😊 Thank you very much for typing it out 😊🙏
@CyberMarshall
@CyberMarshall Ай бұрын
@@ChristopherOkhravi Thanks a lot! 🙏🙏
@bogdanf6698
@bogdanf6698 Ай бұрын
I wish i could comenup with a clever comment.... Not the case 😂! Great video.
@ChristopherOkhravi
@ChristopherOkhravi Ай бұрын
Nevertheless, thank you for watching and for commenting 😊
@BosonCollider
@BosonCollider Ай бұрын
The problem is that you can easily be tempted to ruin this by adding a concrete method to your prematurely chosen interface. You should focus on having as few types to dispatch between as possible before you start abstracting. Imho, Go has it right by making consumers define interfaces instead of having providers define interfaces (decoupling/elimination of imports instead of dependency inversion). If many consumers end up needing the same method, make it a shared interface. If you have one cluster of consumers that need one set of methods and another cluster of methods that needs another, make two smaller interfaces that are used for the different call sites. The most important thing is to avoid having shared interfaces with a large number of methods since those make the interface way less useful since those basically enforce that you will actually only have one or two implementations.
@sanjaysoni-ct2nf
@sanjaysoni-ct2nf Ай бұрын
Not every class need abstraction, some classes could be concrete too. like if we conceptualize hierarchical pattern between responsibility and behavior,= or subtyping then we can go with abstraction using interface but at the other end utility or extension classes should be concrete in application.
@krlsdu
@krlsdu Ай бұрын
You are right, but people careful other principal. A class need change for one reason and not be forced to change when creating other method in your interface.
@denys-p
@denys-p Ай бұрын
Honestly, I hate idea of “all classes should be implementations of some interfaces”. Most of code is not that abstract after all. So, my rule of thumb is “make interface if you have more that one implementation or really anticipate that you will have them in foreseeable future”. It makes less code so it becomes more flexible after all, because you don’t have to make changes to interfaces when modify methods and parameters + easier to read and navigate (and it’s adds up quite fast, much faster than cost of interface extraction in case of need). And if you find out that there should be more than one implementation, it is not too hard to replace it with interface after all. So, when you see and interface, it has some meaning that “here are (or at least could be) multiple implementations, it is not just in sale of putting interfaces for everything”
@DreanPetruza
@DreanPetruza Ай бұрын
Go kinda forces you to this great pattern
@clamhammer2463
@clamhammer2463 Ай бұрын
I really wish this were in e-book format.
@ChristopherOkhravi
@ChristopherOkhravi Ай бұрын
I did write a book on OOP. But it’s less about design. theobjectorientedway.com/ Thank you for watching and for the feedback 😊🙏
@odiiibo
@odiiibo Ай бұрын
Create a concrete type with a general name like Animal. Use it. When time comes your application needs Dog and Cat, change Animal to an interface and implement it in Cat and Dog. This way you keep you clients safe and don't pollute your code with files that are not needed yet. I was taught thid rule by Nikita, and who told him, I don't know.
@kevalan1042
@kevalan1042 Ай бұрын
This seems to be a tradeoff though. By telling users to couple to IMove instead of to Attack, you add complexity to the user's code, because for attack-specific code they have to check if the IMove is an Attack, right?
@ChristopherOkhravi
@ChristopherOkhravi Ай бұрын
Good question. The need to type checking is an indicator that we need to restructure our solution. If we need to distinguish attacks from other moves then we should not mix objects of the two types in the same collection. We can still however couple to the abstraction rather than the concretions. In other words the battle menu might consist of two collections for example. One containing things that you apply to the opponent and one that you apply to yourself. For example. See what I mean? Thank you very much for the question and for watching 😊🙏
@kevalan1042
@kevalan1042 Ай бұрын
@@ChristopherOkhravi Thank you for the response. I still don't understand what should be the driving factor for introducing an abstraction. For example, why not introduce an additional abstraction above IMove, maybe IAction? And one more above that?
@AgodzillaFace98-yj5nq
@AgodzillaFace98-yj5nq Ай бұрын
Abstractions over abstractions, nervous giggle. Yeah. Best approach I have found is focus on the problem and keep architectural stuff out. Solve the problem first. I would go as far as saying code duplication is okay if that's what it takes. Let me give you an example, in the beginning of game development you might have a zombie and a player. Both need to move and attack. If you create a centralized place for this, you have spent more time thinking on architecture than solving the problem. You loose the flexibility. If you adjust player functions, zombie might be affected and broken. You loose flexibility and introduce headaches. It's like shooting yourself in the foot. I follow the rule of never use abstractions and interfaces. Business is not abstract, your problem is not abstract. Decouple with events and you're golden. Modules can be updated, nothing ever breaks in ugly way, and you got modules that can be reused. So if you have a player and a zombie, create modules for those. Be it a class or a collection of functions. This way, if your zombie behaves wrong - you know where to go. Don't be afraid of large functions either. Don't be afraid of incorrect directory architecture - different topic but the advice is the same - avoid. Do not waste your time thinking where your function will go. Just implement it. Instead focus on the big picture. If your module is concerned with rendering - make rendering itself efficient. Abstractions and interfaces won't make your code more maintainable or faster.
@ChristopherOkhravi
@ChristopherOkhravi Ай бұрын
Thank you very much for sharing this very interesting perspective. Let me ask you: Without abstraction, how do you avoid littering your code with endless conditionals?
@AgodzillaFace98-yj5nq
@AgodzillaFace98-yj5nq Ай бұрын
​@@ChristopherOkhravi Thanks. Well it's simple. Either you litter your code base with files and jump between them, or you have conditionals. Conditionals in my opinion, are easier to read and understand without the need to jump between files. This is the high level. If we talk per function level, it's just a matter of organising and writing half decent code and you won't have a problem. My experience showed me that I like modules, albeit sometimes large ones, the functions themselves are not littered with conditionals. Another way to avoid many conditionals is by knowing upfront, what you're doing. This helps in writing maintainable code.
@sodhancha
@sodhancha Ай бұрын
Do one on AI and how it will share future prospects for software engineers
@anon5992
@anon5992 Ай бұрын
decoupling comes with costs it's not free.
@ChristopherOkhravi
@ChristopherOkhravi Ай бұрын
Very interesting point. Would you care to expand? 😊
@kevalan1042
@kevalan1042 Ай бұрын
@@ChristopherOkhravi My thoughts on this: By telling users to couple to IMove instead of to Attack, you add complexity to the user's code, because for attack-specific code they have to check if the IMove is an Attack, right?
@aleksandr2245
@aleksandr2245 Ай бұрын
little mistake, YegO'r, not YE'gor) great video as always)
@FroodyBanana
@FroodyBanana Ай бұрын
It's LEVI-OSAH Not LEVIO-SAH!
@jorkhachatryan317
@jorkhachatryan317 Ай бұрын
Actually, this was an empty space for me before, thanks for clarifying. And one more thing, when we say interface, I assume that we still mean Interface or Abstract class, right?
@ChristopherOkhravi
@ChristopherOkhravi Ай бұрын
I’m very glad to hear that. 😊 Yes generally the point is that we should couple to an abstraction. Which would include abstract classes. It should be said however that it can certainly be argued that we should always prefer interfaces and never abstract classes. Classes can only inherit from one abstract class but can implement multiple interfaces. So the former is less flexible.
@jorkhachatryan317
@jorkhachatryan317 Ай бұрын
​@@ChristopherOkhravi Thanks, now it's more clear.
@alexandernava9275
@alexandernava9275 Ай бұрын
Question, if we are to inherit for data changes, and implement for logic changes, why can't I inherit structs in C# XD
@maayanzar
@maayanzar Ай бұрын
IMO this approach will lead to class explosion very quickly, if ill take the refactoring rule you discussed about in previous video, i would take this rule when i "touch" the code the third time. Regardless thank you for another enriching video
@expeditiontoabyss3597
@expeditiontoabyss3597 Ай бұрын
Just a note that Yegor is a supporter of russo invasion of Ukraine, totalitarian, and he also made many hate speeches before. He is also banned from many conferences outside of russia due to his believe of government should be a god and people should just follow orders.
@ChristopherOkhravi
@ChristopherOkhravi Ай бұрын
Oh no. This makes me very sad. 😢 Thank you for sharing this. I certainly prefer to stay out of this debate and want to focus on the software discussion.
@expeditiontoabyss3597
@expeditiontoabyss3597 Ай бұрын
@@ChristopherOkhravi I can totally relate, and you can't check every author's bio before reading his book/post. Thanks for your kind response.
@user-lk1fw1lp8b
@user-lk1fw1lp8b 29 күн бұрын
Does it invalidate any of Yegor's statements regarding object-oriented design?
@FraJaiFrey
@FraJaiFrey Ай бұрын
And what happens when we are using a dynamically typed language like javascript or ruby?
@ChristopherOkhravi
@ChristopherOkhravi Ай бұрын
In dynamically typed languages we can still “think” in terms of abstractions. We write code that works for any concretion of our abstract ideas. But the abstraction is never written down as code. Thank you for the very relevant question. Will try to dedicate a video to this in the future. Thanks again 🙏😊
@aredrih6723
@aredrih6723 Ай бұрын
Idk, I generally agree that if you can stick to interface you should, but writing good interface is an art and if a lib doesn't expose the method you need in an interface, coupling to the concrete class seems more and more acceptable to me as times passes. Sure, doing so might break the lib correctness but in the context of your app doing what it needs, "correct" coupling with a lib isn't worth much. Though if you have control over both interface and consumer code sticking to interface is the best option. That said, interface are the only kind of technical debts you can't pay back until the next major version so overusing them seems bad too. Also, there is another (niche) angle where interface aren't necessarily the best option: performance critical code. The way I see it, interface are about commitment to a contract but there are things that can't be modelled as part of the interface (error safety, memory usage, perf). Coupling to concrete class doesn't change that fact but if the contract is not sufficient, there's little point setting it up.
@josephlagrange9531
@josephlagrange9531 Ай бұрын
Hello!
@omri9325
@omri9325 Ай бұрын
4:36 Demonstration of how to implement the shape interface
@ChristopherOkhravi
@ChristopherOkhravi Ай бұрын
😆
@toms7114
@toms7114 Ай бұрын
The name of the abstract class would make more sense as action instead of move. Move can be types of actions, and move could mean the character in the game could you are referencing moves location, or it is their turn and they make a move, which is some action. This would decrease the ambiguity of the abstract class name and make the code more reader understandable for different developers.
@ChristopherOkhravi
@ChristopherOkhravi Ай бұрын
Makes sense. This was raised as an issue in the related video and I mostly agree. I wanted to make sure to keep it consistent with that video here however so opted for no changes. On the flip side it makes sense in my mind that a “move” is something you can do in a game. In my mind I was thinking of the old Pokémon battles and since there’s no physical movement there the name made sense to me 😊 Nevertheless I think you are right that it could be clearer 😊 Thank you for your detailed comment 😊🙏
@kekons23
@kekons23 Ай бұрын
serious question, did they use OOP in the old pokemon games?
@ChristopherOkhravi
@ChristopherOkhravi Ай бұрын
Very interesting question! Looks like they were developed in Assembly. Wild to think about having to get that done 😊
@VenkateshKadiriFromBangalore
@VenkateshKadiriFromBangalore Ай бұрын
I see the strategy pattern in the solution.
@HyperionStudiosDE
@HyperionStudiosDE Ай бұрын
Making that a general rule is ridiculous. Abstraction always comes with an overhead cost and it has to be weighed if it's worth it. I hate working with dogmatists who want to cram abstractions into everything. It's a maintainability nightmare, especially in a project with evolving requirements.
@ChristopherOkhravi
@ChristopherOkhravi Ай бұрын
Thank you very much for the perspective. Generally, if you have examples or stories from past experiences do feel very welcome to share them here. I’m not trying to push. Just saying that I’m sure that people, myself included, would appreciate the opportunity to learn more 😊 Thanks for watching and commenting 😊
@HyperionStudiosDE
@HyperionStudiosDE Ай бұрын
@@ChristopherOkhravi Just to be clear, my post wasn't aimed at you. I'm just ranting because I hate dogmatism in programming.
Depend on Abstractions not Concretions (Framework)
11:56
Christopher Okhravi
Рет қаралды 14 М.
The Only Time You Should Use Polymorphism
13:55
Christopher Okhravi
Рет қаралды 85 М.
Не пей газировку у мамы в машине
00:28
Даша Боровик
Рет қаралды 10 МЛН
когда одна дома // EVA mash
00:51
EVA mash
Рет қаралды 13 МЛН
Do you have a friend like this? 🤣#shorts
00:12
dednahype
Рет қаралды 20 МЛН
How Senior Programmers ACTUALLY Write Code
13:37
Thriving Technologist
Рет қаралды 1,3 МЛН
Event-Driven Architecture (EDA) vs Request/Response (RR)
12:00
Proxy - Design Patterns in 5 minutes
3:59
levonog
Рет қаралды 3,1 М.
Liskov Substitution Principle (SOLID)
20:16
Christopher Okhravi
Рет қаралды 7 М.
Factory Method Pattern - Design Patterns (ep 4)
27:21
Christopher Okhravi
Рет қаралды 530 М.
Only Use Inheritance If You Want Both of These
9:10
Christopher Okhravi
Рет қаралды 11 М.
Proxy Pattern - Design Patterns (ep 10)
37:35
Christopher Okhravi
Рет қаралды 159 М.
5 Rules For DTOs
17:56
Ardalis
Рет қаралды 35 М.
How principled coders outperform the competition
11:11
Coderized
Рет қаралды 1,5 МЛН
Liskov's Substitution Principle | SOLID Design Principles (ep 1 part 1)
16:08
Christopher Okhravi
Рет қаралды 156 М.
Не пей газировку у мамы в машине
00:28
Даша Боровик
Рет қаралды 10 МЛН