来自Examples of GoF Design Patterns in Java's core libraries问题,引用了
java.lang.Runnable的所有实现都是 Command 模式的示例。
根据我对命令模式的理解,
客户 来电推荐人 => 邀请者致电 ConcreteCommand => ConcreteCommand 调用 Receiver 方法,该方法实现了抽象命令方法。
看看这个有效的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());
}
}
start()
方法调用 ConcreteCommand 实现(调用run()
方法)接收器在这里丢失了吗?或MyRunnable是否扮演ConcreteCommand和Receiver的角色 ?
答案 0 :(得分:3)
此处已发布一个答案,作者立即将其删除。在阅读答案时,我找到了解决方案。
我可以简单地将上面的示例转换为Command模式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
答案 1 :(得分:3)
Receiver 是可选的,具体取决于 ConcreteCommmand 是否拥有要执行的业务逻辑。从本书第238页开始,
命令可以具有多种能力。在一个极端,它仅定义接收器与执行请求的动作之间的绑定。在另一个极端,它实现了一切,而根本没有委托给接收器。
在原始问题中,我们看到一个没有接收器的示例,因为MyRunnable
拥有要执行的逻辑。在另外两个答案中,我们看到代表名为Receiver
和Account
的显式接收器的示例。
答案 2 :(得分:0)
接收者不会......
System.out.println("Running:"+Thread.currentThread().getName());
调用run方法。因为那是在Runnable运行时接收要执行的操作。
答案 3 :(得分:0)
我想给我两分钱......
原始Command模式将Command
个对象与Receiver
个对象分开,因为这两个集合的责任是不同的。
Receiver
拥有应用程序的业务逻辑。这些类型应该存在于模式之外。在实际情况中,Receiver
可能已经存在于代码库中,在命令之前。
例如,考虑到银行应用程序,接收器可以用以下类型表示:
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..
}
总之,imho,接受答案中的陈述是不正确的。
接收器是C / C ++的遗留物,其中要调用的方法与对象分离以调用它。