patternjavaMinor
I command thee: do SOMETHING
Viewed 0 times
commandtheesomething
Problem
I am currenly contributing to a Chat-Bot to be used across the whole SE-Network's chat which is implemented in Java 8.
This bot is supposed to have commands. These commands again are supposed to be as flexible as possible, and based on chat messages. To allow easy and extensible implementation of arbitrary commands I have created the following two classes:
Currently the bot itself is a work in progress, but a working one can be found on github.
Anyways let's get into code:
```
/**
* Command Builder for ass
This bot is supposed to have commands. These commands again are supposed to be as flexible as possible, and based on chat messages. To allow easy and extensible implementation of arbitrary commands I have created the following two classes:
- CommandHandle: This class defines when a command is "triggered", and specifies the code executed. It's supposed to be as "generic" as possible while allowing clean and specialized code.
- CommandHandleBuilder: This class is responsible for building instances of CommandHandles and defines a chainable API that's supposed to be easy to use for anybody willing to create their own commands.
Currently the bot itself is a work in progress, but a working one can be found on github.
Anyways let's get into code:
/**
* Simple handle for a Command. Consists of a {@link Predicate} to match
* messages (aka. invocations) against, a helpText,
* an infoText and a {@link Consumer Consumer} for {@link ChatMessage ChatMessages}
*
* @author vogel612vogel612@gmx.de>
*/
public class CommandHandle {
private final Predicate matchesSyntax;
private final String helpText;
private final String infoText;
private final Consumer executor;
public CommandHandle(
Predicate matchesSyntax, Consumer executor,
String helpText, String infoText) {
this.matchesSyntax = matchesSyntax;
this.helpText = helpText;
this.infoText = infoText;
this.executor = executor;
}
public void execute(ChatMessage message) {
executor.accept(message);
}
public boolean matchesSyntax(String commandCall) {
return matchesSyntax.test(commandCall);
}
public String getHelpText() {
return helpText;
}
public String getInfoText() {
return infoText;
}
}```
/**
* Command Builder for ass
Solution
If you are intent on using a builder, then I'd suggest either making it an inner static class to the main class or a different class in the same package. If the first solution, then the constructor for the built class can be made
Easy to adapt in the second scenario.
Second remark: I fail to see why
Third remark: calling a
private; if the second, it can be made package local. First scenario:public final class Foo
{
// instance variables...
public static Builder newBuilder()
{
return new Builder();
}
private Foo(args, here) { /* whatever */ }
public static final class Builder
{
// etc etc
public Foo build()
{
return new Foo(args, here);
}
}
}Easy to adapt in the second scenario.
Second remark: I fail to see why
FALSE is an illegal value at all for your predicate; as your code reads right now, I can very well input s -> false as an argument to the predicate and it will work. Why not just "let it be"? After all, it is the user's fault if a correct predicate is not provided, isn't it?Third remark: calling a
Consumer an executor? Uh... Why not just Consumer? Also, remind that any interface obeying the prototype of a @FunctionalInterface can be used, so you can define public interface MessageConsumer extends Consumer and use instances of this interface. By default, you could supply an empty one, or one that System.out.println()s, for instanceCode Snippets
public final class Foo
{
// instance variables...
public static Builder newBuilder()
{
return new Builder();
}
private Foo(args, here) { /* whatever */ }
public static final class Builder
{
// etc etc
public Foo build()
{
return new Foo(args, here);
}
}
}Context
StackExchange Code Review Q#70178, answer score: 3
Revisions (0)
No revisions yet.