Singletons & Service Locators

Sdílet
Vložit
  • čas přidán 29. 08. 2024

Komentáře • 25

  • @mariomastrandrea4165
    @mariomastrandrea4165 Před 3 lety +3

    Very High Quality explanations, you deserve much more audience. I found it super super useful, thank you very much.
    I suggest you to make more video like this, in which you could give us some other advices about design pattern or good programming practices, because I think you have very good teaching qualities

  • @soverain
    @soverain Před 3 lety +7

    Another problem that comes with using GameObject Singletons is "scene ownership". Your singleton lives in a particular scene, and every time you want to test another scene in isolation that has references to that singleton, it's a pain in the butt. Basically you need to add all the "Managers" and global instances in order to have a working scene.
    I found myself using less and less the singleton pattern for this exact reason. Lately I've been switching to ScriptableObjects to hold global state. The neat thing is you can make them as singletons too! if you want! But this time, if you put them in a Resources folder and load them from here, you can access them everywhere, every-time, without the need of a scene instance.

    • @matthewventures
      @matthewventures  Před 3 lety

      Very cool, I've been doing something similar. Though in my case I have a global manager which has a reference to a scriptable object. Is that what you mean by making the scriptableobject itself as Singleton? Otherwise I don't know if I'm too sure how to do that

    • @soverain
      @soverain Před 3 lety

      @@matthewventures No, I meant a static reference to a class derived from ScriptableObject. I wrote an article about that subject, but it's in French. You could try to google translate it I guess, and code snippets are in English: www.samuelduval.fr/posts/scriptable-object-singletons/
      It's based on a talk by Richard Fine if you're interested. It's called "Overthrowing the MonoBehaviour Tyranny in a Glorious ScriptableObject Revolution".

  • @batuaytemiz6437
    @batuaytemiz6437 Před 3 lety +1

    Very solid work! ServiceLocator is an underutilized technique (compared to pure Singletons).

  • @iCeDrAgOn2025
    @iCeDrAgOn2025 Před rokem +2

    I know that this video is about a year old or more. But even at that time, Unity wasn't exclusively a single-threaded engine. As soon as you step into the realm of the Scriptable Render Pipeline, which the HDRP and URP are members of, You then start to see Unity relying more on the burst compiler and the creation of multithreaded jobs. Even though Unity does a good job at protecting the user, there are still conditions where these patterns could be an issue. Especially if you start using the job system yourself.

  • @MrSubZeron
    @MrSubZeron Před 2 lety +1

    Thank you for the great explenation. Now at least I know the name of something I´ve been using the whole time and even funnier, I thought I invented this pattern XD Thank you sir for your time and efforts :)

    • @matthewventures
      @matthewventures  Před 2 lety

      You're welcome. You can checkout the "Programming Patterns
      " section of my book here: tinyurl.com/gamedevStudySheet
      It will cover these patterns and others that may be of interest to you.

  • @INeatFreak
    @INeatFreak Před 2 lety

    I've changed this into a static class that has a Register method for my main systems (AudioSystem, SaveSystem etc) to register themselves and I get references on Start() at my custom scripts

    • @matthewventures
      @matthewventures  Před 2 lety

      What do you do if a service is requested before it has registered itself?

    • @INeatFreak
      @INeatFreak Před 2 lety

      @@matthewventures i have a TryGet method that returns bool and outs the MonoBehaviour, when not registered it just returns false. Main systems Register themselves at Awake (so they're available to access at Start) and Unregister at OnDestroy or OnDisable

    • @INeatFreak
      @INeatFreak Před 2 lety

      I did this because I don't like having Manager singleton instances in my scene, they're annoying to manage across multiple scenes. It's also shorter to access instead of ServiceLocator.instance.GetService, I just type ServiceLocator.TryGet.
      Also more performant as there's no FindObjectOfType calls when reference not found

  • @baroquedub
    @baroquedub Před 3 lety +2

    Really like how you've gone into the details on this. Never thought of SerializeField references being problematic when more than one person is working on a project. Service Locators are a new pattern for me too. Seems useful but is it actually different to just using FindObjectOfType, which is known to be super slow ? (apart from the caching you're doing) My main fear with it is that you're not forcing a single instance of these 'Services' which seems like a recipe for disaster (especially in the context of more than one programmer working on a project)
    You have a great knack of clearly explaining deep programming concepts, I'd love to see you do a video on Dependency Injection. Had a quick Google but it all seemed a bit over my head. :)

    • @matthewventures
      @matthewventures  Před 3 lety +4

      Hey, thanks for the insightful comment. Find object definitely gets a bad reputation for being slow, but it's honestly fine if you're only doing it once. When it becomes a problem is when you're doing it multiple times per frame. As I have written it, the service locator is as you said basically just a machine for doing find object in cashing, however I would suggest you check out other implementations of the pattern because there are more advanced add ons that you can add to a service locator in order for it to do more. One such example is the idea that you can return a null service. What that means is that, if maybe you cannot find a service you can still return one and this service instead of being truly know is instead a service that is sort of empty and does nothing. So for example this might be used when a game is muted, instead of returning a sound machine that is a null pointer, this kind of service locator would return a sound machine that does not play any sounds. Basically, the idea is that if we build the service locator who is in control of obtaining things then we have control over what we can provide and we can do some fancy tricks like that. Maybe I will make a DI video, that could be fun. You bring up a good point about how the current code does not assert that there is one service of each kind. This is actually very easy to do and I've done it in prior implementations. Basically just replace FindObject with FindObjects (note the plurality) and then assert if the array returned is not equal to length one. If it is length one, then grab the 0th index and continue on as normal. Thanks for watching and contributing these great points.

    • @matthewventures
      @matthewventures  Před 3 lety

      Here's a nice DI tutorial I found: czcams.com/video/JgBmAkkLFBI/video.html

  • @Lukeibol
    @Lukeibol Před 3 lety

    Man what a good video, damn. Loved it!

  • @cfffba
    @cfffba Před rokem

    What is the reason for the two Equals() in the null check in your singleton implementation? I'm pretty sure "_instance==null" would've sufficed. :)

  • @IcarusPhoenix
    @IcarusPhoenix Před 2 lety

    Very good video! Could using a service locator with asynchronous methods lead to race conditions?

    • @matthewventures
      @matthewventures  Před 2 lety +1

      Yes definitely. It's very dangerous in that respect.

  • @Iigua
    @Iigua Před 2 lety +1

    I hear "Singleton bad" everywhere but I don't hear anyone giving a clear answer as to why

    • @matthewventures
      @matthewventures  Před 2 lety +3

      The issue is that Singletons are globally accessible. So it's the same ideology behind Globals are bad. If it's not well-structured, everything could be calling everything which leads to a relationship diagram which resembles spaghetti. It's hard to understand. Multi-threaded environment it can be hard to control

    • @Iigua
      @Iigua Před 2 lety

      @@matthewventures Thanks for the answer, is it a performance issue or a project navigation and code readability issue? I've just never gotten to the bottom of this

  • @manugo4
    @manugo4 Před 2 lety

    Not a big fan of the explanation. Doesn't clarify why a bunch of Singletons is worse than the Service Locator pattern. Yes, Singletons are globally accessible which is bad but this is the case with both patterns so...

    • @matthewventures
      @matthewventures  Před 2 lety

      Hey thanks for the comment. Sorry my explanation fell short. Here's a link to a more detailed explanation gameprogrammingpatterns.com/service-locator.html if I said that Singletons are worse than service locators then that is false. These are just different approaches to solving the same problem and the best approach highly depends on your use case. The development environment is extremely relevant, because something like Unity where the c-sharp runs in a single threaded system has very different needs than a multi-threaded AAA engine. In my current Unity projects, I use a service locator which is a Singleton. So there are many hybrid approaches as well.