Go Design Patterns - Generator Pattern and Observer Pattern - Part Two

Tensor Programming · Beginner ·🛠️ AI Tools & Apps ·6y ago

Key Takeaways

This video tutorial demonstrates the implementation of the Generator pattern and the Observer pattern in Go, using tools such as channels, sync maps, and reactive X libraries to create a means to listen to a generator function as a subject with multiple observers.

Full Transcript

hey guys my name is tensor welcome back to the golang design pattern tutorial series in today's video we're going to be covering two patterns we'll be covering the generator pattern and then we will look at the observer pattern so first let's start with the generated pattern so a generator is a special function that is used to control the iteration behavior of a loop in fact all generators are technically iterators if you've ever worked at Python or dart you'll be used to the term generator in Python for instance a generator is a function that doesn't have a return keyword but rather uses the yield keyword in dart on the other hand you have the star async generator which allows you to create a stream in girl generators make use of channels and so they can either be synchronous or asynchronous and so ultimately a generator is just a function but it behaves like an iterator alright so let's go ahead and create a generator function here and I'm going to use the Fibonacci algorithm for this so we'll create a function called Fibonacci and it'll take in one single integer and then it will return a channel of integer type so we want to go ahead and make our channel of integer type so we just say make Chan int and this will be called out and then of course we're going to return this channel and inside of this function will have another anonymous function running inside of this anonymous function we'll create a for loop which essentially uses what is in essence a list comprehension to generate our Fibonacci sequence which will look like this and if the Fibonacci sequence starts with 0 and 1 we then add those two together to get one and then we add the next two values together to get two and then we repeat that pattern and so in our for loop we take 0 we put it into AI we then take 1 and we put it into J then we have a condition here that says we want to continue the loop so long as I is less than n we move forward and we take I and J which would be 0 and 1 add them together put them into I and then we put 0 into J so then for the next iteration I is 1 J is 0 we add those together that gives us another one for I and of course because the last I was one that gets put into J so now we have one one for I and J so then these two get added together and we get two for I our original one gets put into J so then that gives us 3 and then 5 and then 8 and 13 and so on and of course we're only really concerned about I as far as output goes so we're going to take the I value and pipe it into our out channel now keep in mind that the execution of these two functions will happen asynchronously fib will execute will create the channel and then we'll spawn a go routine which has this logic inside of it which will run the for loop and while that's happening we'll pass the out channel back to the main function and so this outer function will end but this go routine will continue executing so now we can go ahead down to our main function and use the fib function like an iterator and because we're receiving a channel from our fib function we can use a for loop to iterate through the sequence of values that are coming from our generator function so we can just say for X in range fib 10 million and we'll then print out each of the X values as we get them from our out channel now we can go into our terminal and execute our program and you'll see here that we will get our Fibonacci sequence we do have an error here and I've deliberately made a mistake to show you guys this error so the error tells us that all of the girl routines are asleep in that we've hit a deadlock what essentially is happening here is that our channel is still open and so the for loop here is expecting to get another value from the channel because it's still open and as a result it throws a deadlock so the program doesn't really get the chance to exit proper and so we need to close the channel after our for-loop finishes so inside of our anonymous function we just want to called defer close and then pass in our channel which will then close our channel which will then close our channel when the anonymous function finishes its execution and that's it this is a generator function that we've created here and it generates a Fibonacci sequence that is less than the value of n that we input into the function and of course you could use this pattern to generate really any kind of sequence of data all right so now that we've finished the generator pattern let's go ahead and take a look at the observer pattern and we're actually going to use our generator function to demonstrate the observer pattern in the observer pattern we create a object or a data structure which we can call a subject this subject maintains a list of other objects which wants to know about what's happening with this object and we can call these other objects observers and the idea is that as the main object changes as the subject changes it will automatically notify them of these state changes you'll be familiar with the observer pattern if you've ever used any rx libraries or reactive X libraries in reactive X you have observables and you have subjects the subjects are the part that actually implements the observer pattern in this way where they contain some kind of state and then they also contain a list of observers that are listening to the subject all right so let's go ahead and define a bunch of different types first let's define an event type the event type will be a data type that we're going to send to our observers when our Fibonacci generator generates a new Fibonacci number we want to attach to this struct a piece of data which will be an integer and this will essentially just be the integer that's going through our channel now along with our event we want to create an interface for our observer type and the observer type we'll implement a notify callback function which will just take in an event and then we can use this to define the logic for what the observer will do when it's notified of an event well create another interface here which we'll call subject and the subject will be the item that we're listening to and of course we want the subject to also maintain a list of the objects that are listening to it we can add three functions to our subject we'll have an add listener function which will take in an observer type then we'll have a remove listener function which were also taken an observer type and then we'll have the notify function which will take in the event type and of course notify will be called when we get some kind of event that we want to then notify our observers with now we can go and create a struct for each of our observers so each of our observers will have an ID and then they'll also maintain a bit of time and so essentially what we'll do is we'll be able to find how long it takes the FIB function to produce a new value and finally we'll create an event subject struct which will contain a sync map which will contain a list of the observers that are listening to this event subject all right so now we need to implement our interfaces for each of our struct types so we need to implement the observer interface for the event observer struct type so that it will be an observer type and then we need to implement the subject interface for the event subject type so that it will be a subject type for our event observer we'll implement the notify callback function and notify callback takes in an event this function of course is the callback function that gets executed when we get notified of an event and so what we want to do is just print out that we've received the data on the event after a certain amount of time and we can get our time by calling time dot sense on e dot time which is just our event observer field we can go ahead and implement add listener and remove listener for our event subject and of course these take in the observer type for the first one all we're going to do is just take the observer type store it into our map and then start with an empty anonymous struct as its value then with the removing listener method we'll take in the observer and then we'll call ask dot observers delete on that observer to delete it from the map if an observer is in our map then it's a listener if it's not in our map then it will not be a listener the notify method will be a little bit more complicated than the others because we want to add logic which will allow us to iterate through the map of observers and then pass an event to each of those observers the sync map type has a method on it called range and we can use this method to iterate through all of the keys and values inside of the map now this range function takes in a function and the function will have the key which is an interface type the value which is also an interface site and then it will return a boolean if it returns true then it will continue to iterate and if it returns false then it will stop iterating through the map and so we can set up a little if statement to just check to see if the key itself is nil and if that key doesn't exist then we'll return false and so what this means is that it will just iterate through the values that exist in the map and then once it hits the end of that list it'll have a empty key and then it will just return false which will stop the iteration and I made a mistake up here I was asking an observer in as a parameter the notify function needs to take in an event here after we've checked to see if the key is nil we can then take the key and then execute the notify callback method on that key which is the observer of course and then we can pass in the event that we want to pass to this observer now of course this is going to throw an error because the key is currently an interface type and so we need to take the key and cast it as an observer and we can do it by just saying keyed out observer in parentheses like this dot notify callback and we'll then just return true like this that way the iteration will continue until we hit an empty key we can also go ahead and expand this little if checked and we can just say if he is equal to nil or the value is equal to narrow then we'll return false either way it should be all right you can come down to our main function and set things up so that we use the observer pattern so first we can go ahead and create our event subject which will contain our observers map we can then set up our observers I'm just going to create two of them and we'll just have observer of ID 1 and then observer of ID 2 and then both of these will also have their time fields just be timed on now so they'll just get the time stamp from when they were created we can then take these observers and put them into our ad listener method on our event subject so n dot add listener and then we pass in the reference for observer 1 and then a reference for observer 2 and then finally we can have a for loop like we had before which will iterate through our generator function and then call and notify and create a new event with data and then the data of course will be the x value in our for loop so now we can go ahead and run our program we'll get each of our values twice because both of our observers are receiving the values each time a value is created by our generator so we get 0 0 and then we get 1 1 and then 1 1 again then 2 2 and then 3 3 and 5 5 and so on and this will just keep doing and actually to make this a little bit clearer let's go ahead and just add the observer ID to the print function here so we'll just say observer ID so observer 1 received the value after the time and so of course now we can see observer 2 received 0 after 0 seconds and then one receives 0 after 1 point 2 4 milliseconds and then this will just keep going of course the order that the observers receive the events is not guaranteed because this is all asynchronous in this case our observer 2 got the 0 event first and then observer 1 received that event and if we go all the way down to the end you can see that observer one received this value after 32 milliseconds whereas observer 2 received that same value after 33 milliseconds so even the time will change in some cases as well now finally let's add some logic to remove one of our observers after a certain period of time above our for loop we can create a anonymous function on a go routine and of course executed immediately and inside of this function we'll just have a select block which will have a single case and the case will check for a channel that will send a piece of data after 10 milliseconds and when that piece of data comes through we'll call n dot remove listener on our first observer which will then remove it from our map and then should stop it from getting notifications and now if we run our application if we scroll up to where 10 milliseconds happens you can see that the first observer stops receiving data and the second observer continues to receive data all right guys well I hope you enjoyed this tutorial if you did feel free to like and subscribe if you have any questions or comments feel free to leave them in the box below and if you dislike this video and then by all means download it as much as you like if you'd like to catch the next video in the golang design pattern tutorial series and you should go ahead and click that notification bill have a good night

