Jan 25, 2022
When I first wrote FnGoBot, which is my second Go program, I made a lot of mistakes that made it very difficult to change anything in the code. Everything was highly coupled, everywhere and out of place.
But after I got a new job, I have been refactoring the code to the point that I can now easily add a new quote source in ½ hour, or even add new interface to the bot. And I did just that.
Now that I also write tests, adding new feature or refactoring also becomes much easier.
So first I had to identified which part of the bot is a lib, and which part a main. Then I categorized code into roughly 4 packages:
Package cmd
is where the main
programs live.
Package bot
deals with bot logic, such as handling alerts, getting quotes based on source, etc.
Package parse
defines a parsing function. Because both the Telegram bot and CLI versions use this package, their commands are 100% compatible.
Package fetch
deals with getting quotes from remote APIs.
Package enums
for enums. lol.
FnGoBot interacts with users via handlers. And before CLI, FnGoBot had only 1 type of handlers: Telegram bot handlers.
The Telegram bot handler is an interface, but the implentation is a struct with all the fields required by a Telgram chatbot embedded. So a CLI handler should me much more simpler and minimalistic than the Telegram bot handler.
All I had to do was to create a new package bot/handler_cli
and write code!
fetch.Quoter
interfaceThe fetch.Quoter
interface abstracts how quotes can be passed around to functions. It defines 3 methods: Last()
, Bid()
, Ask()
.
To add a new quote source, I’ll just have to parse its API data into a struct that implement this interface, and the entire FnGoBot can now use quotes from that new sources.
Users can now see all of the handlers with /handlers
Users can also stop a running handler with /stop <UUID>
Handlers are stored per-sender in a map, so now users can only see and stop their own handlers