Code Like a Pro: Refactoring to Patterns!

Поделиться
HTML-код
  • Опубликовано: 24 ноя 2024

Комментарии •

  • @git-amend
    @git-amend  20 часов назад +15

    Happy Sunday! I really enjoy refactoring because IMO it's the best way to keep your programming skills sharp! I hope you do too! 👍

    • @ВалентинТерентьев-п4р
      @ВалентинТерентьев-п4р 17 часов назад

      I don't love refactoring because I can't reliably feel the line between refactoring and overengineering
      What I love, tho, is to receive notification about new git-amend video upload ❤

  • @bogoid
    @bogoid 19 часов назад +16

    Regarding what you mentioned about technical debt at the beginning, many years ago, during my first project as a lead, I had the opportunity to work with a very experienced architect, guy in his sixties I guess he must be retired by now. Well, one day, we were discussing a feature we needed to implement, but the timeline was pretty tight.
    I suggested we could do a basic, quick-and-dirty implementation and then "properly implement it later, after the release." He replied, "There's never a 'later'..."
    It took me some time and a few challenging projects under my belt to truly understand why he was so strict about technical debt... But Craig, if you're reading this, you were absolutely right!

    • @git-amend
      @git-amend  19 часов назад +4

      Hahaha, those are VERY wise words! Thanks for the comment!

  • @nickdevprod3667
    @nickdevprod3667 12 часов назад +3

    Super cool type of vieeos. Just let viewers send messy code and refractor it. Best way to learn something

    • @git-amend
      @git-amend  6 часов назад

      Thanks! More to come I'm sure!

  • @gonzaloasencio4503
    @gonzaloasencio4503 20 часов назад +8

    like that you bring advanced things and videos like these. Excellent work as always 😃

  • @lemetamax
    @lemetamax 19 часов назад +2

    This is really good! Nicely done.
    I actually learned the factory pattern from one of your previous videos. Now I use it everywhere possible. It ties cleanly with an object pooling system and jobs and burst.
    Please make more refactor videos like this one. And Happy Sunday!

    • @git-amend
      @git-amend  19 часов назад +1

      Great to hear! Thanks for the comment!

  • @oldshamen
    @oldshamen Час назад

    This type of video is awesome .. not only will it encourage programmers not to start over "because I know better now" but also shows how to use all the important programming patterns you have already taught in previous videos. Great work :)

  • @Mikso46
    @Mikso46 13 часов назад

    Hey there. I wanted to thank you from the bottom of my heart for all the amazing content you create. I'm a self-taught programmer and game dev, and after coding for 2 years, I hit a learning plateau. That is, until I discovered your channel. At first, I didn't fully grasp your videos, but I kept rewatching them over and over again, slowly refactoring my game's code. Nowadays, I feel like my code is on steroids, and it's all thanks to you

    • @git-amend
      @git-amend  6 часов назад

      Thanks for the kind words, very motivating!

  • @ewwitsantonio
    @ewwitsantonio 15 часов назад +1

    Absolutely love this refactoring video approach! It's so helpful to see the before and after, because I know so many of us work ourselves into corners and it can be quite hard to see a path out when you are too close to the project and have been looking at it from one perspective for too long. Thanks a lot for sharing these videos with us!

    • @git-amend
      @git-amend  15 часов назад

      You are so welcome!

  • @Luciphear
    @Luciphear 18 часов назад +2

    It's interesting to watch even though I knew the majority of concepts here, but there were some things that were new to me! It's a nice feeling to realize how much I've learned since I started. I really appreciate that you're giving good advice and habits right away despite being a bit more complex unlike many tutorials, that even I had to follow, which taught me some really awful habits that I had to spend a lot of time unlearning. It'll take time either way so better to take that time to learn than have to take the time later on unlearning and feeling unproductive because now you're kind of back to what feels like square one.

    • @git-amend
      @git-amend  18 часов назад

      I agree 💯 - thanks for the great comment!

  • @nickolasbrown2260
    @nickolasbrown2260 15 часов назад +1

    This is the type of youtube channel where u see ur first video and hit subscribe within 10 min

  • @grzegorzpedrycz2630
    @grzegorzpedrycz2630 20 часов назад +3

    Love that series :) My game code is so much better thanks to you !

  • @kyoseoul
    @kyoseoul 20 часов назад

    One of my favorite types of videos! I love seeing so many coding patterns in action. Some are still a bit tricky for me, but I was surprised to realize I’ve already used a few.
    Do you code like this in your own projects, or do you use more "niche" tools like R3 or other libraries/assets? I'd be curious to see some of your older code!

    • @git-amend
      @git-amend  20 часов назад

      Thanks for the comment! I actually don't use too many niche libraries - mostly it's just regular C# when I'm coding. Of course I do use my own systems, like the Service Locator, Event Bus, Improved Timers and the Unity Utility library that we keep adding to as well.

  • @Typtick
    @Typtick 18 часов назад

    Beautifully explained

  • @검은모래
    @검은모래 19 часов назад

    Thank you for the great video! I'll enjoy listening to it

    • @git-amend
      @git-amend  19 часов назад

      You're welcome! Thank you!

  • @JustLetMePickAFuckingUsername
    @JustLetMePickAFuckingUsername 14 часов назад

    Grest video as always. Cheers

  • @Haze_E1
    @Haze_E1 9 часов назад

    amazing content as usual 10/10

  • @techdave99
    @techdave99 20 часов назад

    Awesome. will watch again. could apply this to a toy i am working on.

    • @git-amend
      @git-amend  20 часов назад

      Nice! Glad you liked this one.

  • @bodardr
    @bodardr 18 часов назад

    Had a lot of refactoring to do this week as well. I ended up moving the factory pattern to the scriptable object directly, so it doesn't use a factory instance, plus I can override it in the child classes. I wonder what's your opinion on that. As always, keep up the good work, your code is top notch!

    • @git-amend
      @git-amend  18 часов назад +1

      Having a static factory method is a viable option, especially if you don't need to mock the factory for testing purposes. I do it fairly often actually. Thanks for the comment!

    • @bodardr
      @bodardr 18 часов назад

      Yeah when I can I love going static. But I actually meant moving the object creation to the WeaponConfig as a public function. That way you can make it virtual and override it for child Config classes. You could for instance load the projectile prefab for BowConfig or StaffConfig, or any kind of additional stuff. But in your scenario it was perfect because it was simple enough to not be required at all, since there's only WeaponConfig class for now.

  • @TheKr0ckeR
    @TheKr0ckeR 4 часа назад

    Nice video content mate! Where would we need enum in that case? Can we solve that differently, every time we add new item type, we also need to add enum, thats what i dont like about enums.

  • @GameDragon2k
    @GameDragon2k 19 часов назад

    @git-amend Sensei! Great video! Great way to showcase refactoring workflow. I have two questions regarding your setup. 1. How are you getting those Hierarchy Folders? 2. When you're doing null checks in Rider, I noticed there's a little icon there. What is that for?

    • @git-amend
      @git-amend  19 часов назад

      The folders are an Asset created by Sisus that is extremely useful, I'll add a link in the description of this video. Actually, I recommend (and own/use) all Assets made by that creator, especially InitArgs and Debug Extensions. The icon in Rider indicates an implicit check on Unity object lifetime, which is different from regular objects.

  • @DapperNurd
    @DapperNurd 6 часов назад

    Could you elaborate what the point of the interface for the Weapon is, when you just load it into the abstract class anyways? You could remove the interface from your code and have the exact same functionality.

    • @git-amend
      @git-amend  6 часов назад

      The interface ensures a clear contract for any weapon implementation. This approach comes from the "start from interfaces" principle, rooted in the Interface Segregation and Dependency Inversion principles of SOLID. While it may seem redundant with an abstract class, I almost always start refactoring classes that have things in common by first defining the interface they must all adhere to.

  • @ilkangamedev4477
    @ilkangamedev4477 13 часов назад

    Teşekkürler.

    • @git-amend
      @git-amend  6 часов назад

      Teşekkürler! Çok sağ ol, Süper için!

  • @Fitz0fury
    @Fitz0fury 18 часов назад

    This feels like someone wanted help transitioning from stephen Hubbards arpg course to something more scalable....

    • @git-amend
      @git-amend  18 часов назад

      Could be, I don't think I'm familiar with that one.

  • @akifemrebozdemir
    @akifemrebozdemir 16 часов назад

    How do you draw the line between refactoring and over engineering?

    • @git-amend
      @git-amend  15 часов назад +1

      Well, keep in mind that over engineering means adding features that were NOT requested. Refactoring is improving code so that you can facilitate changes that were requested. It's important to keep this in mind so you don't build things that are unnecessary, while still building the things that you do need in the best way you can for your skill level.

  • @guillem99
    @guillem99 20 часов назад

    8:29 Would it be acceptable to make WeaponFactory and its methods static?

    • @git-amend
      @git-amend  20 часов назад +3

      As it stands right now, you certainly could. However, one of the nice things about a Factory or Abstract Factory is it's use in testing - if you added an interface, it would be very easy to add a test version of the factory and just produce exactly the kinds of output that you need to executing test logic. We don't necessarily need it in this simple example, but injecting a factory is an extremely common practice. Another option you could go with, instead of a static factory, is have a static factory method on the WeaponConfig object so that it can create itself.

  • @mmertduman
    @mmertduman 19 часов назад

    I have no problem refactoring the code to the state you've shown in the video, but then things get more complicated and the patterns start to feel insufficient.
    For example, what if the bow needs additional config variables that the sword doesn't need? What if the staff needs the same? What if I make variations to the staff that all take different elemental attributes and their configs? Soon enough, each weapon would need its own "WeaponConfig". Its not the end of the world, but different weapons would need to cast the given WeaponConfig to their own config type, e.g. StaffConfig, BowConfig. Maybe there is a better way to handle this?
    The biggest pitfall I encounter is that the inheritance hierarchy that made sense the first time I'm writing it starts to make less and less sense as the project gets more complicated, and refactoring an inheritance tree is a mess.
    I really liked the IWeaponState refactoring that allowed each weapon type to implement its own Down/Up/Update functionality and still be driven by the WeaponController. Because the bow would probably need to aim before shooting, etc. And if a weapon needs additional variables to function correctly (instead of the simple target we get from Use(Transform target)), they can collect it during these 3 states. As I was watching, I was wondering how you'd handle that, and the solution makes a lot of sense to me!
    I would love to see more videos like this as the project gets more complicated. Even though your example has great coverage, the game is not really 'playable' from the POV of a consumer. At the later stages, I feel like patterns become a hassle to maintain as well. Nonetheless, they are much better than the initial code you showed at the beginning.

    • @git-amend
      @git-amend  19 часов назад

      Thanks for the comment. I'm sure we'll look at some more challenging scenarios in the future, maybe some works in progress from Discord.

    • @bodardr
      @bodardr 18 часов назад

      There's always generics. For instance I'm working on an inventory system, and I decided to make the item config as a generic parameter in my item class.
      So something like *Item where TConfig : ItemConfig*. That way the definition is always of the type you want it to be. So you'd have Bow : Weapon, Sword : Weapon. And they all inherit from the contract, either IWeaponConfig or WeaponConfigBase.
      But generics aren't perfect because sometimes you want to use a Weapon as a parameter, but you can't because it requires that generic argument now. You can't make an equip function that takes in Weapon, or Weapon, it won't compile (which is understandable). Solution? Weapon should inherit an interface or a base class that has no generic argument. Now you're good to go.
      I know this is a mouthful but the takeaway is : if you're going generics, it's great, but make sure you have no generics at the top.

    • @git-amend
      @git-amend  18 часов назад

      @@bodardr Great advice. Maybe a good topic for a future video as well.

    • @mmertduman
      @mmertduman 13 часов назад

      @@bodardr​​⁠ Yes, but as you said, functions still need to take the non-generic definition. How would your example work with the WeaponFactory shown in the video? The factory also needs to be generic then. Even so, i feel like there needs to be casting somewhere down the line. Same with the UI buttons which take in a List. How would that work? In my mind, if I need to cast the non-generic definition to one of the generic and concrete types, its not much different than casting at the weapon level. Maybe it does help, but Id need to sit down and try to code it to see. Nonetheless, I agree generics are great, especially for EventNotifier, Messaging etc patterns where by nature of the design you need to be able to work with any type of event, message, or payload.

  • @damonfedorick
    @damonfedorick 12 часов назад

    Nice! Only 50k more views.

  • @RonaldMcDonald-o5z
    @RonaldMcDonald-o5z 20 часов назад +1

    for the algo!

    • @git-amend
      @git-amend  20 часов назад +1

      Nice thank you!

  • @neinxxl1440
    @neinxxl1440 8 часов назад

    • @git-amend
      @git-amend  6 часов назад

      谢谢支持!😊

  • @PerroConChaleco
    @PerroConChaleco 16 часов назад

    How would you like taking a look into a project that already became a mountain of tech debt?

    • @git-amend
      @git-amend  15 часов назад

      How would I like it? Haha, well I have to do that a lot in my current work, and I can't say I like it too much. Nobody likes it, which is why it should be avoided in the first place. Of course, in the real world it does pay very well. But if you are asking me to consider looking at a specific project for a video, maybe before the next refactoring video I'll ask on Discord for some submissions.

  • @ilkangamedev4477
    @ilkangamedev4477 15 часов назад

    Thanks a lot can you upload 2K or 4k please :), High quality videos deserve higher resolution.

    • @git-amend
      @git-amend  6 часов назад

      I'll see what I can do!

  • @lee1davis1
    @lee1davis1 7 часов назад

    Interface question??? I see in most of your videos you write an interface then never edit it. This vid. You edited the interface three times then had to update all the scripts that implement it. My questioni is...Isn't it bad practice to ever edit an interface?

    • @git-amend
      @git-amend  6 часов назад

      Editing interfaces isn’t inherently bad practice, but it can lead to maintenance overhead as all implementing classes must be updated. If it’s your own code, it just requires some extra work. However, in published or shared code, changing an interface can break dependent systems, so be careful if you are doing that.