Liskov Substitution Principle
20:16
7 Tips to Grow as a Developer
7:25
They Knew Waterfall Didn't Work
6:36
Always Use Interfaces
8:08
2 ай бұрын
Covariance and Contravariance
13:31
The Square-Rectangle Problem
9:59
My Vim Setup #1 (Job Control)
43:27
5 жыл бұрын
Ramda JS Tutorial - Part 40 (filter)
57:55
Todo App in Vue.js - The Hard Way (Ep18)
1:07:11
Vue.js - The Hard Way (Ep16)
1:00:12
5 жыл бұрын
Vue.js - The Hard Way (Ep15)
51:46
5 жыл бұрын
Vue.js - The Hard Way (Ep14)
34:00
5 жыл бұрын
Vue.js - The Hard Way (Ep13)
41:29
5 жыл бұрын
Ramda JS Tutorial - Part 39 (T, F)
23:45
Пікірлер
@kartikeykaushiq5278
@kartikeykaushiq5278 17 сағат бұрын
in the Iobservable interface could we have had an update method that could have one info class paramerter? sorry for irregularities in code...did it directly on comment box. I mean something like this class Tempinfo{ String todays temp; ...... other members and constructor..... } then in class Iobserer{ .............all other members and methods......... update(TempInfo obj); } class WeatherStation implements Iobservable{ ................................other smembers and method................. getTempInfor(){ return new TempInfo("It's just Nuclear Winter "); } public notify(){ foreach( Iobserver o : IobserberObj){ o.update(this.getTempInfo()); } } } in Iobserver interface class Iobserver{ update(TempInfo obj); } finally in Phonedisplay class class PhoneDisplay{ ......other members..... TempInfo tempobj; update(TempInfo temp){ this.tempobj = temp; } display(){ System.out.println(temponj.toString()) } } thanks for the content
@kartikeykaushiq5278
@kartikeykaushiq5278 17 сағат бұрын
Ohhh i hurried a bit 😅😅... U mentioned same thing around 47:10
@Flynnor
@Flynnor 2 күн бұрын
Great insights. Thank you.
@agzapiola
@agzapiola 3 күн бұрын
Your return to YT is a blessing!
@revensoftware
@revensoftware 3 күн бұрын
Regarding the performance vs readability, I tend to lean towards performance - within reason. I've encountered many times where someone wanted to significantly reduce performance for the sake of improving readability slightly. I hear the same thing a lot, "don't worry about performance until it's an issue," but that's one of the big problems in our society - people don't want to do anything that takes effort until there's an actual bonafide problem (and sometimes not even then). If you intentionally hinder the performance a small amount for the sake of readability and then do that 1000 times across a system, it can take a lot of unnecessary effort to identify which pieces need to be updated, which are the worst offenders, how to fix them, etc. It might be obvious which option is more performant vs readable when it is being written/reviewed, but 6 months, a year, 3 years later, that knowledge is probably lost.
@SanoussiMaiga
@SanoussiMaiga 3 күн бұрын
Perfect Explanation.Thank you 😃
@isedorheering
@isedorheering 4 күн бұрын
Thank you!
@Msyo_Jaber
@Msyo_Jaber 4 күн бұрын
Thank you this is the usfol tip I will do it
@jessecalato4677
@jessecalato4677 4 күн бұрын
doesn't matter much for this example, but when you talk about mutation you say @24:27 you say that b will be 6, but that's not true, you used the post decrement opperator, the value of a is returned before it is incremented, so b would actually be set to 5, and then a becomes 6.
@user-hg4fs2ik5c
@user-hg4fs2ik5c 5 күн бұрын
Man I love you. I see that you're back on KZfaq after years. I have encountered your channel after university bullied me into Software Design, but you made it slightly more tolerable. Anyways, thank you so much. I will be having my exam in two days. If I pass, it's totally because of you. Even mentioned you in the Course Review section of my course, as our course was probably the most boring thing I have ever seen. However, you made me see the beauty of it, even though I totally hated it all. You just earned yourself a permanent member of your community :)
@user-hg4fs2ik5c
@user-hg4fs2ik5c 5 күн бұрын
I can't believe this video is 7 years old. The whole playlist is absolutely awesome. Anyways, I don't understand why you'd want to couple the ConcreteObserver to a ConcreteSubject, instead of coupling it to the interface? If I am not totally stupid, you should still be able to do a constructor along the lines of ConcreteObserver(ISubject s), and then use s.getStuff() or whatever it's supposed to do. Actually, I think I rubberducked myself by writing this comment. is it because I do not know what my getStuff is actually like? maybe it's a getTemp(), maybe it's a getStockPrices()? Makes sense. I'll still leave this here. Thanks again!
@kokoleismail912
@kokoleismail912 6 күн бұрын
2024 and am here great series
@moristar
@moristar 6 күн бұрын
It's like the first thing that gets violated in OOP and probably the least important TBH
@ShivamKendre-fc3su
@ShivamKendre-fc3su 6 күн бұрын
What a great video!!
@HKCS-yn5nc
@HKCS-yn5nc 7 күн бұрын
In the third case, a switch on an enum wouldn't be bad after all, especially it would help spot the missing Armour logic more quickly I the attack class.
@ruslan_yefimov
@ruslan_yefimov 8 күн бұрын
Not all people are "enormously smart" at Microsoft, apparently :D
@jonasbarka
@jonasbarka 7 күн бұрын
No, it's because they prioritized backwards compatibility in newer versions of .NET.
@Asdayasman
@Asdayasman 8 күн бұрын
You didn't suggest a fix. Inheritance among interfaces appears to be bad design. When I have something that implements IList, all I really care about is the extra stuff it adds on top of its parent class, so it shouldn't have a parent class. Something that today implements IList, should tomorrow implement IList, ICollection, and IEnumerable. If the programmer needs to add something, they call for an ICollection. If they need to index, they call for an IList. If the programmer requires something that is both indexable and add-to-able, they should define their own combination of those types.
@IstoriaSubLupa
@IstoriaSubLupa 8 күн бұрын
In your example with the weatherStation shouldn't the PhoneDisplay and the WindowDisplay be connected to the WeatherStation through an arrow?
@Tynach
@Tynach 8 күн бұрын
I really like your teaching style, and find your videos to be fairly good at getting the point across in a concise and easy to understand way. However, most of these seem to be very focused on object oriented programming, which is something I've started to move away from in favor of data-oriented programming. One of the core tenants of data-oriented programming is that data and behavior should be separated, rather than encapsulating the two together. While it makes less sense for Tic-Tac-Toe (which can only have 2 players, and the game board has such an extremely limited set of possible states), for more complex games my instinct would be to not have 'HumanPlayer' or 'ComputerPlayer' classes at all, but instead to have an array of all the names of the players (probably just called 'Players'), and two arrays with indices into that array.. One labeled as 'HumanPlayers' and the other 'ComputerPlayers'. Assuming game logic runs on the server and multiple clients connect to said server, sending their player's input, then there'd just be two 'for' loops. One would iterate over every player in 'HumanPlayers', passing the input from the clients into a function that calculates game logic. The other loop would iterate over every player in 'ComputerPlayers', but instead of receiving input from a client it would run a function that calculates what that input would be, and then feeds the output of that function into the game logic function. Of course, the game's state would be accessible from within said functions (both the function that calculates computer moves, and the function that calculates game logic). Maybe a global, or maybe both functions require another parameter for the state object. Or perhaps all of these are in the same 'Game' class and can see a 'Game.state' object that holds the internal state of the current game. Actually, thinking about it a bit more, perhaps it'd be even better if instead the first loop simply calculated what the 'input' from the computer players would be, and adds them to the same pile of inputs from the players that was collected from the connected clients... And then the second loop iterates over 'Players' (that is, the array with all the players) and processes all of their input all at one time. It's 3 AM and I should go to bed.
@samuelzev4076
@samuelzev4076 8 күн бұрын
What is the name of the site where I can ask you programming-related questions?
@codahighland
@codahighland 9 күн бұрын
And this is why C++ has `const`. You don't need to have two different types for this.
@realbart
@realbart 9 күн бұрын
Yes. IList is one of my pet peeves, the one I'm always using to exlain Liskov. You should not have "ReadOnly" prefixes, but "Mutable" IList should be readonly and implement ICollection ICollection should be readonly and implement IEnumerable. The mutable varant of ICollection should be named IMutableCollection and implement IEnumerable. The mutable variant of IList should be named IMutableList an implement IList and IMutableCollection. IsReadOnly should not exist. Having to call that befor writing is madness. The reason things are not named this way are historic. The error was already there in the first version of the framework, in the non-generic interface and IList. They needed a common interface for arrays and other collections. Not that at that point in time, ICollection did not have Add and Remove. When introducing .net 2.0 they could've fixed it by removing Add and Remove from IList. However, they wanted to be downward compatible. So introducing prefixes ("Mutable") for the interface that can do more instead of introducing different prefixes ("ReadOnly") for the interface that can do less was not an option.
@namanvaishnav4307
@namanvaishnav4307 10 күн бұрын
How someone can be relevant after 6 years!! Amazing!!
@jessecalato4677
@jessecalato4677 10 күн бұрын
I've be developing software for 23 years and, have read both books, and know and have used all of these patterns. I came looking for good tutorials for my less experienced team members, and even with knowing this information already, I can't stop watching these, they are excellent resources.
@ChristopherOkhravi
@ChristopherOkhravi 9 күн бұрын
Very happy to hear that. Thanks for sharing 😊🙏
@jessecalato4677
@jessecalato4677 10 күн бұрын
Yes Singleton shouldn't be used, but also, if you really "must" use it then this implementation is not thread safe. The instance should be created in a construct that guarantees thread safety. In c# the static constructor would do as that is guaranteed to only run once, and is thread safe. In a language that doesn't have the idea of a static constructor that guarantees that thread safety then the instantiation of the singleton should be done within a synchronization context to ensure multiple thread don't accidentally create multiple instances of the singleton.
@nasimnajand9697
@nasimnajand9697 10 күн бұрын
you are just amazing 😇
@todortotev5399
@todortotev5399 11 күн бұрын
I suffered the entirety of the 18 minutes wandering, why this is not a 30 seconds Shorts, because that's the length of the useable content.
@todortotev5399
@todortotev5399 11 күн бұрын
Also, ffs, LSV was not violated, it's just that the basic interface behaves weirdly (but in a well-documented way) and the class that implemented it implemented it fully. So essentially, the video title is a lie, and the the entire video is just garbage.
@ChristopherOkhravi
@ChristopherOkhravi 10 күн бұрын
Thank you very much for the feedback 😊🙏 and I'm sorry to have made you angry. Many are not familiar with all the details which is why we are taking it so slowly. Imho I still belive that we should read this as a violation of LSP. As I say in the video I of course agree that it is not technically a violation. But still, it seems to me that most of us would agree that there is an obviously right way to structure this hierarchy and that the way they chose to structure it is NOT the right way. Moving errors from compile-time to run-time is NOT a sensible thing to do in a statically typed language. And as soon as we disregard the IsReadOnly property and the run-time exception (which should NOT be there because this is a statically typed language and this problem is entirely solvable without them) this becomes a violation of LSP. Thanks for watching and for commenting! Just a headsup: I will keep posting long-form content so please consider yourself warned 😊
@davidmatten8519
@davidmatten8519 11 күн бұрын
a related terrrible interface is ISet<T>, which crazily inherits from ICollection<T> then tacks on a bunch of other junk. Mostly I'm irritated with them squatting on such a generic name, which doesn't represent a general mathematical set at all. In general terms, the only thing you should be able to do with a set that is given to you is check if a given element is part of the set. There isn't a notion of "adding/removing/clearing" a set. if you "Add" something to a given set? That's a different set. Set to a different reference, give it a different name. Even Counting the elements of a set is not necessarily meaningful in plenty of ordinary cases. If you want more feature-full implementations with support features/methods that have a common interface, fine, but call that common interface something more specific. I ended up creating my own IProperSet<T> interface, and the only thing it implemented was IsElement(T), and from there I could build a flexible support module with a few types of implementations according to how the membership was confirmed. Some were large collections, of elements from an cached distributed data source, but were only supplied to the consumer as an immutable IProperSet<T> (as far as they knew). Other simple objects literally checked for equivalence to a single value special domain value. Having it check explicitly was less contrived than creating a collection of one item. Rather than bloat the base interface or even the specific set implementation Union<T> and Intersection<T> were implemented as objects themselves that implemented IProperSet<T> and called the IsElement(t) on each constituent set as appropriate. IsSubset() was implemented as an extension method, not needing to know anything about the underlying implementations.
@davidturner9827
@davidturner9827 11 күн бұрын
OOP is upside-down. Types are generalizations of objects, objects aren’t realizations of types.
@ran-j
@ran-j 11 күн бұрын
This video was simply fantastic, great explanation about LSP
@ChristopherOkhravi
@ChristopherOkhravi 11 күн бұрын
Thank you for watching 😊🙏
@HMan2828
@HMan2828 12 күн бұрын
7:29 huuuh an interface doesn't inherit from a type, it can be implemented in a type.... The reason ReadOnlyCollection implements IList is because ReadOnlyCollection is intended to be a pre-cooked base class for implementers looking to make their own custom read only collections, and has been around since .NET 2.0... IReadOnlyCollection was only added in .NET 4.5. So they couldn't just modify ReadOnlyCollection without breaking compatibility... I think this is a big tempest in a tiny water glass... Usability > theory.
@ayushdayani7157
@ayushdayani7157 12 күн бұрын
The example of Dark and Light mode was beautiful. It gave the most clarity about the use case of abstract factory. Kudos!
@ChristopherOkhravi
@ChristopherOkhravi 11 күн бұрын
Happy to hear. Thanks for watching 😊🙏
@a.yashwanth
@a.yashwanth 13 күн бұрын
I dont feel right about giving weatherstation object to all the observers (PhoneDisplay in this case). Now the observers can access any method from the weather station even if it's not relevant to the observers. For example an observer can add another observer using the add method. I think we can create one more interface which the weatherstation can implement that contain only the methods that we want the observers to have access to.
@AlgoristHQ
@AlgoristHQ 13 күн бұрын
I write code in C#. Technically, if I don't override any base class methods or if I don't use base classes, then I can't violate the LSP. I dont find this to be a particularly useful definition.. In C#, the LSP changes. We talk about implementing interfaces instead of inheriting from super classes. All implementations must correctly implement all methods on the base interface. This means that a method can consist of one line throwing an exception. Some people say that LSP means that you must use the most abstract class in your code and let DI do the work of populating the correct class. There is no value to doing this ALL of the time. Interfaces should only be used when mocking for testing is needed or if you are implementing something like a strategy design pattern. Otherwise, you are increasing the amount of code in your code base for no discernable reason.
@ChristopherOkhravi
@ChristopherOkhravi 13 күн бұрын
Thank you for sharing your experiences 😊🙏 LSP applies to interface implementation as well and not just inheritance. LSP is fundamentally about subtyping not about inheritance. In this video I use the term “inherits” because this case regards inheritance between interfaces. If you have the time I would highly recommend my videos on LSP (kzfaq.info/get/bejne/bc6InJN_ltW7dok.html) and on variance (kzfaq.info/get/bejne/fMp2dbyGtqnZeIU.html). They help elucidate why LSP applies to subtyping and not just class inheritance. Thanks again for watching and for sharing 😊🙏
@grrlgd3835
@grrlgd3835 13 күн бұрын
best explanation...thanks Chris
@AlgoristHQ
@AlgoristHQ 14 күн бұрын
Im not a fan of using interfaces all of the time. If im not mocking this code in a test and I'm not implementing something like a state design pattern, then i dont use interfaces. That has made my code much much cleaner!!
@dhruvab5
@dhruvab5 14 күн бұрын
I don't get how the strategy pattern is different from the bridge?
@fourZerglings
@fourZerglings 14 күн бұрын
There's a simpler example: arrays in .NET implement IList<T> without support for Add or Remove
@NeilPoulton
@NeilPoulton 14 күн бұрын
Please stop saying interfaces inherit - they don't
@ChristopherOkhravi
@ChristopherOkhravi 14 күн бұрын
Actually this is the way it works in C# and is the terminology from the documentation 😊. See below. “Interfaces can inherit from one or more interfaces. The derived interface inherits the members from its base interfaces. A class that implements a derived interface must implement all members in the derived interface, including all members of the derived interface's base interfaces. That class may be implicitly converted to the derived interface or any of its base interfaces.” Source: learn.microsoft.com/en-us/dotnet/csharp/fundamentals/types/interfaces Nevertheless I very much appreciate being called out since I’m wrong a lot of the time 😊😊 Tganks for watching and for commenting 😊🙏
@NeilPoulton
@NeilPoulton 14 күн бұрын
@@ChristopherOkhravi Yes, I was wrong, thinking about something else. oops.
@BangsarRia
@BangsarRia 14 күн бұрын
GoF intends that the Composite Pattern be used in cases that the Client does not have to distinguish between Nodes and Leaves. GoF p167, point 4 expressly addresses the issues of ISP and LSP: "trade-off between safety and transparency". GoF's use of "transparency" here makes me uncomfortable, because I don't think they mean that at all, and the word does not appear in the index, so we don't know what they mean by it. In this context I think they mean "uniformity", or even "abstraction". While we're talking about terminology, GOF was published before Java was revealed. So we see "operation" for "method" throughout. They might have gone with "function" instead of "method" anyway, as not all languages use "method" and "member" etc as terms.
@qj0n
@qj0n 15 күн бұрын
I think there are 2 ways of thinking about read-only collections. On the one hand, these are generalizations of read-write collections, which only support reading. On the other hand, these are collections which guarantee they won't change. I believe MS devs have change their mind about it couple of times and here's the result
@leerothman2715
@leerothman2715 15 күн бұрын
Love it. I am now changing my workshop session on LSP to include this. Basically the way that C# has got round it is by a hack and use and a boolean to the ICollection contract. If you need to check the result of this first then does this go against ‘tell don’t ask’? Not a SOLID principle obviously but a commonly used rule.
@mortenhattesen
@mortenhattesen 15 күн бұрын
IReadOnly* is a poor naming. It should be called IImmutable*.
@BangsarRia
@BangsarRia 15 күн бұрын
Thanks for reminding us that insanity is hereditary; you get it from your children. From a genetic pov your first diagram is a 1/2-part - whole hierarchy
@BangsarRia
@BangsarRia 15 күн бұрын
Try to avoid Template Method. It can get out of hand very quickly and is hard to debug or maintain, even with an advanced IDE. If you have only one subclass or only one overridable method, obviously you're going to use Strategy instead. So you've got multiple subclasses and/or multiple overridable methods - the Abstract Class already looks too big and complicated. Over time the amount of code in the Abstract Class will grow, and the number of subclasses will grow. I have had two-page Abstract Classes with six-to-nine overridable methods and ten-to-twenty subclasses. Huge future time sink. If you use Spring it's even far worse because you'll lock in the structure of the Abstract Class quite early. Find a way to shift responsibility to delegates, even if you have to use Bridge.
@CodingTutorialsAreGo
@CodingTutorialsAreGo 15 күн бұрын
I share your pain, though an even more fundamental violation is: IList<int> list = new int[] { 1, 2, 3, 4, 5 }; list.Add(27);
@NeilHighley
@NeilHighley 15 күн бұрын
What a waste of time that video was. Explaining with omission is a bad way to teach. Your title is a lie. And you end with some opinion. Spoiler: no they don't, this guy is dogmatically creating click bait
@ddystopia8091
@ddystopia8091 15 күн бұрын
Just use language that supports immutability natively, like Rust
@delicious_seabass
@delicious_seabass 16 күн бұрын
Not to bash the video or you yourself. You seem good teacher, to be honest. It's just amazing how much simpler programming is when you realize how none of this actually matters and how stupid and overly complicated OOP makes everything. What's funny to me is that the complaint here boils down to the fact that IsReadOnly is being checked at runtime instead of compile time, but you're using a managed language where literally everything is being JIT compiled and checked at run time.
@syriuszb8611
@syriuszb8611 14 күн бұрын
JIT has nothing to do with it. If programmer will get compiler error they have to fix it before they build the program. Not when JIT will finally compile it. You hate something and you don't even know what.
@logiclrd
@logiclrd 16 күн бұрын
I think they wanted the "common type" to be something that developers (their own developers) could use without thinking. What they should have done is IEnumerable <- ICollection <- IMutableCollection, and ICollection <- IList <- IMutableList, and then List implements IMutableList and IMutableCollection, and ReadOnlyList implements IList. Then, the majority of methods that want a collection or list for read-only reasons automatically require only a read-only collection or list. If someone wants it to be mutable and they haven't given it enough thought, they find they have an object that doesn't have mutation methods, and then they go and add the word "Mutable" to the input type.
@Asdayasman
@Asdayasman 8 күн бұрын
What an awful solution - simply don't inherit in interfaces and the problem evaporates. Your idea leads to combinatorial explosion.
@logiclrd
@logiclrd 8 күн бұрын
@@Asdayasman I don't think it does.
@orterves
@orterves 16 күн бұрын
Without a doubt, the ReadOnlyCollection inheriting from IList is a mistake even though the interface is technically correct by throwing that exception. One thing I'd say in addition is, I hope no one thinks that technical validity means the correct approach to using IList.Add is to check if it's safe or otherwise handle the exception in the case of ReadOnlyCollection - we should still code with the assumption IList.Add is always safe to call, and if a client passes in a ReadOnly collection to that method, that's on them to fix.