Original Description

#tensorprogramming #golang #designpatterns In this tutorial, we take a look at the Generator pattern and the Observer pattern. We create a Generator function and then use the observe pattern to create a means to listen to it as a subject with multiple observers. Source Code: https://github.com/tensor-programming/pattern-tutorial/ Request Form: https://goo.gl/forms/rFjHcZMRJ3bYPEC03 Cloudways Web App Hosting: https://www.cloudways.com/en/?id=507366 Support the Channel and Join Patreon: Patreon: https://www.patreon.com/tensor_programming Dontate: ETH: 0x03247265dd5242605bD2FA3c40fb3b70d9e3D685 Cardano: addr1q9auccwrr9ws8qdyv45f4qwsx76pfmld4zapks89sakq94ay0xmle73y0r8ruwd0zslls4eglf98lghru7ywv56cedysk7ftjt Check out our Twitter: https://twitter.com/TensorProgram Check out our Facebook: https://www.facebook.com/Tensor-Programming-1197847143611799/ Check out our Steemit: https://steemit.com/@tensor
Watch on YouTube ↗ (saves to browser)
Sign in to unlock AI tutor explanation · ⚡30

Playlist

Uploads from Tensor Programming · Tensor Programming · 0 of 60

← Previous Next →
1 NodeJs, Text editors and IDEs
NodeJs, Text editors and IDEs
Tensor Programming
2 Vanilla JS todo App
Vanilla JS todo App
Tensor Programming
3 Elm Tutorial part 1
Elm Tutorial part 1
Tensor Programming
4 Elm Lang Tutorial, Part 2
Elm Lang Tutorial, Part 2
Tensor Programming
5 Elm Tutorial Part 3
Elm Tutorial Part 3
Tensor Programming
6 Elm Tutorial Part 4 -- Analog Clock App
Elm Tutorial Part 4 -- Analog Clock App
Tensor Programming
7 Elm Tutorial part 5 -- Snake Game
Elm Tutorial part 5 -- Snake Game
Tensor Programming
8 Elm Tutorial part 6 -- Calculator
Elm Tutorial part 6 -- Calculator
Tensor Programming
9 Go Tutorial part 1 -- Hello World and Static File Server
Go Tutorial part 1 -- Hello World and Static File Server
Tensor Programming
10 Go Tutorial part 2 -- Web Crawler
Go Tutorial part 2 -- Web Crawler
Tensor Programming
11 Go Tutorial Part 3 (Web App part 1)
Go Tutorial Part 3 (Web App part 1)
Tensor Programming
12 Go tutorial Part 4 (Web tutorial part 2) - Using templates
Go tutorial Part 4 (Web tutorial part 2) - Using templates
Tensor Programming
13 Go tutorial part 5 (web app part 3)
Go tutorial part 5 (web app part 3)
Tensor Programming
14 Go tutorial part 6 (webapp part 4)
Go tutorial part 6 (webapp part 4)
Tensor Programming
15 Go tutorial part 7 (web app part 5)
Go tutorial part 7 (web app part 5)
Tensor Programming
16 Go tutorial part 8 (Web app part 6)
Go tutorial part 8 (Web app part 6)
Tensor Programming
17 Go tutorial Part 9 (web tutorial part 7)
Go tutorial Part 9 (web tutorial part 7)
Tensor Programming
18 Go tutorial Part 10 (web app part 8)
Go tutorial Part 10 (web app part 8)
Tensor Programming
19 Go tutorial Part 11 (Web app Part 9)
Go tutorial Part 11 (Web app Part 9)
Tensor Programming
20 Go Tutorial Part 12 (Web app Part 10)
Go Tutorial Part 12 (Web app Part 10)
Tensor Programming
21 Go Tutorial Part 13 (Web app Part 11)
Go Tutorial Part 13 (Web app Part 11)
Tensor Programming
22 Looking at Elm 0.18
Looking at Elm 0.18
Tensor Programming
23 Go tutorial Part 14 (Web tutorial part 12)
Go tutorial Part 14 (Web tutorial part 12)
Tensor Programming
24 Go tutorial Part 15 (Web tutorial part 13)
Go tutorial Part 15 (Web tutorial part 13)
Tensor Programming
25 Go tutorial part 16 (web app part 14)
Go tutorial part 16 (web app part 14)
Tensor Programming
26 Elm Tutorial Part 7 (SPA part 1)
Elm Tutorial Part 7 (SPA part 1)
Tensor Programming
27 Elm Tutorial Part 8 (SPA Part 2)
Elm Tutorial Part 8 (SPA Part 2)
Tensor Programming
28 Electron Elm Tutorial
Electron Elm Tutorial
Tensor Programming
29 Go tutorial part 17 (web app part 15)
Go tutorial part 17 (web app part 15)
Tensor Programming
30 Up and Coming Programming Languages and Technologies for 2017
Up and Coming Programming Languages and Technologies for 2017
Tensor Programming
31 elixir tutorial part 1
elixir tutorial part 1
Tensor Programming
32 elixir tutorial part 2
elixir tutorial part 2
Tensor Programming
33 Elixir tutorial Part 3 (GenServer and Supervisor)
Elixir tutorial Part 3 (GenServer and Supervisor)
Tensor Programming
34 Elixir Tutorial Part 4 (GenStage)
Elixir Tutorial Part 4 (GenStage)
Tensor Programming
35 Elixir Tutorial Part 5 (Plug and Cowboy)
Elixir Tutorial Part 5 (Plug and Cowboy)
Tensor Programming
36 Phoenix Framework Tutorial Part 1 (elixir part 6)
Phoenix Framework Tutorial Part 1 (elixir part 6)
Tensor Programming
37 Phoenix Framework Tutorial Part 2  (elixir part 7)
Phoenix Framework Tutorial Part 2 (elixir part 7)
Tensor Programming
38 Phoenix Framework Tutorial Part 3 (elixir part 8)
Phoenix Framework Tutorial Part 3 (elixir part 8)
Tensor Programming
39 A Intro to Clojure and Clojure Syntax
A Intro to Clojure and Clojure Syntax
Tensor Programming
40 An Update about the channel
An Update about the channel
Tensor Programming
41 Intro to Rustlang (Setup and Primitives)
Intro to Rustlang (Setup and Primitives)
Tensor Programming
42 Intro to Rustlang (Strings, Tuples, Arrays, Slices and Pretty Printing)
Intro to Rustlang (Strings, Tuples, Arrays, Slices and Pretty Printing)
Tensor Programming
43 Intro to Rustlang (Ownership and Borrowing)
Intro to Rustlang (Ownership and Borrowing)
Tensor Programming
44 Intro to Rustlang (Structs, Methods, Functions, Related Functions and the Display/Debug Traits)
Intro to Rustlang (Structs, Methods, Functions, Related Functions and the Display/Debug Traits)
Tensor Programming
45 Intro to Rustlang (Control Flow, Conditionals and Pattern Matching)
Intro to Rustlang (Control Flow, Conditionals and Pattern Matching)
Tensor Programming
46 Intro to RustLang (Enums and Options)
Intro to RustLang (Enums and Options)
Tensor Programming
47 Intro to Rustlang (Vectors, HashMaps, Casting, If-Let, While-Let, and the Result Enum)
Intro to Rustlang (Vectors, HashMaps, Casting, If-Let, While-Let, and the Result Enum)
Tensor Programming
48 Rustlang Project: Snake Game
Rustlang Project: Snake Game
Tensor Programming
49 Intro to Rustlang (Traits and Generic Types)
Intro to Rustlang (Traits and Generic Types)
Tensor Programming
50 Intro to Rust-lang (Closures, the Box Pointer and Iterators)
Intro to Rust-lang (Closures, the Box Pointer and Iterators)
Tensor Programming
51 Intro to Rust-lang (Modules and Lifetimes)
Intro to Rust-lang (Modules and Lifetimes)
Tensor Programming
52 Intro to Rust-lang (Macros and Metaprogramming)
Intro to Rust-lang (Macros and Metaprogramming)
Tensor Programming
53 Intro to Rust-lang (Error Handling)
Intro to Rust-lang (Error Handling)
Tensor Programming
54 Intro to Rust-lang (Concurrency, Threads, Channels, Mutex and Arc)
Intro to Rust-lang (Concurrency, Threads, Channels, Mutex and Arc)
Tensor Programming
55 Intro to Rust-lang (Tests, Attributes, Configuration and Conditional compilation)
Intro to Rust-lang (Tests, Attributes, Configuration and Conditional compilation)
Tensor Programming
56 Rustlang Project: Port Sniffer CLI
Rustlang Project: Port Sniffer CLI
Tensor Programming
57 Rustlang Project: Chat Application
Rustlang Project: Chat Application
Tensor Programming
58 Rustlang Project: CLI Toy Blockchain
Rustlang Project: CLI Toy Blockchain
Tensor Programming
59 Intro to Rust-lang (Setting up a Development Environment)
Intro to Rust-lang (Setting up a Development Environment)
Tensor Programming
60 Intro to Rust-lang (Building a Web API with Iron)
Intro to Rust-lang (Building a Web API with Iron)
Tensor Programming

