@urMamaMuthaSukka That is is correct, it is not very OO. But taking the OO approach is also brittle, just in a different way. As I pointed out, if we need to implement toString() then we have to modify every class, there is no getting around that when you use inheritance to achieve polymorphism. Haskell solves the "add a function later" problem by using type classes for polymorphism, this is a much less brittle approach. It is a bit like using interfaces and the adapter pattern in OO.
It's really easy to remove all if statements from your code. Take this snippet for example: if(a > b){ c = a - b; } Replace this bad if statement with the following for good, clean code: while(a > b){ c = a - b; break; } If statements = gone
All done with my evaluate() methods, now I want to implement toString()... Oh no! I have to modify every single class to do that :( So much for the open/close principle.
There's always a trade off here. Either you can make it easy to extend your data type or you can make it easy to add new operations on that data type.
Also I would argue that it's nicer to have all the evaluate() stuff in the same place and all the toString() stuff in the same place instead of spread across many classes/files.
I thought about writing a Renderer class to do the printing job - originally I also wanted to write the toString method - and then I figured "what if I want to have OpenGL output? Or LaTeX?" . So I decided to seperate the structure from it's rendering - and now I'm trying to figure out a sensible way to make the renderer extensible. I think I'm on to something, but I haven't tried it yet.
@jystic That's not very OO. Objects should have specific behavior. If the behavior of the object changes on state, then it's obvious that behavior belongs in it's own object. Your suggestion leads to brittle design, which is harder to maintain, test, and extend.
The speaker says that when using flags it's better to use polymorphism. In his example this is quite clear. But what if you have multiple flags in one class which can be set independently from each other? If you create subclasses for all possible combinations you end up with 2^n subclasses, in which n is the number of flags. Is there also a polymorphic way to solve this?
@MarkIJbema even with MI you still have to create all these subclasses, since the baseclasses need to be combined first. The only advantage is that you don't have to duplicate functions. You'll still end up with 2^n subclasses.
Also, getting rid of all if statements in a program is easy with a combination of template metaprogramming and lambda calculus. That doesn't mean it's easier to read though.
It seems like the examples were specifically chosen so that polymorphism could work. What happens if the state changes? You can't have one subclass instance magically turn into a different subclass. Not all switch statements switch over constants.
your talks are very clean, consise and contain good explanations. I blogged about 'avoiding if's in OOP' a few months ago before seeing this presentations. Right on the money... many people who aren't in the industry (posting comments) may not see the point in writing code this way but believe me... there are reasons.
So if I have object state flags where A=2 states, B=3 states, C=7, D=15 then all I need is 630 subclasses, then when the client comes along with another 4 state flag, I just have to write 1890 MORE subclasses.
I suppose I should name them Obj_A1_B3_C6_D1_E3 and so on? Then build an interpreter to transcode that name into some human readable form like - Obj_Homeowner_Canadian_Single_SalaryMoreThan40k_MetLife_Smoker?
@mindprism Along the same lines maybe we could reduce code clutter by simplifying everything into Main() and DoSomething(XML systemwidestate, String verb, int intparm, int intparm2, double dblparm....):Object
@TheKeinash I am just giving an example. You cant really subclass for every combination of attributes except in the most limited situations where extension is known and constrained. Even then it seems silly: EmployeeMarried, EmployeeSingle....
You are just making grief for yourself it seems to me.
@mindprism if you have a lot of logic inside Employee, that depends on Relationship status it is a sign that you should subclass. But it would not be logical to subclass Employee, but rather to create RelationshipStatus class and subclass it into Single, Married and so on.
@TheKeinash And what of my initial example of a health insurance client who has a database record with many attribute fields such that to subclass all the permutations would involve ~1000 subclasses?
Isn't there a practical limit to 'open/closed' design?
@mindprism Oh, c'mon stop trolling and admit it: you don't like his idea without any good reason. In your last example even without subclassing it would be required to do a lot of routine coding. With subclassing you will have more readable code.
@Hax0rPr0n You're completely missing the point of the object oriented method and in particular an OO principle called the Open Closed Principle which states that software modules should be open for extension but closed for modification. This property allows us to add capabilities to a software system by adding new modules (i.e new subclasses) without incurring the risk of changing existing code. That's the main reason to favor inheritance over conditionals, it has nothing to do with clarity.
@Hax0rPr0n I agree, but i honestly think this is all just a matter of semantics. If it is appealing to read without IF statements who cares. And I do not think the if statement is a hard statement to discern ever, by anyone. Again it is like trying to wrap everything in a template rather than a macro. In practice and implementation a macro can be much easier to work with, however that may not be the "correct" way to do things. All in all i suppose I agree with you, i retract my previous comment.
@jihedamine It's not about African people, it's about African swallows -- a Monty Python reference, which 80% of the geek viewers of the video are likely to get. (The "Norwegian Blue" in the example refers to another Monty Python sketch about a dead parrot.)
@Omirion Ending up with the same result is the whole point: we don't want to change the behavior of the program, only to refactor it so it's easier to read, easier to extend, and easier to test. As a bonus, a lot of the common mistakes beginners make with linked data structures (lists, trees, etc.) become type errors so they're caught by the compiler rather than being run-time exceptions.
I created a Slot Machine in the procedural style with a ridiculously amount of if statements, apart from usability problems, the processor gets extremely over used and the program could easily crash!
ok. but wouldn't you have to switch alot of variables all the time, or are you talking about internal classes withing the class that is supposed to change state?
You would have to change the object-type variables exactly as many times as you would anyway have to change the flag-type variables. That you are using objects makes it no worse and no better.
Very simple examples, but as Misko points out, many experienced developers are abusing if/switch statements, and making their code difficult to maintain.
For subclassing Update ... what happens when you want to extend the functionality again? How do you reuse the code from both? Extend both? Then for each flag, your number of classes grows exponentially.
For the node example, you can't remove the if, just move them. And I would argue that using
switch(operator){ case '*': node = new MultiplyOperator();
...
is less readable than node = new Operator(operator), and will have to be duplicated more in any code that uses Operator.
I completely agree about Polymorphism. Unfortunately, I have a better idea about a programming language's basic functionality than I do how to construct classes, the basic construct statemetns, if I can overload functions... etc.
I do like Polymorphism enough to use it. "No if statements"-- what a challenge! I already love the challenge of hitting the DB as few times as possible. :3
I once had the experience of a test we apply at work. My base implementation took about 10 seconds to process a 10000 records data set, which was in average good compared to another similar, OO engineered approaches.
Then, a student which didnt have a lot of experience with OO tackled the test, made the thing work and delivered it. It ran the same dataset in less than 1 second.
Coding from the 70s, 80s, 90s, and 2000s, I wholeheartedly disagree. IF statements have their place, but 99.44% of all IF statements can productively be replaced with polymorphism.
That depends entirely on your desired level of abstraction. Most IF statements serve only to disambiguate between two or more run-time types, perhaps types which cannot be expressed cleanly in the static type system. So, instead of having a big wad of IF or switch/case statements, you invoke an operation through a vector. Polymorphism is simply vectored execution implemented as a formal part of your language.
Polymorphism can be useful in circumstances -- in my experience - the religious use of it has lead to encounters the multi-moduled, obsenely confuzing obese code where a couple of seperate modules with a few simple straight forward faster executing switches would've been more than sufficient(especially since it's finished product not to be modified). Sometimes if you have 99 ditto flag chex - just shove a def/macro in there. Abusive religious over-use of OOP has made me very bitter. Grr.
This lesson is so sueful for me. I've changed my mind through this film in my programming. Thank you.
PiesTfojegoPiesa 17 hours ago
Great video
jb3689 2 weeks ago
i'm just a few minutes in, but let me speak my mind: re-readability is not a religion; How many times have you actually recycled your code?!
MoshMage 1 month ago
@urMamaMuthaSukka That is is correct, it is not very OO. But taking the OO approach is also brittle, just in a different way. As I pointed out, if we need to implement toString() then we have to modify every class, there is no getting around that when you use inheritance to achieve polymorphism. Haskell solves the "add a function later" problem by using type classes for polymorphism, this is a much less brittle approach. It is a bit like using interfaces and the adapter pattern in OO.
jystic 1 month ago
berserkguard 1 month ago
Very good tutorials on object programming. I would love to hear more of them from Misko Hevery. Good job.
PiesTfojegoPiesa 2 months ago
Misko is the man!
12ig0 3 months ago
All done with my evaluate() methods, now I want to implement toString()... Oh no! I have to modify every single class to do that :( So much for the open/close principle.
There's always a trade off here. Either you can make it easy to extend your data type or you can make it easy to add new operations on that data type.
Also I would argue that it's nicer to have all the evaluate() stuff in the same place and all the toString() stuff in the same place instead of spread across many classes/files.
jystic 3 months ago
@jystic
I thought about writing a Renderer class to do the printing job - originally I also wanted to write the toString method - and then I figured "what if I want to have OpenGL output? Or LaTeX?" . So I decided to seperate the structure from it's rendering - and now I'm trying to figure out a sensible way to make the renderer extensible. I think I'm on to something, but I haven't tried it yet.
narutofan9999 1 month ago
@jystic That's not very OO. Objects should have specific behavior. If the behavior of the object changes on state, then it's obvious that behavior belongs in it's own object. Your suggestion leads to brittle design, which is harder to maintain, test, and extend.
urMamaMuthaSukka 1 month ago
The speaker says that when using flags it's better to use polymorphism. In his example this is quite clear. But what if you have multiple flags in one class which can be set independently from each other? If you create subclasses for all possible combinations you end up with 2^n subclasses, in which n is the number of flags. Is there also a polymorphic way to solve this?
Tiddo1000 4 months ago
@Tiddo1000 In some languages you have multiple inheritance (python), or mixins (ruby). If not, you're a bit out of luck in that case.
MarkIJbema 4 months ago
@MarkIJbema even with MI you still have to create all these subclasses, since the baseclasses need to be combined first. The only advantage is that you don't have to duplicate functions. You'll still end up with 2^n subclasses.
Tiddo1000 4 months ago
@Tiddo1000 One way to achieve this is to use the decorator pattern to decorate your conditional with another conditional.
DanielGjorwell 1 month ago in playlist API Design
Also, getting rid of all if statements in a program is easy with a combination of template metaprogramming and lambda calculus. That doesn't mean it's easier to read though.
3243F6A8885 7 months ago
@3243F6A8885
Which is kinda bad considering that readability is the second most important quality of code after functionality.
narutofan9999 4 months ago
It seems like the examples were specifically chosen so that polymorphism could work. What happens if the state changes? You can't have one subclass instance magically turn into a different subclass. Not all switch statements switch over constants.
3243F6A8885 7 months ago
Comment removed
icilianfenner 6 months ago
Norwegian :D
klut1 8 months ago
Polymorphism can be described as an equation in Algebra I such as a+b = c. It's basically plugging in variables.
AugmentedMinor 9 months ago
Can I have the Bart slide?
wakeupfist 9 months ago
your talks are very clean, consise and contain good explanations. I blogged about 'avoiding if's in OOP' a few months ago before seeing this presentations. Right on the money... many people who aren't in the industry (posting comments) may not see the point in writing code this way but believe me... there are reasons.
rpocklin 10 months ago
Love to see a discussion about inheritance vs composition, in relation to this talk...
NerdCityLiving 1 year ago
So if I have object state flags where A=2 states, B=3 states, C=7, D=15 then all I need is 630 subclasses, then when the client comes along with another 4 state flag, I just have to write 1890 MORE subclasses.
I suppose I should name them Obj_A1_B3_C6_D1_E3 and so on? Then build an interpreter to transcode that name into some human readable form like - Obj_Homeowner_Canadian_Single_SalaryMoreThan40k_MetLife_Smoker?
mindprism 1 year ago
@mindprism Along the same lines maybe we could reduce code clutter by simplifying everything into Main() and DoSomething(XML systemwidestate, String verb, int intparm, int intparm2, double dblparm....):Object
mindprism 1 year ago 2
@mindprism You mean you have 630 'if' statements in one method?
TheKeinash 9 months ago
@TheKeinash I am just giving an example. You cant really subclass for every combination of attributes except in the most limited situations where extension is known and constrained. Even then it seems silly: EmployeeMarried, EmployeeSingle....
You are just making grief for yourself it seems to me.
mindprism 9 months ago
@mindprism if you have a lot of logic inside Employee, that depends on Relationship status it is a sign that you should subclass. But it would not be logical to subclass Employee, but rather to create RelationshipStatus class and subclass it into Single, Married and so on.
TheKeinash 9 months ago
@TheKeinash And what of my initial example of a health insurance client who has a database record with many attribute fields such that to subclass all the permutations would involve ~1000 subclasses?
Isn't there a practical limit to 'open/closed' design?
mindprism 9 months ago 2
@mindprism Oh, c'mon stop trolling and admit it: you don't like his idea without any good reason. In your last example even without subclassing it would be required to do a lot of routine coding. With subclassing you will have more readable code.
TheKeinash 9 months ago
@TheKeinash {With subclassing you will have more readable code.}
Code is not more readable if its spread across a lot of files. I can see what he is saying, but IMHO it doesnt get you very far.
mindprism 9 months ago 3
i watched that vid a few month ago.. how sweeeet my current system now look like..
Thank you veeery much to share that information!!
it changed my view of the world :-)
Stiba441 1 year ago
This has been flagged as spam show
i watched that vid a few month ago.. how sweeeet my current system now look like..
Thank you veeery much to share that information!
Stiba441 1 year ago
Comment removed
Stiba441 1 year ago
@Hax0rPr0n You're completely missing the point of the object oriented method and in particular an OO principle called the Open Closed Principle which states that software modules should be open for extension but closed for modification. This property allows us to add capabilities to a software system by adding new modules (i.e new subclasses) without incurring the risk of changing existing code. That's the main reason to favor inheritance over conditionals, it has nothing to do with clarity.
jfarr23 1 year ago 4
@Hax0rPr0n I agree, but i honestly think this is all just a matter of semantics. If it is appealing to read without IF statements who cares. And I do not think the if statement is a hard statement to discern ever, by anyone. Again it is like trying to wrap everything in a template rather than a macro. In practice and implementation a macro can be much easier to work with, however that may not be the "correct" way to do things. All in all i suppose I agree with you, i retract my previous comment.
nickrohn93 1 year ago 2
Comment removed
nickrohn93 1 year ago
OOP: the "art" of hiding from the programmer (or code reviewer) what is actually going on in the program
lukstafi 1 year ago
Comment removed
jihedamine 1 year ago
@jihedamine It's not about African people, it's about African swallows -- a Monty Python reference, which 80% of the geek viewers of the video are likely to get. (The "Norwegian Blue" in the example refers to another Monty Python sketch about a dead parrot.)
stephenbloch 1 year ago 5
@jihedamine
Are you suggesting that africans migrate?
Divinized 1 year ago
Great talk. Reinforced what I read in "Clean Code: A Handbook of Agile Software Craftsmanship", edited by Robert C. Martin (several contributors).
moktail 1 year ago
Can anyone explain the basic of this?
I mean, what's the point of doing this, when you just end up with the same result.
Omirion 1 year ago
@Omirion Going by his example; There's no reason to explicitly store the operator, when it can be handled implicitly by a single abstract method.
jazzjackrabbits 1 year ago
@Omirion Ending up with the same result is the whole point: we don't want to change the behavior of the program, only to refactor it so it's easier to read, easier to extend, and easier to test. As a bonus, a lot of the common mistakes beginners make with linked data structures (lists, trees, etc.) become type errors so they're caught by the compiler rather than being run-time exceptions.
stephenbloch 1 year ago
I love this guy's work.
berlinbrown03 2 years ago 4
quite good
jinqiangzhang 2 years ago
this man 100% right
mistulac 2 years ago 3
I created a Slot Machine in the procedural style with a ridiculously amount of if statements, apart from usability problems, the processor gets extremely over used and the program could easily crash!
javonoUTube 2 years ago
What if your class changed state often? how do you then use polymorphism?
omniscient232 2 years ago 3
Change the object that represents that state, in the same way that you would change the flag that represent that state.
bjakerr 1 year ago
ok. but wouldn't you have to switch alot of variables all the time, or are you talking about internal classes withing the class that is supposed to change state?
omniscient232 1 year ago
You would have to change the object-type variables exactly as many times as you would anyway have to change the flag-type variables. That you are using objects makes it no worse and no better.
bjakerr 1 year ago
Very simple examples, but as Misko points out, many experienced developers are abusing if/switch statements, and making their code difficult to maintain.
espinchi 2 years ago 2
Hesitant to watch since inheritance and polymorphism are mentioned in the title but not delegation.
ytatv 2 years ago
Go ahead, it's in there.
chrisbord 2 years ago
thanks Misko, I enjoy your talks
please post more!
neohubris 2 years ago 4
For subclassing Update ... what happens when you want to extend the functionality again? How do you reuse the code from both? Extend both? Then for each flag, your number of classes grows exponentially.
For the node example, you can't remove the if, just move them. And I would argue that using
switch(operator){ case '*': node = new MultiplyOperator();
...
is less readable than node = new Operator(operator), and will have to be duplicated more in any code that uses Operator.
magicalhobo87 3 years ago
I completely agree about Polymorphism. Unfortunately, I have a better idea about a programming language's basic functionality than I do how to construct classes, the basic construct statemetns, if I can overload functions... etc.
I do like Polymorphism enough to use it. "No if statements"-- what a challenge! I already love the challenge of hitting the DB as few times as possible. :3
TrueSoreThumb 3 years ago
This comment has received too many negative votes show
this guy doesn't know algebra. then a
disambiguation happens
zeno111111 3 years ago
I agree with jsmartin00, these should be available on a different channel so I can subscribe!
MarkOates 3 years ago 20
I once had the experience of a test we apply at work. My base implementation took about 10 seconds to process a 10000 records data set, which was in average good compared to another similar, OO engineered approaches.
Then, a student which didnt have a lot of experience with OO tackled the test, made the thing work and delivered it. It ran the same dataset in less than 1 second.
santizap 3 years ago 5
If Clean Code Talks becomes a regular series, please consider spinning it off into its own channel.
jsmartin00 3 years ago 5
damn noobs
ZeroMemPtr 3 years ago
You can get rid of all virtual dispatch by just using a few IFs here and there ;-)
BjarkeEbert 3 years ago 2
if statements are the most clear statements, they are great dont abolish them
CharlesDoub 3 years ago
Coding from the 70s, 80s, 90s, and 2000s, I wholeheartedly disagree. IF statements have their place, but 99.44% of all IF statements can productively be replaced with polymorphism.
hoser4 3 years ago 2
maybe they can be replaced ... but are the most easy to understand, like for "the clear code talks"
CharlesDoub 3 years ago
That depends entirely on your desired level of abstraction. Most IF statements serve only to disambiguate between two or more run-time types, perhaps types which cannot be expressed cleanly in the static type system. So, instead of having a big wad of IF or switch/case statements, you invoke an operation through a vector. Polymorphism is simply vectored execution implemented as a formal part of your language.
It makes code _immensely_ easier to understand.
hoser4 3 years ago
Polymorphism can be useful in circumstances -- in my experience - the religious use of it has lead to encounters the multi-moduled, obsenely confuzing obese code where a couple of seperate modules with a few simple straight forward faster executing switches would've been more than sufficient(especially since it's finished product not to be modified). Sometimes if you have 99 ditto flag chex - just shove a def/macro in there. Abusive religious over-use of OOP has made me very bitter. Grr.
SuperiorMind 3 years ago 7
@SuperiorMind I'm pretty new to OOP. Do you think you might be able to give a concrete example of this abuse/over-use of OOP?
mceldeen 1 year ago
Wouldn't recommend using this for every polymorphic problem... The number of classes will otherwise quickly grow to unmanageable numbers.
lordmetroid 3 years ago 7
Smalltalkers and Selfers might have a different opinion. :-)
Tia1ko 3 years ago
This comment has received too many negative votes show
This I learned at the seconds course of my education at the university... Why is pressures time and efforts invested in this?
lordmetroid 3 years ago
Because not everyone gets the opportunity to partake in the university system.
Also, it is precious, not pressures.
harking 3 years ago 12
lol
shreeksn 3 years ago
You learn about object graph instantiation with respect to unit testing?
Please, be patient when writing comments! lol
faustmen777 3 years ago