6

Von Examples of GoF Design Patterns in Java's core libraries Frage wurde zitiert, dassBeispiel für ein Java-Befehlsmuster mit der Klasse Runnable: Ist der Empfänger nicht vorhanden?

Alle Implementierungen von java.lang.Runnable sind Beispiele für Befehl Muster.

Gemäß meinem Verständnis von Muster-Befehl,

KundeInvoker ruft =>Invoker nennt ConcreteCommand =>ConcreteCommand Anrufe Empfänger Methode, die abstrakt implementiert Befehl Methode.

Werfen Sie einen Blick auf diese example

Befehlsmuster UML-Diagramm von this article arbeitet wie unten gezeigt.

enter image description here

Werfen Sie einen Blick auf diesen Code:

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()); 
    } 
} 
  1. ThreadCommand ist Kunde
  2. Runnable Schnittstelle ist Befehl
  3. MyRunnable ist ConcreteCommmand
  4. ThemaInvoker mit start() Methode aufrufen ConcreteCommand implementaiton ist hier fehlt

Ist-Empfänger (die run() Methode aufruft)? Oder spielt MyRunnable die kombinierte Rolle von ConcreteCommand und Receiver?

Antwort

3

Der Empfänger ist ein Überbleibsel von C/C++ in dem das Verfahren aufgerufen wird, wird von dem Objekt getrennt es aufzurufen auf. Sie können dieses Verhalten in Java implementieren, indem Sie eine Methode mit Reflektion übergeben. Aber wie Sie vermuten, ist der idiomatische Java-Ansatz, den konkreten Befehl und Empfänger als ein Objekt zu behandeln.

+0

Das Objekt * receiver * ist der Typ, der die Geschäftslogik einer Anwendung darstellt. Die Verantwortung eines Befehls besteht nicht darin, die Geschäftslogik zu besitzen, sondern diese Geschäftslogik Clients zur Verfügung zu stellen, die eine gemeinsame und Standardschnittstelle verwenden, d. H. Die "Ausführen" -Methode. Dann denke ich, dass der Empfänger nicht nur ein Relikt von C/C++ ist. –

0

Würde Empfänger nicht ...

System.out.println("Running:"+Thread.currentThread().getName()); 

Aufruf in der run-Methode. Weil das die Aktion erhält, die ausgeführt werden soll, wenn das Runnable ausgeführt wird.

1

Eine Antwort wurde hier veröffentlicht und sie wurde sofort vom Autor entfernt. Während ich die Antwort gelesen habe, habe ich eine Lösung gefunden.

Ich kann einfach oben Beispiel zu Command Pattern UML-Diagramm mit einer kleinen Änderung konvertieren.

kann ich Receiver Objekt MyRunnable (ConcreteCommand) passieren.

Jetzt habe ich meinen Code wie folgt geändert.

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"); 
    } 
} 

Output:

java ThreadCommand 
I am AC 
0

Ich will meinen zwei Cent geben ...

Das ursprüngliche Befehlsmuster trennt die Command Objekte aus den Receiver Objekten, weil die Verantwortung der beiden Sätze unterschiedlich ist.

Receiver s eigene die Geschäftslogik der Anwendung. Diese Typen sollten außerhalb des Musters existieren. In einem praktischen Fall waren Receiver s wahrscheinlich bereits in der Codebasis vor Befehlen vorhanden.

Zum Beispiel denken an eine Bank Anwendung, ein Empfänger kann durch die folgende Art dargestellt werden:

public class Account { 
    private final double balance; 
    // Construct omissis 
    public Account deposit(double amount) { 
     // Deposit code 
    } 
    public Account withdraw(double amount) { 
     // Withdraw code 
    } 
} 

Eines der Ziele des Befehl Entwurfsmuster ist, dass eine einheitliche von geben, homogene und standardmäßige Art, Operationen an einer Menge von Objekten (dh den Empfängern) auszuführen. Sie müssen sich nicht darum kümmern, wie sie die echte Geschäftslogik ausführen. Dies wird begrenzen die Wiederverwendbarkeit des Codes Business-Logik implementieren.

Aus diesem Grund muss die Command s Implementierung die Information an Receiver weiterleiten. Es folgt ein Beispiel.

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.. 
} 

Abschließend imho ist die Aussage in der akzeptierte Antwort nicht korrekt.

Der Empfänger ist ein Relikt von C/C++, in dem die aufzurufende Methode vom Objekt getrennt wird, um sie aufzurufen.