This video tutorial teaches the implementation of the Generator pattern and the Observer pattern in Go, using various tools and techniques to create a means to listen to a generator function as a subject with multiple observers. The tutorial provides a comprehensive overview of the concepts and skills required to implement these patterns in a real-world application.

Key Takeaways
  1. Create a generator function
  2. Use the yield keyword to control iteration behavior
  3. Create a channel of integer type
  4. Return the channel from the generator function
  5. Use a for loop with a list comprehension to generate the Fibonacci sequence
  6. Implement the subject interface for the event subject type
  7. Implement the notify callback function
  8. Add a listener to the generator
  9. Remove an observer after a certain period of time
💡 The Observer pattern can be used to notify observers of state changes in a generator function, allowing for asynchronous processing and event-driven programming.

Related AI Lessons

How to Create a Second Version of Yourself Inside Obsidian Using AI (Step-by-Step Guide)
Learn to create a second version of yourself inside Obsidian using AI with a step-by-step guide
Medium · ChatGPT
How to prepare for Spain civil service TIC exam using AI in 2026
Learn how to prepare for the Spain civil service TIC exam using AI in 2026, boosting your chances of success with technology-driven study techniques
Dev.to · David García
Going Viral! How I Created AI Kissing Videos Step by Step Easily Using AIAI.com
Create viral AI kissing videos using AIAI.com in a step-by-step process, leveraging AI technology for creative content creation
Medium · AI
How to prepare TIC teacher exams in Spain with AI (oposiciones 2026)
Prepare for TIC teacher exams in Spain using AI with these actionable steps
Dev.to AI
Up next
Low-Tech, High-Impact: Replacing Your Receptionist With a $15 AI Phone System
Maximum Lawyer
Watch →