java 带有 Runnable class 的命令模式示例:是否缺少 Receiver?
java command pattern example with Runnable class : Is Receiver missing?
从Examples of GoF Design Patterns in Java's core libraries问题中引述
All implementations of java.lang.Runnable are examples of Command pattern.
根据我对命令模式的理解,
Client 调用 Invoker => Invoker 调用 ConcreteCommand => ConcreteCommand调用Receiver方法,后者实现抽象的Command方法.
看看这个工作example
来自this article的命令模式UML图如下所示。
看看这段代码:
public class ThreadCommand{
public static void main(String args[]){
Thread t = new Thread(new MyRunnable());
t.start();
}
}
class MyRunnable implements Runnable{
public void run(){
System.out.println("Running:"+Thread.currentThread().getName());
}
}
- ThreadCommand 是 Client
- Runnable界面是Command
- MyRunnable 是 ConcreteCommmand
- Thread 是 Invoker 与
start()
方法调用 ConcreteCommand 实现(其中调用 run()
方法)
是不是Receiver不见了?还是 MyRunnable 兼具 ConcreteCommand 和 Receiver?
接收者不会是...
System.out.println("Running:"+Thread.currentThread().getName());
调用运行方法。因为那是接收Runnable运行s.
时要做的动作
此处已发布一个答案,已被作者立即删除。在阅读答案时,我找到了解决方案。
我可以简单地将上面的示例转换为命令模式 UML 图,只需一点小改动。
我可以将 Receiver 对象传递给 MyRunnable (ConcreteCommand)。
现在我已经更改了我的代码如下。
public class ThreadCommand{
public static void main(String args[]){
Receiver r = new AC();
Thread t = new Thread(new MyRunnable(r));
t.start();
}
}
class MyRunnable implements Runnable{
private Receiver receiver;
public MyRunnable(Receiver r){
this.receiver = r;
}
public void run(){
receiver.execute();
}
}
interface Receiver{
public void execute();
}
class AC implements Receiver{
public void execute(){
System.out.println("I am AC");
}
}
class Fan implements Receiver{
public void execute(){
System.out.println("I am Fan");
}
}
输出:
java ThreadCommand
I am AC
A Receiver 是可选的,取决于 ConcreteCommmand 是否拥有要执行的业务逻辑。从书的第 238 页开始,
A command can have a wide range of abilities. At one extreme it merely defines a binding between a receiver and the actions that carry out the request. At the other extreme it implements everything itself without delegating to a receiver at all.
在最初的问题中我们看到了一个没有接收者的例子,因为 MyRunnable
拥有要执行的逻辑。在这里的另外两个答案中,我们看到了委托给名为 Receiver
和 Account
.
的显式接收者的示例
我想给我两分钱...
原始命令模式将Command
对象与Receiver
对象分开,因为这两个集合的职责不同。
Receiver
拥有应用程序的业务逻辑。这些类型应该存在于模式之外。在实际情况下,Receiver
s 可能已经存在于代码库中,在命令之前。
例如,考虑到 bank 应用程序,接收者可以用以下类型表示:
public class Account {
private final double balance;
// Construct omissis
public Account deposit(double amount) {
// Deposit code
}
public Account withdraw(double amount) {
// Withdraw code
}
}
命令设计模式的目标之一是提供一种统一、同类和标准的方式来对一组对象(即接收者)执行操作。他们不必关心如何执行真正的业务逻辑。这将限制实现业务逻辑的代码的可重用性。
因此,Command
的实施必须将信息转发给 Receiver
。它遵循一个例子。
public class DepositCommand implements Command {
private final Account account;
// An instance of Command should reprenset only a single request
private final double amount;
public DepositCommand(Account account, double amount) {
this.account = account;
this.amount = amount;
}
public void execute() {
account.deposit(amount);
}
// Omissis..
}
总之,恕我直言,接受的答案中的陈述是不正确的。
The receiver is a relic of C/C++ in which the method to be invoked is separated from the object to invoke it on.
从Examples of GoF Design Patterns in Java's core libraries问题中引述
All implementations of java.lang.Runnable are examples of Command pattern.
根据我对命令模式的理解,
Client 调用 Invoker => Invoker 调用 ConcreteCommand => ConcreteCommand调用Receiver方法,后者实现抽象的Command方法.
看看这个工作example
来自this article的命令模式UML图如下所示。
看看这段代码:
public class ThreadCommand{
public static void main(String args[]){
Thread t = new Thread(new MyRunnable());
t.start();
}
}
class MyRunnable implements Runnable{
public void run(){
System.out.println("Running:"+Thread.currentThread().getName());
}
}
- ThreadCommand 是 Client
- Runnable界面是Command
- MyRunnable 是 ConcreteCommmand
- Thread 是 Invoker 与
start()
方法调用 ConcreteCommand 实现(其中调用run()
方法)
是不是Receiver不见了?还是 MyRunnable 兼具 ConcreteCommand 和 Receiver?
接收者不会是...
System.out.println("Running:"+Thread.currentThread().getName());
调用运行方法。因为那是接收Runnable运行s.
时要做的动作此处已发布一个答案,已被作者立即删除。在阅读答案时,我找到了解决方案。
我可以简单地将上面的示例转换为命令模式 UML 图,只需一点小改动。
我可以将 Receiver 对象传递给 MyRunnable (ConcreteCommand)。
现在我已经更改了我的代码如下。
public class ThreadCommand{
public static void main(String args[]){
Receiver r = new AC();
Thread t = new Thread(new MyRunnable(r));
t.start();
}
}
class MyRunnable implements Runnable{
private Receiver receiver;
public MyRunnable(Receiver r){
this.receiver = r;
}
public void run(){
receiver.execute();
}
}
interface Receiver{
public void execute();
}
class AC implements Receiver{
public void execute(){
System.out.println("I am AC");
}
}
class Fan implements Receiver{
public void execute(){
System.out.println("I am Fan");
}
}
输出:
java ThreadCommand
I am AC
A Receiver 是可选的,取决于 ConcreteCommmand 是否拥有要执行的业务逻辑。从书的第 238 页开始,
A command can have a wide range of abilities. At one extreme it merely defines a binding between a receiver and the actions that carry out the request. At the other extreme it implements everything itself without delegating to a receiver at all.
在最初的问题中我们看到了一个没有接收者的例子,因为 MyRunnable
拥有要执行的逻辑。在这里的另外两个答案中,我们看到了委托给名为 Receiver
和 Account
.
我想给我两分钱...
原始命令模式将Command
对象与Receiver
对象分开,因为这两个集合的职责不同。
Receiver
拥有应用程序的业务逻辑。这些类型应该存在于模式之外。在实际情况下,Receiver
s 可能已经存在于代码库中,在命令之前。
例如,考虑到 bank 应用程序,接收者可以用以下类型表示:
public class Account {
private final double balance;
// Construct omissis
public Account deposit(double amount) {
// Deposit code
}
public Account withdraw(double amount) {
// Withdraw code
}
}
命令设计模式的目标之一是提供一种统一、同类和标准的方式来对一组对象(即接收者)执行操作。他们不必关心如何执行真正的业务逻辑。这将限制实现业务逻辑的代码的可重用性。
因此,Command
的实施必须将信息转发给 Receiver
。它遵循一个例子。
public class DepositCommand implements Command {
private final Account account;
// An instance of Command should reprenset only a single request
private final double amount;
public DepositCommand(Account account, double amount) {
this.account = account;
this.amount = amount;
}
public void execute() {
account.deposit(amount);
}
// Omissis..
}
总之,恕我直言,接受的答案中的陈述是不正确的。
The receiver is a relic of C/C++ in which the method to be invoked is separated from the object to invoke it on.