OOP、架构、SOLID 原则等等……
在 SOLID 原则中,有第一个原则是Single Responsibility Principle,其中必须将每个责任分离到它自己的对象中,每个对象只有一个责任。因此,不能将应用程序逻辑放在同一个 UI 对象中。
您的解决方案是将应用程序逻辑与 UI 分开,然后制作另一个界面,即命令行界面。
例如:你想做两个数字相加的东西。
一个是 JFrame,有两个 JTextField 和一个按钮。然后你添加
按钮上的单击侦听器,它将两个数字相加并将其打印在 JLabel 上。但是,如果是这样,怎么可能做 CLI 呢?
在这种情况下,你应该做这样的事情,它处理 Swing 和 CLI 之间的公共逻辑(应用程序逻辑):
interface NumberAdditionResultAsString {
void postResult(String result);
void postError(Exception ex);
}
class NumberAdderFromStrings {
void executeTheAddition(String num1, String num2, NumberAdditionResultAsString listener) {
try {
double n1 = Double.parseDouble(num1);
double n2 = Double.parseDouble(num2);
listener.postResult(Double.toString(n1 + n2));
} catch(Exception ex) {
listener.postError(ex);
}
}
}
现在可以从 Swing 和 CLI 轻松调用此应用程序逻辑。
还使用了更适合处理发生在其他线程上的冗长操作的“回调”。
另外,如果你想要更复杂的东西,你可以使用command 设计模式。所有这些“应用程序逻辑”都实现了一个接口。然后你的 UI 和 CLI 都会调用它们。
interface ApplicationCommand {
Object execute(Object... parameters);
}
然后在你的主应用程序类中做类似的事情:
Map<String, ApplicationCommand> commandMap = new HashMap<>();
然后像这样填充它:
commandMap.put("add", new ApplicationCommand() {
@Override
public Object execute(Object... parameters) {
double sum = 0;
for (Object one: parameters) {
sum += Double.parseDouble(one.toString());
}
return sum;
}
});
嗯,这不是最好的设计。最好将每个字符串与创建命令的工厂对象相关联,而不是与命令对象本身相关联。但这是为了简单起见。
建议:了解一下
Command design pattern
Strategy design pattern
Abstract factory design pattern
Flyweight design pattern(可以帮助正确创建命令映射)
SOLID Principles(主要阅读:单一职责、依赖倒置)