patternjavaMinor
Simple (base) Twitch IRC bot
Viewed 0 times
simpletwitchbotircbase
Problem
I've created the beginnings of a Twitch IRC bot. As of current, it only has one command (
This is my first time making a system with this much threaded and i/o operations in it, so I'd especially appreciate comments around those parts of the code. Other key points I'm looking at are: potential for further "good" abstraction of the Twitch IRC API; routines potentially located in the wrong class/package; places to use the Java8 Streams; extensibility of the command handler. And of course, naming and documentation improvements.
Uses JetBrains Nullability Annotations.
You can view the full bot on GitHub. You can view the Twitch IRC API on GitHub.
cad97.twitchapi.Constants
cad97.twitchapi.TwitchIRCSocket
`package cad97.twitchapi;
import org.jetbrains.annotations.NotNull;
import java.io.*;
import java.net.Socket;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.function.Supplier;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class TwitchIRCSocket implements Closeable {
private final @NotNull Socket socket;
private final @NotNull BufferedReader reader;
private final @NotNull PrintWriter writer;
private TwitchIRCSocket() throws IOException {
socket = new Socket(Constants.HOST, Constants.PORT);
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
!echo), though the infrastructure is (hopefully) there to library this code and build an actual bot on top of this base code.This is my first time making a system with this much threaded and i/o operations in it, so I'd especially appreciate comments around those parts of the code. Other key points I'm looking at are: potential for further "good" abstraction of the Twitch IRC API; routines potentially located in the wrong class/package; places to use the Java8 Streams; extensibility of the command handler. And of course, naming and documentation improvements.
Uses JetBrains Nullability Annotations.
You can view the full bot on GitHub. You can view the Twitch IRC API on GitHub.
cad97.twitchapi.Constants
package cad97.twitchapi;
final class Constants {
static final String HOST = "irc.chat.twitch.tv";
static final int PORT = 6667;
static final double RATE_LIMIT = 20d / 30d;
static final double MOD_RATE_LIMIT = 100d / 30d;
static final double INVERSE_RATE_LIMIT = 1d / RATE_LIMIT;
static final double INVERSE_MOD_RATE_LIMIT = 1d / MOD_RATE_LIMIT;
private Constants() {
throw new UnsupportedOperationException("No Constants instance for you!");
}
}
cad97.twitchapi.TwitchIRCSocket
`package cad97.twitchapi;
import org.jetbrains.annotations.NotNull;
import java.io.*;
import java.net.Socket;
import java.util.Optional;
import java.util.function.Consumer;
import java.util.function.Supplier;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class TwitchIRCSocket implements Closeable {
private final @NotNull Socket socket;
private final @NotNull BufferedReader reader;
private final @NotNull PrintWriter writer;
private TwitchIRCSocket() throws IOException {
socket = new Socket(Constants.HOST, Constants.PORT);
reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
Solution
- The annotations are nice, if a bit verbose. There are also some more
(unpopular) annotations (like Lombok) that can remove even more
boilerplate, but I guess that depends on personal taste and the
contributors to a project.
- I don't see much point with package-private visibility to be honest,
similarly the private constructor in
Constants is not helping thereader much.
- The code doesn't look very testable, I'd suggest to move the inline
anonymous classes into their own top-level ones and if possible to
pass in objects in the constructor instead of constructing them there
so you could instead pass in mock objects.
- The comment for the
modparameter inTwitchIRCSocketis oddly
specific and likely to be out of sync with the code very quickly.
It's probably enough to link to the corresponding fields in the
constants class or wherever the values are coming from (a future
configuration file for example).
- Splitting the two constructors like that looks super weird. I'd
rather have a separate method to initialise the fields, or rather put
it all in one constructor.
- Use a logging framework sooner rather than later.
System.outand
friends will get quite old very quickly.
- I'd suggest to move the fields together at the start or end of the
class so it's tidier. If there are too many fields that's also an
indicator that the class is growing too big.
- In
convertRawMessagethe variable should be namedmatcherbecause
it's a ...
Matcher object.- In
closeI'd catch and throw away (or perhaps accumulate them) all
the exceptions from the other
close calls so that as many of themare done as possible.
Can't say anything about the UI part. The separation between the "raw"
interface and having a separate, more customisable bot part is nice and
the message-passing between the different actors does too. With a
little bit less repetition and possibly splitting it up some more I
think it's on the right way.
Context
StackExchange Code Review Q#138207, answer score: 2
Revisions (0)
No revisions yet.