Still watching this video on 2023! A video less than 40 mins takes me hours to complete because there are a lot to think , reflect and apply in my own code. Really learned a lot. Thanks for sharing!
21:00 How many factories do you need? In theory, one factory for all of the objects of the same lifetime. In practice, we break it down further for code sensibility. 28:37 You want to abandon new operator in 99% of cases. But sometimes it's okay. Instantiating a hash map? Okay. How about a value object like a user? Fine. The key is that these objects are the leaves of your application -- the end of the road. 29:30 No need to know about objects you don't directly need -- Law of Demeter. 30:20 Think of objects as two categories: 1) Your pile of business logic. This is where most of your bugs are. You want these easy to instantiate. 2) Your pile of factories, new operators, builders, etc.
Excellent content; but I really disagree on the null checking part. The thing is: fields and methods of your classes should be very tightly coupled. If you have a lot of methods that don't need a certain field (and thus would be fine having that field to be null) then I should not worry if I can allow that field to be null. Then I should be asking myself: why do I have so many methods in that class that don't need that field? In other words: if you find that some set of fields is used by one half of your methods, and the other methods all use other fields ... then maybe those fields and methods better go into TWO different classes.
I agree. I mean if the object can operate with a null parameter, then it could have a constructor which doesn't receive that parameter at all. He makes the argument that passing in Door is not essential for the test of the House color, but I feel like external users of the House API shouldn't know exactly how Door is used anyways. So maybe Door is essential for testing the color, or maybe it isn't. Either way it's not known to the test. But like you, I respect the talk and got a lot from it. Little questions like whether it's best to check parameters for null or not people will continue to debate, and I might have a different opinion about in a few years.
@Frederik Hertzum This sounds a lot like the Service Locator anti-pattern. There is a separate talk about that. The problem caused by service locator is that users of the api (such as a test case) have no way of knowing the real requirements because the code is reaching through the service locator to try and find what it needs. This violates the Law of Demeter. It complicates test setup and when requirements of a class change the code still compiles but fails in mysterious ways at runtime because the locator (your collection) doesn't contain the new dependency.
25:45 "What you're really saying is that you don't trust yourself". You *shouldn't* trust yourself. You are the number one source of bugs in your code. By putting your intent in code, you can leverage the compiler and runtime to help ensure you never violate your intent, even if you're tired or otherwise not coding at your maximum ability. Runtime pre-conditions are good, compile time checking is even better.
There is a difference between not trusting yourself to pass a null into your own function vs not trusting yourself to implement a feature correctly. Checking for null/invalid parameters is literally a waste of time unless others will be using your code. These kinds of issues would pop up in your integration or system level tests. Focus your efforts on the checks that have a chance of failing (which, in a public-facing API in a library/etc does involve null checks).
Sagiri look at it this way, if I were building a box out of wood, I'll trust the boards I measured and cut myself because I know I measured it. I'd definitely double check the boards cut for me by some random busy guy at Home Depot that might not even measure correctly. That's when you will test for null, external untrusted sources.
@@Typhoonbladefist But you just said you measured your boards. So you tested. And maybe you measured your boards. And later realized you misunderstood if the dimension was inside or outside dimension - and did cut wrong. A huge amount of bugs comes from incorrect assumptions. So when possible, it tends to help to verify assumptions at runtime. Because even module test code is based on assumptions - that are sometimes wrong. The video complains about needing to read the code to know what is needed from that locator. But assumes we *don't* need to read the code to know if the door is important or not for painting the house. If you paint a car, then the huge majority of cars has same color for doors and the other parts. Why is it unreasonable to believe a house implementation may care about doors for the paint operation? So why allow null door? And why see it wrong to test for null door?
With regards to the wallet/credit card issue, it's a bit more nuanced than he and the commenter let on. When you give the cashier your credit card, you're not giving them your entire wallet (a global settings object), you're giving them a "money" object that works regardless of how many physical bills you have in your wallet. It's the same concept as a future in Java. You may not know the correct value immediately, but you have a way of calculating that value at some point, so instead of passing the value, you pass your value-getting function, and law of demeter is maintained.
This is a very good overview though I find views agaist precondition checks very contencious. Basically if you contend new House(null) is valid you are saying that the internal state of the House is ok without a Door. This may not be true. It is often better to ensure the consistent validity of an objects creation upfront rather than allow system fail 2 weeks after booting. I would advise Mocking to Door regardless of your test to only paint it. Donot increase the chances of bugs for ease.
Great talk! Remember that "your tests is the first client of your code". So if you cannot write easy tests that uses your solution how "the client" can?
@MattCrypto The great thing about nulls is that you instantly knows when the code under test has changed. The null pointer exception you get is a good signal.
@Titousensei I think it's mostly considered OK to have globally available loggers, due to one important detail - information flows only to such an object, not from them. You will really never have code that inspects the recently entered log messages, and make decisions based on that data. What one object logs does not affect what other objects do.
(...) In theory (depending on the language, etc) you could have a signaling-dummy-factory that gets passed in an interface. It would then return an object that acts like null, but claims to support the desired interface (or be the desired type). Pragmatically, that's a bit bulky, and with a safe language you can usually just remove the null checks.
Nice... but a dummy object, instantiated and passed for test is not useful just to avoid exceptions; could be useful for "simulate" operations, execute dummy operations, that , for example, will log something instead of execute.
Interesting talk with good points, but it feel like workarounds for the deficiencies of OOP. I would at least use more traits, e.g: a 'Paintable' interface for the house, then you don't need to care about the doors and windows etc
The point is that there should be a separate HouseFactory that is responsible for wiring up the House object. The unit test for the HouseFactory makes sure that Doors are included, the House itself doesn't perform the test.
The problem is that the language uses null to mean "no object needed", whereas the speaker wants it to mean "signaling dummy". The type checking should exclude the former, but not the latter. It's a problem of the language that null exists for every type, rather than requiring a union (or similar polymorphic declaration.) (blah length limit...)
Very insightful talk that stresses the point that every module/method/constructor should ask for what it needs (dependencies) explicitly. Global State, whether it is from a Singleton/Public Static Instance should be avoided. It may be better than contex/aspect oriented progamming. Dependecies if passed argument(s), we would know what it needs at compile time; whether a dependency is missing in the context, would be known at run-time when context.get(..) gives null. :)
if I do outsourcing project, or do a contract project, after delivery I'm done. why should I write unit test. what I care is integration testing and system testing. This can explains why contract project has low maintainability in general.
If the house can be built without a door in first place, then why making only one constructor for such object with a door passed in?. Make two constructors, and let the tests do their job with the needed/unneeded objects according to each constructor make sense scenario. Now, if the purpose of such test is to pinpoint the developer that he/she missed a constructor according to the user case, then it does makes sense.
I don't fully agree. When you have some kind of 'service' object, you want to pass all of the references in one constructor. It doesn't matter if some parts of this object won't use all the references. It could make sense in a test, where you know exactly what should be passed in the constructor to satisfy the test. Now imagine someone else want to use your house object and uses constructor without doors and then calls method buildHouse(), which internally uses doors and BOOM - null reference exception. That user would be very confused, because he didn't do anything wrong, he just created object with perfectly valid constructor and calls method on it. On the other hand, if you offered him only one constructor with doors and let him pass null, then it should be more obvious, that problem is on his side, since he ignores the constructor parameter. Moreover if you provide different constructors for different use cases, your constructor count will grow exponentionally and it would become hell to maintain it. The problem with this example is that it is quite clumsy. House is not a typical business object, you would call methods on and do some complicated logic. Is more like the Document object in the video, which shouldn't be aware how is it build. In case you would need to build it with optinal door, I would use some kind of builder patter and construct it like this: House house = houseBuilder.addDoor(door).build(); Hope this makes sense
If you have several constructors you probably forsee this scenario. If not, it means your house object shouldn't have the buildHouse method in the first place, since it is obvious that its internal structure is not highly cohesive.
Yeah, I'm not sure why he didn't just suggesting overloading the constructor so that one takes an Engine directly and the other builds one from a factory. Then you can easily instantiate it in the test as well as avoid having to keep reinstantiating Engines when you actually want to use it for real. It increases the coupling slightly, but might be worth it depending on the application.
Not mandatory constructor parameters should have internal default implementation (as Null Object Pattern for example) and should be excluded of some constructor. Then construtors with this parameter should enforce the non nullity of mandatory arguments). Like that everyone is happy !
Misko just opened up my eyes to null checking! I always thought it was stupid to null check, because all i'm doing is making the code "correct itself". he's right... gotta learn to trust yourself!
I feel like the preconditions checking for accidental null usage is more valuable then the information gained in the tests, passing in null unintentionally should fail fast and tell you what is wrong (Ideally if you don't want null as a possible value it should fail in compilation as opposed to runtime) If you truly want to show that a class isn't used in a test, use a "mock Object" that throws exceptions if any of its methods are called.
what if a service locator wrap inside of a factory that return the object the constructor is asking for will it still violate the law of demeter? so now if we want a house we ask for a house from the factory which deal with service locator to wire up the house object.
That's very interesting. But how do you deal with non-essential objects that are possibly needed throughout the code, such as a Logger. Should I pass the global logger to each constructor so that each of their methods can log some messages? Or is it OK to use a singleton in this case?
The only one reasonable use case to use service locator, any sort of ContainerAware, etc. as I see is get rid of CircularReferenceException if you just haven't found another way yet.
Isn't the main difference between a service locator and "passing things into the constructor" just a syntactic limitation of java (and most other languages besides)? All the problems mentioned could even be solved within Java by providing a sufficiently smart IDE and a first class service locator. He is arguing against out-of-band dependency passing. I would argue that sometimes you just need default passing to be hidden, and when you need to test, you would just introspect and override them.
I dont understand how in this case Service Locator pettern is different from IoCC for which the speaker is fighting. Also, Service Locator is NOT responsible for instantiating the classes, it is only responsible for storing them and retrieving where needed. THe example with Customer is very odd actually. Since Service Locator would actually contain the interface reference to service working with Customers, not the actual Customer. In this case the Customer class is perfectly instantiatable elsewhere, including tests. Your client code doesn't care where that Customer actually coming from - Service Locator or directly instantiated object itself. And Service Locator is not responsible for creating customers - this is a great misconception here.
The Customer example makes another analogy what is wrong with the Service Locator and it is not about Service Locator directly. House and Locator is the clever example of this anti-pattern. I think that, kind of a Context always should appear on a some level of abstraction. It's just about not leaking contexts to the domain code. Probably when you're using an IoC system the Context stuff is going there under the hood, but you don't want to use it directly.
When you inject the dependency of a service locator to a constructor and using it to retrieve other objects, you violate the Law of Demeter because you are not directly using the object but using it to retrieve other objects and perform actions on those retrieved objects. The speaker has also explained the disadvantages of violating the Law of Demeter.
26:21 The problem with not checking for null in the constructor, is that now you must check for null inside every method that *does* need a door, and technically you also need to write a test for every method that used Door where you set door to null in the test. So what would you rather do? A.Write a SINGLE null-checking precondition (and then forget about the possibility of door being null) or, B. (1) check for null inside every method that uses door and (2) write an additional test for every null check in every method that uses Door? B. Leaves your code with many opportunities to create bugs and requires more tests and A. has fewer opportunities for bugs to get in and requires fewer tests. I like the 'spirit' of this talk, but this guy is making some crucially bad recommendations. I find it a bit funny that at the end he says "by doing this you're just saying you don't trust yourself", that's CORRECT! Don't trust yourself! We're human we get tired, we're in a rush, we make mistakes (and if you don't someone else changing your code will!), of course, we shouldn't trust ourselves to write perfect code!
6:10 I think the reason people code in that way is because they are trying to promote code re-use. They don't want to have to instantiate EngineFactory a zillion times in their application if they know a car will always need an engine. I know it may not be good DI, but from the angle of code re-use, why is that so bad?
You seem to be missing the point. If it is invalid to have a house without a door you should never compromise the system stability based on laziness in the test. On responsibilitis. Sure you can test the door in isolation but your main responsibility is to produce water tight code. I thinhk his ideas on 'null' are wrong, Null can be considered a friend, that is is you like friends that jump up a cut your throat in your sleep ;-) JSR 308 is a far more improved approach to null checks
I understand that hidden dependencies are bad. Then they should be well documented. I am not sure that Registry objects are that bad : in fact they make objects more autonomous about their relationships with other objects. If I tell something to an object but it cannot fulfill itself the task, it should be able to ask to an other object of its acquaintances to do it, and I am not responsible to provide directly this secondary object, but the first called object itself is. However I am responsible to provide a manner to locate the object. Directly by injecting a Repository, or indirectly by setting the required Repository (or a mock for tests) into the Registry oblect.
34:36 "So, I'm gonna ask for questions now" Misko should have paid attention to his own presentation. What he should have actually done is to have told the audience which questions he wanted to receive. Much easier. 😂😂😂
You are still missing the point. He is meaning you should use null even for mandatory parameters , as you may be testing a method that doesnt use them. i.e you safe your selve a Mock. Even he doesnt mean this the whole part of the talk is meaningless This is wrong and pure lazines. thank god he doesnt design Space shuttles, i.e. it would be nice and painted , but when you hit start it would blow up as you havent asserted the flight control is in place.
So many years later, this talk is still pure gold.
Still watching this video on 2023! A video less than 40 mins takes me hours to complete because there are a lot to think , reflect and apply in my own code. Really learned a lot. Thanks for sharing!
I first saw these talks in 2010, and I still go back and rewatch them from time to time.
These talks by Misko have changed the way I code. Fantastic talk!
21:00 How many factories do you need? In theory, one factory for all of the objects of the same lifetime. In practice, we break it down further for code sensibility.
28:37 You want to abandon new operator in 99% of cases. But sometimes it's okay. Instantiating a hash map? Okay. How about a value object like a user? Fine. The key is that these objects are the leaves of your application -- the end of the road.
29:30 No need to know about objects you don't directly need -- Law of Demeter.
30:20 Think of objects as two categories:
1) Your pile of business logic. This is where most of your bugs are. You want these easy to instantiate.
2) Your pile of factories, new operators, builders, etc.
This is a game changer for me. Simply great. Thanks for that.
An ancient, but still very relevant & useful talk.
Excellent content; but I really disagree on the null checking part.
The thing is: fields and methods of your classes should be very tightly coupled. If you have a lot of methods that don't need a certain field (and thus would be fine having that field to be null) then I should not worry if I can allow that field to be null.
Then I should be asking myself: why do I have so many methods in that class that don't need that field?
In other words: if you find that some set of fields is used by one half of your methods, and the other methods all use other fields ... then maybe those fields and methods better go into TWO different classes.
I agree. I mean if the object can operate with a null parameter, then it could have a constructor which doesn't receive that parameter at all.
He makes the argument that passing in Door is not essential for the test of the House color, but I feel like external users of the House API shouldn't know exactly how Door is used anyways. So maybe Door is essential for testing the color, or maybe it isn't. Either way it's not known to the test.
But like you, I respect the talk and got a lot from it. Little questions like whether it's best to check parameters for null or not people will continue to debate, and I might have a different opinion about in a few years.
@Frederik Hertzum This sounds a lot like the Service Locator anti-pattern. There is a separate talk about that. The problem caused by service locator is that users of the api (such as a test case) have no way of knowing the real requirements because the code is reaching through the service locator to try and find what it needs. This violates the Law of Demeter. It complicates test setup and when requirements of a class change the code still compiles but fails in mysterious ways at runtime because the locator (your collection) doesn't contain the new dependency.
@Frederik Hertzum Can you elaborate on what you mean by "pair of iterators"?
I love how he says "Printer"
25:45 "What you're really saying is that you don't trust yourself".
You *shouldn't* trust yourself. You are the number one source of bugs in your code. By putting your intent in code, you can leverage the compiler and runtime to help ensure you never violate your intent, even if you're tired or otherwise not coding at your maximum ability. Runtime pre-conditions are good, compile time checking is even better.
Sagiri Exactly! Moreover - if we assume that we are always trusting ourselves, we can get rid of all test.
There is a difference between not trusting yourself to pass a null into your own function vs not trusting yourself to implement a feature correctly. Checking for null/invalid parameters is literally a waste of time unless others will be using your code. These kinds of issues would pop up in your integration or system level tests. Focus your efforts on the checks that have a chance of failing (which, in a public-facing API in a library/etc does involve null checks).
Sagiri look at it this way, if I were building a box out of wood, I'll trust the boards I measured and cut myself because I know I measured it. I'd definitely double check the boards cut for me by some random busy guy at Home Depot that might not even measure correctly. That's when you will test for null, external untrusted sources.
@@Typhoonbladefist But you just said you measured your boards. So you tested.
And maybe you measured your boards. And later realized you misunderstood if the dimension was inside or outside dimension - and did cut wrong.
A huge amount of bugs comes from incorrect assumptions. So when possible, it tends to help to verify assumptions at runtime. Because even module test code is based on assumptions - that are sometimes wrong.
The video complains about needing to read the code to know what is needed from that locator. But assumes we *don't* need to read the code to know if the door is important or not for painting the house. If you paint a car, then the huge majority of cars has same color for doors and the other parts. Why is it unreasonable to believe a house implementation may care about doors for the paint operation? So why allow null door? And why see it wrong to test for null door?
With regards to the wallet/credit card issue, it's a bit more nuanced than he and the commenter let on. When you give the cashier your credit card, you're not giving them your entire wallet (a global settings object), you're giving them a "money" object that works regardless of how many physical bills you have in your wallet.
It's the same concept as a future in Java. You may not know the correct value immediately, but you have a way of calculating that value at some point, so instead of passing the value, you pass your value-getting function, and law of demeter is maintained.
WOW iLove that reply an ClevverObservation
This is a very good overview though I find views agaist precondition checks very contencious. Basically if you contend new House(null) is valid you are saying that the internal state of the House is ok without a Door. This may not be true. It is often better to ensure the consistent validity of an objects creation upfront rather than allow system fail 2 weeks after booting. I would advise Mocking to Door regardless of your test to only paint it. Donot increase the chances of bugs for ease.
Great talk!
Remember that "your tests is the first client of your code". So if you cannot write easy tests that uses your solution how "the client" can?
Thanks Misko Hevery. Your session is delightful. Thoroughly enjoyed listening on the same.
@MattCrypto The great thing about nulls is that you instantly knows when the code under test has changed. The null pointer exception you get is a good signal.
@Titousensei I think it's mostly considered OK to have globally available loggers, due to one important detail - information flows only to such an object, not from them. You will really never have code that inspects the recently entered log messages, and make decisions based on that data. What one object logs does not affect what other objects do.
Paul's comedic timing was perfect.
sut at 7:48 stands for system under test.
Still relevant as always!
Is there a book where I can find out more about the things discussed in this video?
(...)
In theory (depending on the language, etc) you could have a signaling-dummy-factory that gets passed in an interface. It would then return an object that acts like null, but claims to support the desired interface (or be the desired type).
Pragmatically, that's a bit bulky, and with a safe language you can usually just remove the null checks.
Nice... but a dummy object, instantiated and passed for test is not useful just to avoid exceptions; could be useful for "simulate" operations, execute dummy operations, that , for example, will log something instead of execute.
Interesting talk with good points, but it feel like workarounds for the deficiencies of OOP. I would at least use more traits, e.g: a 'Paintable' interface for the house, then you don't need to care about the doors and windows etc
This was really good. I've been wondering how to make my code better in this way and I finally understand it. Thank you!
The point is that there should be a separate HouseFactory that is responsible for wiring up the House object. The unit test for the HouseFactory makes sure that Doors are included, the House itself doesn't perform the test.
Amazing explanation man! Some concepts here help me a lot!
The problem is that the language uses null to mean "no object needed", whereas the speaker wants it to mean "signaling dummy". The type checking should exclude the former, but not the latter. It's a problem of the language that null exists for every type, rather than requiring a union (or similar polymorphic declaration.)
(blah length limit...)
Very insightful talk that stresses the point that every module/method/constructor should ask for what it needs (dependencies) explicitly. Global State, whether it is from a Singleton/Public Static Instance should be avoided.
It may be better than contex/aspect oriented progamming. Dependecies if passed argument(s), we would know what it needs at compile time; whether a dependency is missing in the context, would be known at run-time when context.get(..) gives null. :)
if I do outsourcing project, or do a contract project, after delivery I'm done. why should I write unit test. what I care is integration testing and system testing.
This can explains why contract project has low maintainability in general.
If the house can be built without a door in first place, then why making only one constructor for such object with a door passed in?. Make two constructors, and let the tests do their job with the needed/unneeded objects according to each constructor make sense scenario.
Now, if the purpose of such test is to pinpoint the developer that he/she missed a constructor according to the user case, then it does makes sense.
I don't fully agree. When you have some kind of 'service' object, you want to pass all of the references in one constructor. It doesn't matter if some parts of this object won't use all the references. It could make sense in a test, where you know exactly what should be passed in the constructor to satisfy the test.
Now imagine someone else want to use your house object and uses constructor without doors and then calls method buildHouse(), which internally uses doors and BOOM - null reference exception. That user would be very confused, because he didn't do anything wrong, he just created object with perfectly valid constructor and calls method on it.
On the other hand, if you offered him only one constructor with doors and let him pass null, then it should be more obvious, that problem is on his side, since he ignores the constructor parameter.
Moreover if you provide different constructors for different use cases, your constructor count will grow exponentionally and it would become hell to maintain it.
The problem with this example is that it is quite clumsy. House is not a typical business object, you would call methods on and do some complicated logic. Is more like the Document object in the video, which shouldn't be aware how is it build. In case you would need to build it with optinal door, I would use some kind of builder patter and construct it like this:
House house = houseBuilder.addDoor(door).build();
Hope this makes sense
If you have several constructors you probably forsee this scenario. If not, it means your house object shouldn't have the buildHouse method in the first place, since it is obvious that its internal structure is not highly cohesive.
Yeah, I'm not sure why he didn't just suggesting overloading the constructor so that one takes an Engine directly and the other builds one from a factory. Then you can easily instantiate it in the test as well as avoid having to keep reinstantiating Engines when you actually want to use it for real. It increases the coupling slightly, but might be worth it depending on the application.
Not mandatory constructor parameters should have internal default implementation (as Null Object Pattern for example) and should be excluded of some constructor. Then construtors with this parameter should enforce the non nullity of mandatory arguments). Like that everyone is happy !
Misko just opened up my eyes to null checking!
I always thought it was stupid to null check, because all i'm doing is making the code "correct itself". he's right... gotta learn to trust yourself!
I feel like the preconditions checking for accidental null usage is more valuable then the information gained in the tests, passing in null unintentionally should fail fast and tell you what is wrong (Ideally if you don't want null as a possible value it should fail in compilation as opposed to runtime)
If you truly want to show that a class isn't used in a test, use a "mock Object" that throws exceptions if any of its methods are called.
simply good.
what if a service locator wrap inside of a factory that return the object the constructor is asking for will it still violate the law of demeter? so now if we want a house we ask for a house from the factory which deal with service locator to wire up the house object.
That's very interesting. But how do you deal with non-essential objects that are possibly needed throughout the code, such as a Logger. Should I pass the global logger to each constructor so that each of their methods can log some messages? Or is it OK to use a singleton in this case?
18:40 then why was the service locator design pattern defined??
any use cases where it might be useful??
The only one reasonable use case to use service locator, any sort of ContainerAware, etc. as I see is get rid of CircularReferenceException if you just haven't found another way yet.
27:10 Null object design pattern it is...
Thanks for spreading awareness of this simple but useful design pattern.
Pleasure is mine
Well, in this day an age, you should use Optional types as the way to add a null object state to your design rather than pollute the original class.
Isn't the main difference between a service locator and "passing things into the constructor" just a syntactic limitation of java (and most other languages besides)? All the problems mentioned could even be solved within Java by providing a sufficiently smart IDE and a first class service locator.
He is arguing against out-of-band dependency passing. I would argue that sometimes you just need default passing to be hidden, and when you need to test, you would just introspect and override them.
In your country, you create object- in IOC, object create YOU!
Hi, who is the owner of this channel? I am looking to purchase the username Salsa Vida, if that's possible.
I dont understand how in this case Service Locator pettern is different from IoCC for which the speaker is fighting. Also, Service Locator is NOT responsible for instantiating the classes, it is only responsible for storing them and retrieving where needed. THe example with Customer is very odd actually. Since Service Locator would actually contain the interface reference to service working with Customers, not the actual Customer. In this case the Customer class is perfectly instantiatable elsewhere, including tests. Your client code doesn't care where that Customer actually coming from - Service Locator or directly instantiated object itself. And Service Locator is not responsible for creating customers - this is a great misconception here.
The Customer example makes another analogy what is wrong with the Service Locator and it is not about Service Locator directly. House and Locator is the clever example of this anti-pattern. I think that, kind of a Context always should appear on a some level of abstraction. It's just about not leaking contexts to the domain code. Probably when you're using an IoC system the Context stuff is going there under the hood, but you don't want to use it directly.
When you inject the dependency of a service locator to a constructor and using it to retrieve other objects, you violate the Law of Demeter because you are not directly using the object but using it to retrieve other objects and perform actions on those retrieved objects. The speaker has also explained the disadvantages of violating the Law of Demeter.
good
26:21 The problem with not checking for null in the constructor, is that now you must check for null inside every method that *does* need a door, and technically you also need to write a test for every method that used Door where you set door to null in the test.
So what would you rather do? A.Write a SINGLE null-checking precondition (and then forget about the possibility of door being null) or, B. (1) check for null inside every method that uses door and (2) write an additional test for every null check in every method that uses Door? B. Leaves your code with many opportunities to create bugs and requires more tests and A. has fewer opportunities for bugs to get in and requires fewer tests. I like the 'spirit' of this talk, but this guy is making some crucially bad recommendations.
I find it a bit funny that at the end he says "by doing this you're just saying you don't trust yourself", that's CORRECT! Don't trust yourself! We're human we get tired, we're in a rush, we make mistakes (and if you don't someone else changing your code will!), of course, we shouldn't trust ourselves to write perfect code!
11:55 it should definitely be an interface.
6:10 I think the reason people code in that way is because they are trying to promote code re-use. They don't want to have to instantiate EngineFactory a zillion times in their application if they know a car will always need an engine. I know it may not be good DI, but from the angle of code re-use, why is that so bad?
Di: Great as a FXCop rule that forbid's you to compile.
You seem to be missing the point. If it is invalid to have a house without a door you should never compromise the system stability based on laziness in the test. On responsibilitis. Sure you can test the door in isolation but your main responsibility is to produce water tight code. I thinhk his ideas on 'null' are wrong, Null can be considered a friend, that is is you like friends that jump up a cut your throat in your sleep ;-) JSR 308 is a far more improved approach to null checks
I understand that hidden dependencies are bad. Then they should be well documented. I am not sure that Registry objects are that bad : in fact they make objects more autonomous about their relationships with other objects. If I tell something to an object but it cannot fulfill itself the task, it should be able to ask to an other object of its acquaintances to do it, and I am not responsible to provide directly this secondary object, but the first called object itself is. However I am responsible to provide a manner to locate the object. Directly by injecting a Repository, or indirectly by setting the required Repository (or a mock for tests) into the Registry oblect.
cool
34:36 "So, I'm gonna ask for questions now"
Misko should have paid attention to his own presentation. What he should have actually done is to have told the audience which questions he wanted to receive. Much easier. 😂😂😂
Your car may not be able to build its own engine, but mine can.
You are still missing the point. He is meaning you should use null even for mandatory parameters , as you may be testing a method that doesnt use them. i.e you safe your selve a Mock. Even he doesnt mean this the whole part of the talk is meaningless
This is wrong and pure lazines. thank god he doesnt design Space shuttles, i.e. it would be nice and painted , but when you hit start it would blow up as you havent asserted the flight control is in place.