The Clean Code Talks - Don't Look For Things!

แชร์
ฝัง

ความคิดเห็น • 78

  • @josephmbimbi
    @josephmbimbi 4 หลายเดือนก่อน +4

    So many years later, this talk is still pure gold.

  • @zilongli4941
    @zilongli4941 ปีที่แล้ว +5

    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!

    • @jonberling
      @jonberling 7 หลายเดือนก่อน +1

      I first saw these talks in 2010, and I still go back and rewatch them from time to time.

  • @hosecoat
    @hosecoat 8 ปีที่แล้ว +27

    These talks by Misko have changed the way I code. Fantastic talk!

  • @AlexandriaRohn
    @AlexandriaRohn 6 ปีที่แล้ว +20

    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.

  • @tymekmajewski4718
    @tymekmajewski4718 11 ปีที่แล้ว +3

    This is a game changer for me. Simply great. Thanks for that.

  • @KDOERAK
    @KDOERAK 4 ปีที่แล้ว +1

    An ancient, but still very relevant & useful talk.

  • @glpathy
    @glpathy 7 ปีที่แล้ว

    Thanks Misko Hevery. Your session is delightful. Thoroughly enjoyed listening on the same.

  • @codinginflow
    @codinginflow 5 ปีที่แล้ว +2

    I love how he says "Printer"

  • @edg9382
    @edg9382 8 ปีที่แล้ว +38

    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.

    • @MaxwellPietsch
      @MaxwellPietsch 6 ปีที่แล้ว +7

      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.

    • @DanielHallmark
      @DanielHallmark 4 ปีที่แล้ว

      @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.

    • @NathanJohnson815
      @NathanJohnson815 4 ปีที่แล้ว

      ​@Frederik Hertzum Can you elaborate on what you mean by "pair of iterators"?

  • @MichaelKubler-kublermdk
    @MichaelKubler-kublermdk 11 ปีที่แล้ว

    This was really good. I've been wondering how to make my code better in this way and I finally understand it. Thank you!

  • @theren8311
    @theren8311 6 ปีที่แล้ว

    Paul's comedic timing was perfect.

  • @jessta314
    @jessta314 14 ปีที่แล้ว +1

    @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.

  • @froobly
    @froobly 10 ปีที่แล้ว +16

    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.

  •  8 หลายเดือนก่อน

    Still relevant as always!

  • @nacasadobeirinha1524
    @nacasadobeirinha1524 4 ปีที่แล้ว

    Amazing explanation man! Some concepts here help me a lot!

  • @Zeturic
    @Zeturic 6 ปีที่แล้ว +15

    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.

    • @piotreek7
      @piotreek7 6 ปีที่แล้ว +4

      Sagiri Exactly! Moreover - if we assume that we are always trusting ourselves, we can get rid of all test.

    • @kashperanto
      @kashperanto 6 ปีที่แล้ว +4

      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).

    • @Typhoonbladefist
      @Typhoonbladefist 6 ปีที่แล้ว +1

      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.

    • @perwestermark8920
      @perwestermark8920 2 ปีที่แล้ว

      @@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?

  • @kinkokonko
    @kinkokonko 15 ปีที่แล้ว +7

    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.

  • @zustaz
    @zustaz 4 ปีที่แล้ว +1

    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?

  • @softwareskills.jinqiang
    @softwareskills.jinqiang 14 ปีที่แล้ว

    simply good.

  • @magwo
    @magwo 14 ปีที่แล้ว +3

    @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.

  • @ParantapSharma
    @ParantapSharma 8 ปีที่แล้ว +5

    sut at 7:48 stands for system under test.

  • @rhamph
    @rhamph 15 ปีที่แล้ว

    (...)
    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.

  • @merocastle
    @merocastle 6 ปีที่แล้ว +1

    Is there a book where I can find out more about the things discussed in this video?

  • @Titousensei
    @Titousensei 14 ปีที่แล้ว

    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?

  • @simarpaul84
    @simarpaul84 15 ปีที่แล้ว

    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. :)

  • @tudorm6838
    @tudorm6838 10 ปีที่แล้ว +2

    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.

  • @BumblesTheUnicorn
    @BumblesTheUnicorn 11 ปีที่แล้ว

    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.

  • @minhtruong017
    @minhtruong017 9 ปีที่แล้ว

    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.

  • @miguel47
    @miguel47 15 ปีที่แล้ว

    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.

  • @tsooooooo
    @tsooooooo ปีที่แล้ว

    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

  • @ananang3648
    @ananang3648 11 ปีที่แล้ว

    good

  • @siben2628
    @siben2628 5 ปีที่แล้ว

    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 !

  • @michaeldeng1981
    @michaeldeng1981 13 ปีที่แล้ว +1

    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.

  • @sallylauper8222
    @sallylauper8222 5 ปีที่แล้ว

    In your country, you create object- in IOC, object create YOU!

  • @Chorofonfilo
    @Chorofonfilo 7 ปีที่แล้ว +3

    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.

    • @ondrejkunc753
      @ondrejkunc753 7 ปีที่แล้ว +2

      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

    • @MrGuardianX
      @MrGuardianX 7 ปีที่แล้ว +1

      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.

  • @GenericInternetter
    @GenericInternetter 10 ปีที่แล้ว

    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!

    • @HonestAuntyElle
      @HonestAuntyElle 9 ปีที่แล้ว +5

      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.

  • @twistedbydsign99
    @twistedbydsign99 14 ปีที่แล้ว

    11:55 it should definitely be an interface.

  • @rhamph
    @rhamph 15 ปีที่แล้ว

    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...)

  • @nonearus
    @nonearus 11 ปีที่แล้ว

    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.

  • @ParantapSharma
    @ParantapSharma 8 ปีที่แล้ว +1

    18:40 then why was the service locator design pattern defined??
    any use cases where it might be useful??

    • @oleksandrsova4803
      @oleksandrsova4803 7 ปีที่แล้ว

      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.

  • @RogerKeulen
    @RogerKeulen 11 ปีที่แล้ว

    Di: Great as a FXCop rule that forbid's you to compile.

  • @TakeshiYoung
    @TakeshiYoung 4 ปีที่แล้ว

    Hi, who is the owner of this channel? I am looking to purchase the username Salsa Vida, if that's possible.

  • @MarcelValdez
    @MarcelValdez 3 ปีที่แล้ว

    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!

  • @ParantapSharma
    @ParantapSharma 8 ปีที่แล้ว +6

    27:10 Null object design pattern it is...

    • @No3xx
      @No3xx 8 ปีที่แล้ว +1

      Thanks for spreading awareness of this simple but useful design pattern.

    • @ParantapSharma
      @ParantapSharma 8 ปีที่แล้ว

      Pleasure is mine

    • @kwanarchive
      @kwanarchive 7 ปีที่แล้ว +1

      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.

  • @mikemurko
    @mikemurko 12 ปีที่แล้ว

    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?

  • @MrGuardianX
    @MrGuardianX 7 ปีที่แล้ว

    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.

    • @Fizzlebania
      @Fizzlebania 7 ปีที่แล้ว

      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.

    • @FeroChau
      @FeroChau 7 ปีที่แล้ว

      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.

  • @urMamaMuthaSukka
    @urMamaMuthaSukka 11 ปีที่แล้ว

    Your car may not be able to build its own engine, but mine can.

  • @flowewritharoma
    @flowewritharoma 13 ปีที่แล้ว

    cool

  • @kinkokonko
    @kinkokonko 15 ปีที่แล้ว

    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

  • @siben2628
    @siben2628 5 ปีที่แล้ว

    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.

  • @kinkokonko
    @kinkokonko 15 ปีที่แล้ว

    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.

  • @bazcuda
    @bazcuda 3 ปีที่แล้ว +2

    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. 😂😂😂