Mediator Pattern - Reduce Chaotic Dependencies

  Рет қаралды 9,105

git-amend

git-amend

Күн бұрын

Пікірлер: 86
@git-amend
@git-amend 8 ай бұрын
Hey everyone! Both Mediator and Blackboard are good patterns to know before diving into Behavior Trees, GOAP and State Trees. If these kinds of topics interest you, let me know in the comments and hit the 🔔!
@ryaz4704
@ryaz4704 8 ай бұрын
Yes
@ragerungames
@ragerungames 8 ай бұрын
Yesssss behavior trees and state trees
@carlwong1919
@carlwong1919 8 ай бұрын
GOAP please
@TChrisBaker
@TChrisBaker 8 ай бұрын
all of those sound interesting. I would be curious on your take on how to implement a Blackboard as well
@drewalkemade3715
@drewalkemade3715 8 ай бұрын
Seeing your implementation of GOAP would be great!
@git-amend
@git-amend 8 ай бұрын
Alrighty! One vote for a GOAP video!
@PetersExcapades
@PetersExcapades 8 ай бұрын
@@git-amendmake it 2!
@PetersExcapades
@PetersExcapades 8 ай бұрын
yes thats 2 factorial
@Fitz0fury
@Fitz0fury 8 ай бұрын
Also voting for goap.
@fear_ctpax
@fear_ctpax 7 ай бұрын
@@git-amend +, me too!
@danny-g4328
@danny-g4328 8 ай бұрын
I thought this thing was facade pattern. I guess as soon as components need to know of / communicate with each other, it turns from facade into mediator pattern. Thanks for making this video, I tend to use this pattern a lot and this video really helped me with improving on it :))
@git-amend
@git-amend 8 ай бұрын
That's a great observation, thanks for sharing that. Cheers!
@silchasruin4487
@silchasruin4487 8 ай бұрын
GOAP, GOAP! You're a fantastic teacher, I'm busy working on enemy AI that uses the Observer pattern to update randomly assigned weights based on the players actions. So if the player is looking in their direction and shooting them, an enemy with a lower Courage weight will run, where as one with a higher weight value will rush the player. Just to add a bit more dynamic behavior. Im still working on the implementation but I don't know if GOAP would simplify things or make it unnecessarily complicated. We all want F.E.A.R. type AI in our games haha
@git-amend
@git-amend 8 ай бұрын
Ok another vote for GOAP. I’ll start working on that soon!
@silchasruin4487
@silchasruin4487 7 ай бұрын
@BornToTroll-it5ju that's pretty cool to think I've got a similar idea to a 15 dollar asset since I can't afford it at the moment
@TChrisBaker
@TChrisBaker 8 ай бұрын
Great video ! Your timing with these videos is amazing . I was just trying to make a central "EnemyManager" class this week but I wasn't sure if there was a more sophisticated way to do it. I will give this a try
@git-amend
@git-amend 8 ай бұрын
Glad it was helpful!
@_stephenhubbard
@_stephenhubbard 7 ай бұрын
Great stuff I've always struggled with some of these practices in the past. Was pretty recently I was looking for a good explanation of the mediator pattern and couldn't find one! Super helpful :D
@git-amend
@git-amend 7 ай бұрын
Right on, glad to hear that!
@PurpleDaemon_
@PurpleDaemon_ 8 ай бұрын
The first part with the AI chat was very cool! But I didn't catch the essence of the mediator in the second part. What prevents us from making private fields and public interface-methods in the hero class itself? Btw, this is exactly the problem I'm currently trying to solve as my character class consists of a dozen public systems, which causes problems when one system must influence another, so I'm going to make them private and expose public methods instead.
@git-amend
@git-amend 8 ай бұрын
Thanks for the comment! Nothing is preventing you from exposing/using field and properties on the Hero class itself - but any class that calls them directly will also need a reference to the Hero. That's not necessarily a bad practice, but consider a UI that exists in a 2nd scene. Beyond the issue with having to 'tunnel' into the sub classes of the Hero for information, you also can't reference it directly. So, consider the Mediator just another tool in your toolkit for when the need arises!
@PurpleDaemon_
@PurpleDaemon_ 8 ай бұрын
@@git-amend I just realized that may be in my approach I already use some type of mediator as all my logic live in non-MonoBehaviour classes while MonoBehaviours simply subscribes to these class events , which makes it much simpler to write tests. I just never thought about this as a sub-type of mediator pattern, closer to a model - view decomposition. Thank you for making me think more about such things!
@Fitz0fury
@Fitz0fury 8 ай бұрын
I had not even heard of this pattern. Ill have to play with it this week. It might solve for a problem i have actually..
@git-amend
@git-amend 8 ай бұрын
Nice, that's what I like to hear!
@franciscooteiza
@franciscooteiza 3 ай бұрын
Hi Adam, I’d love to hear your thoughts on using MediatR for implementing the mediator pattern. What do you think?
@git-amend
@git-amend 3 ай бұрын
I haven't actually used it myself, but that has been suggested as a topic before, or just request/response in general. I'll give some thought to making a video about it. Personally, I think it's a good choice, but I'd have to look and see if there are any gotchas.
@DuckeryDoo
@DuckeryDoo 7 ай бұрын
I often wonder with more "complex" implementations like these patterns, there is often creating new instances involved, that only serve temporary (e.g. Payload or Builder here). Is this something that one should "worry" about (e.g. performance/GC-wise) and try to avoid creating new instances or build stuff like pools on top of that (especially when having lots of entities communicating)?
@git-amend
@git-amend 7 ай бұрын
That is a valid concern. For me, I usually add concerns for performance later on. It wouldn't be difficult to add pooling these kinds of resources.
@SunSailor
@SunSailor Ай бұрын
@git-amend, which application did you use to create this nice node graph illustration with the hand drawn look at the beginning of the video?
@git-amend
@git-amend Ай бұрын
That's Excalidraw for Obsidian, though you can use it without Obsidian too. kzbin.info/www/bejne/pWHIqX5jrauDac0
@anasmostefaoui3027
@anasmostefaoui3027 7 ай бұрын
can't wait for the GOAP video :D
@git-amend
@git-amend 7 ай бұрын
Coming soon!
@bartekwoszek233
@bartekwoszek233 7 ай бұрын
God damn, that is awesome, never seen solution like that. Im gonna jump on another level with your videos. Thanks
@git-amend
@git-amend 7 ай бұрын
Thanks! Welcome aboard, join the Discord too if you like.
@connorjagielski6760
@connorjagielski6760 7 ай бұрын
Great video as always! Unrelated to the code, what software do you use for the diagrams? I’ve been looking for something super simple for drawing them
@git-amend
@git-amend 7 ай бұрын
Thanks! I'm using ExcaliDraw (with the plugin for Obsidian) excalidraw.com/ kzbin.info/www/bejne/pWHIqX5jrauDac0
@AstralNostalgia
@AstralNostalgia 8 ай бұрын
thanks ! however I Notice all the game pattern needs to be addapted to unity monobehaviour ? or non-unity monobehaviour right?
@git-amend
@git-amend 8 ай бұрын
The patterns can be applied to both. The main issue with MonoBehaviour is that you can't use constructor injection. Otherwise, it's all very similar.
@atherissquamigera7425
@atherissquamigera7425 2 ай бұрын
To me, the first implementation is the same as EventBus, and the second use case is like Facade pattern. Can you tell me the difference?
@bgt7911
@bgt7911 8 ай бұрын
Hi, i love your videos because you work as professional. Can you make a video about game dev roadmap. I really need it please
@git-amend
@git-amend 8 ай бұрын
Not a bad idea!
@votranduy8836
@votranduy8836 2 ай бұрын
Hi! I come from the future of this video @@, really appreciate every content in this channel!! So far I have implemented and used several techniques you have taught us and they're pretty powerful! I would like to ask in regards of this pattern, we have a Message method which will direct a message from a source to a specific target, I would like to ask what is the best way to do it? because if we want to message to a specific object, we have to know or keep a reference to it, the way I am doing is to use service locator to store the target reference and use it inside the source! Looking forward to your response! Happy coding time!
@git-amend
@git-amend 2 ай бұрын
My intention with the message was not to keep a reference, but only to be able to send messages when two agents were close enough together in the game that they could see each other, for example within range of a trigger collider. Just like in the real world, you can only talk to someone directly if they are close enough.
@votranduy8836
@votranduy8836 2 ай бұрын
@@git-amend Alright I understand now, actually my case is a bit different as the implementation's not used for chat room agent, but acting as mediator between UIs, then it's more appropriate to use broadcast then the UI agent will determine what to do with the message! I have another question regarding to the visitor pattern used here, generally speaking visitor will handle the logic of visitable object with their passing data right? that's what I understand, but do you think it's viable to "reverse" the action back to the visitable? Like the visitor come, visitable objects accept, then the visitor (right now it's the payload) will pass the necessary data of the broadcast back to the visitable and they decide what to do with it!
@git-amend
@git-amend 2 ай бұрын
@@votranduy8836 Yes, the Vistor can be implemented in either direction.
@votranduy8836
@votranduy8836 2 ай бұрын
@@git-amend Thanks a lot!! Learn something new today from you again!!!
@crazyfox55
@crazyfox55 8 ай бұрын
A visitor with a generic visit method is a code smell. What do you think?
@git-amend
@git-amend 8 ай бұрын
Labeling a visitor with a generic visit method as a code smell can be context-dependent. If the generic method overly complicates the interaction between visitors and visitable objects or leads to type checking and casting that defeats the purpose of using patterns for clean and maintainable code, it might be considered a code smell. However, in scenarios where such a design significantly simplifies the implementation by reducing boilerplate code or enhances flexibility without sacrificing clarity and type safety, it could be justified.
@crazyfox55
@crazyfox55 7 ай бұрын
@@git-amend Yes I think I follow what you're saying here. I would agree it's not a code smell.
@AtmosMr
@AtmosMr 4 ай бұрын
Hi, I am a hobbyist coder but am looking to improve. I have created a few projects which suffer from all the basic errors but work... I am sure you would laugh your head off at my code. Can you tell me what Visual Studio addons you are using? Or rather what would you recommend? Any tips/videos aimed at amateurish intermediates, who make all the classic mistakes, would be great. A lot of your code is very sophisticated and a bit over my head. Thanks!
@git-amend
@git-amend 4 ай бұрын
Well, I don't use VS Code very often to be honest, I mostly use JetBrains Rider as my IDE, which you can get for free right now if you want to try the early access version: www.jetbrains.com/rider/nextversion/ Next week's video is going to be about Plugins and Assets, and the setup script that I use in all my projects, so hit the bell and you'll get the notification next Sunday!
@rechnight
@rechnight 7 ай бұрын
Hey Adam! I just finished watching your latest video, and as always, it was fantastic. I did notice one thing though: in the Message method, the T source parameter doesn't seem to be utilized. I was wondering if it was intended to ensure that the source of the message isn't the same as the target, or should be removed? Great job overall, looking forward to your next video! One more vote for GOAP!
@git-amend
@git-amend 7 ай бұрын
Thanks! In the Message method, you might want to be able to send a direct message to another entity if you happen to have a direct reference to it. So, for example if one AI Agent comes into contact with another one in the game world, it might want to deliver a Payload/message just to that specific entity instead of a Broadcast to all agents, similar to a DM in a normal chatroom.
@rechnight
@rechnight 7 ай бұрын
@@git-amend That part, I understood, but there's something bothering me: public void Message(T source, T target, IVisitor message) { entities.FirstOrDefault(entity => entity.Equals(target))?.Accept(message); } We have the T source that is not being utilized... So just wanted to make sure what's its purpose here.
@git-amend
@git-amend 7 ай бұрын
@@rechnight Oh I see. I'm sure I probably had something in mind, but by the time I recorded maybe I wasn't necessary for the video anymore. An oversight on my part I guess.
@MarushiaDark316
@MarushiaDark316 7 ай бұрын
What's the difference, if any, between Mediator and Bridge patterns? Is it just a different name or is there some meaningful distinction like there is between Builder and Factory?
@git-amend
@git-amend 7 ай бұрын
The Mediator pattern is designed to simplify communications between multiple objects or classes in a system by having them communicate indirectly through a central mediator, thereby reducing direct dependencies between them. In contrast, the Bridge pattern separates the interface (abstraction) of an object from its implementation, allowing both to be modified independently without affecting each other, aiming to enhance scalability and manageability. Perhaps a video about the Bridge pattern should go onto the list, though I'll have to think of a good example use case.
@pstudioDOTtk
@pstudioDOTtk 8 ай бұрын
As usual your videos are very interesting. I do have a few questions regarding the second example. First the HeroMediator to me might as well be called HeroFacade. The class hides away object dependencies and instead offers simplified methods to interact with those underlying objects. What do you see as the differences between the Mediator and Facade patterns in that example? Or is it more about intent? Mediator is concerned about decoupling dependencies whereas Facade is about simplifying interaction with dependencies. Second it is not quite clear to me what you are trying to solve or prevent, when you introduce a separate Mediator object to modify stats etc. rather than having those methods on the Hero object itself? If you are using a ServiceLocator or other method of retrieving dependencies, why not just retrieve the Hero object or the specific sub-object I need? E.g. what benefit would a UI Healthbar gain from retrieving the mediator over getting a direct reference to the Health object? Anyways, thank you for the videos. They are in my opinion the best regarding game development in Unity on KZbin.
@git-amend
@git-amend 8 ай бұрын
You bring up some interesting points. First, the distinction between the Mediator and Facade patterns does largely hinge on intent and context; the Mediator pattern aims to reduce coupling between classes by centralizing complex communications and control logic, whereas the Facade pattern typically offers a unified, simplified method/interface that encapsulates multiple steps or operations, like changing the hero stats and health with one method call. Second, introducing a separate Mediator, like HeroMediator, is about centralizing the interaction logic between different components (HeroStats and HeroHealth) to manage their relationships and interactions in a decoupled way, enhancing modularity and maintainability. Using a Mediator over direct object retrieval, such as through a ServiceLocator, can offer clearer encapsulation of the interaction logic and potentially simplify changes to the system's behavior without altering the individual components or their consumers. That being said, there is nothing wrong with either approach. Thanks for your comment!
@MarushiaDark316
@MarushiaDark316 7 ай бұрын
I understand the value of chaining all these systems and patterns together and showing that such a thing is possible at an advanced level; and maybe teaching is a side benefit whereas the primary concern is that you're actually building something useful to you like a specific game you want to eventually publish. However, I'm starting to feel that this format does make it a bit nebulous and difficult to follow any individual pattern if you don't have a decent grasp of all the other ones already. So in order to follow along in THIS tutorial, it's not enough that I know the Mediator pattern. I have to know Visitor, Service Locator, GOAP, generics, and many other things. As opposed to the first patterns in your series about Builder and Factory where I don't have to have prior knowledge, I can just learn about builder and factory. In my case, I was still stuck on the Visitor and Service Locator, so I can't get as much value from learning the Mediator, even though it's definitely something I conceptually get would be really useful as a central command center. So if you do make a GOAP vid - and I really would love it if you did - can you please make it a stand-alone thing that just focuses on that system as if it were the first in the series? Or maybe going forward, a better approach might be to show an introductory implementation for beginners and then finish with the flair of, "Now here's my advanced use case tying into everything else we learned so far." As always, I really appreciate your content.
@git-amend
@git-amend 7 ай бұрын
Thanks for sharing your feedback. I can understand how integrating multiple concepts can make it difficult to grasp new patterns without prior knowledge of related systems and patterns. At the same time, it's my intent to create intermediate and advanced Unity content. I appreciate your input and I'll take it into consideration.
@MarushiaDark316
@MarushiaDark316 7 ай бұрын
​@@git-amend By no means am I saying don't do advanced integrated stuff. That's an important niche. All I'm suggesting is maybe do the intro stuff first and THEN tie it into existing systems. So you learn beginner things then graduate to intermediate and advanced things later in the video.
@TheKr0ckeR
@TheKr0ckeR 6 ай бұрын
Sometimes i feel that way too, for example, we have used ServiceLocator, but i generally prefer other solutions like DI or Singleton maybe. But since I dont really grasp the concepts of Service Locator, or i dont prefer; It makes me feel like i am "obligated" to use Service Locator here to make this work. But I know know those concepts are prefer to use and you are showing them to make them work together which is great. Combining Locator, visitor and mediator is great it might be hard to grasp. But THE IMPORTANT PART HERE is you have already shown those concepts in previous videos. So that means as you soon as you have grasped those concept, you will be fine to follow up this tutorial. So i recommend going back and learn those concepts.
@Hovrawl
@Hovrawl 7 ай бұрын
More votes for a GOAP video please 🙏
@mertakbulut241
@mertakbulut241 7 ай бұрын
Hello sir, Thanks for the video again. Waiting a video for your code editor.
@git-amend
@git-amend 7 ай бұрын
You're welcome
@martin.m.kloeckener
@martin.m.kloeckener 8 ай бұрын
Very interesting, haven't heard about this pattern before.
@git-amend
@git-amend 8 ай бұрын
Glad to hear that!
@omeryilmaz1021
@omeryilmaz1021 5 ай бұрын
can we use this pattern to manage UI system to solve complex relations between buttons and popups etc., or do you have any other solution for ui management because I think its a big issue to get rid of drag and drops, using many components for each buttons and popups, deciding which pop will be front or not and etc..
@git-amend
@git-amend 5 ай бұрын
Yes actually that is a very common use of the Mediator pattern. You can see an example of that here: refactoring.guru/design-patterns/mediator
@omeryilmaz1021
@omeryilmaz1021 5 ай бұрын
@@git-amend Thank you very much!
@franciscooteiza
@franciscooteiza 8 ай бұрын
I know there is no right or wrong answer but what would be the best pattern to apply in a UI? Thanks for another great video.
@git-amend
@git-amend 8 ай бұрын
You're welcome. Yes, there is no right or wrong answer, but if you keep the Mediator approach in mind, you'll have a lot easier time reusing similar elements like buttons and toggles. Of course, the Observer pattern is also very useful.
@Efim141
@Efim141 8 ай бұрын
Depending on what you want you can either look into Data Binding (simpler approach) or Model-view-presenter pattern (more sophisticated). For starters here's a good playlist to learn about Unity's UI 'intended' architecture: kzbin.info/www/bejne/fpiwf51_j9OEnq8
@franciscooteiza
@franciscooteiza 8 ай бұрын
@@Efim141 Thanks for sharing!
@puretrack06
@puretrack06 7 ай бұрын
Any thought on how you would implement this in unity entities api ?
@git-amend
@git-amend 7 ай бұрын
Haha... well that's a question with a complex answer. I don't think I can tackle that one in a comment, but maybe that's a good idea for a video when we start talking about DOTS/ECS more.
@puretrack06
@puretrack06 7 ай бұрын
@git-amend would definitely watch as this is something I need with my utility ai implementation
@Multizauri
@Multizauri 8 ай бұрын
GOAP, let’s go!
@git-amend
@git-amend 8 ай бұрын
Another vote! I’ll start working on it!
@kutanarcanakgul5533
@kutanarcanakgul5533 3 ай бұрын
I really like this pattern but I think too much complexity for 1 Pattern, If someone wants to watch this video. It has to know Visitor and Builder Pattern, What is ServiceLocater mean and how it works, Complete Understanding Over Generics etc. Does Mediator Pattern must need a complex system to work? Or Can we purify the workflow of this pattern?
@truman5652
@truman5652 4 ай бұрын
We just have to remember that each new abstraction = more resources. If game has many entities and logic, then it could be critical and in performance optimization time - it will be antipattern time) - get rid not only from abstractions, but reflection, complex types, any additional logic which needs resources.
@git-amend
@git-amend 4 ай бұрын
While abstractions can introduce some overhead, they generally help manage complexity without significant performance costs, unlike reflection, which can be more resource-intensive and should be used sparingly in performance-critical code.
@damonfedorick
@damonfedorick 8 ай бұрын
nice
@git-amend
@git-amend 8 ай бұрын
Thanks
Optimal Goal-First Pathfinding - D* Lite
20:49
git-amend
Рет қаралды 6 М.
Visitor: How I Mastered the Toughest Programming Pattern
12:59
From Small To Giant 0%🍫 VS 100%🍫 #katebrush #shorts #gummy
00:19
Из какого города смотришь? 😃
00:34
МЯТНАЯ ФАНТА
Рет қаралды 2,6 МЛН
ТЮРЕМЩИК В БОКСЕ! #shorts
00:58
HARD_MMA
Рет қаралды 2,7 МЛН
Code Like a Pro: Refactoring to Patterns!
25:52
git-amend
Рет қаралды 6 М.
Improve Your Unity Code with MVC/MVP Architectural Patterns
15:32
Day Night System | Events, Dial, Skyboxes and PostProcessing
19:23
The Unity HACK that the PROS know
21:27
git-amend
Рет қаралды 17 М.
How to do MORE with the Observer Pattern
13:09
git-amend
Рет қаралды 12 М.
RAYCASTING Made Insanely Fast for Collision Detection!
17:03
git-amend
Рет қаралды 14 М.
Streamline Your Game - Without Being a Memory EXPERT!
17:05
git-amend
Рет қаралды 6 М.
It's EASY to think your code will always be UGLY!
15:28
git-amend
Рет қаралды 8 М.
Better Save/Load using Data Binding in Unity
18:47
git-amend
Рет қаралды 16 М.