2012-08-28 7 views
11

Command pattern może być użyty do implementacji Transactional behavior (i Undo).
Ale nie mogłem znaleźć tego przykładu, googlując. Mogłem tylko znaleźć kilka trywialnych przykładów lampy, która jest switched on lub off.
Gdzie mogę znaleźć przykład kodu (najlepiej w Java) tego/tych zachowań zaimplementowanych przy użyciu Command Pattern?Przykład światowego przykładu zastosowania wzorca polecenia

Odpowiedz

11

W jednym z naszych projektów, mamy następujące wymagania:

  1. utworzyć rekord w DB.
  2. Zadzwoń do serwisu, aby zaktualizować powiązany rekord.
  3. Zadzwoń do innej usługi, aby zarejestrować bilet.

Aby wykonać tę operację w sposób transakcyjny, każda operacja jest realizowana jako polecenie z operacją cofania. Na końcu każdego kroku polecenie jest przekazywane na stos. Jeśli operacja nie powiedzie się na pewnym etapie, to wyskakujemy komendy ze stosu i wywołujemy operację cofania po każdym poleceniu. Operacja cofania każdego kroku jest zdefiniowana w tej implementacji polecenia, aby odwrócić wcześniejsze polecenie.execute().

Mam nadzieję, że to pomoże.

+0

Nie jestem pewien, czy śledzę. Transakcja jest wycofana. Nie składa się z operacji cofania. Jak zaimplementowałeś część atomową z wzorcem poleceń? – Jim

+0

W transakcji na poziomie bazy danych każda operacja jest poleceniem z operacjami cofania i ponawiania. Po wycofaniu system DBMS wywoła operację cofania, aby przywrócić zmiany wprowadzone w kopii przechowywanej bazy danych. Symulujemy to samo w rozproszonej transakcji obejmującej różne systemy. Czy teraz ma to sens? – Vikdor

+0

'przywrócić zmiany wprowadzone do kopii przechowywanej przez nią bazy danych'. Tak więc polecenie dotyczy najpierw kopii danych, a nie faktycznych danych? Myślałem, że to zastosowane bezpośrednio do danych, dlatego musisz 'cofnąć'. Twój opis jest dość jasny, ale potrzebuję trochę więcej szczegółów niższego poziomu, jeśli to możliwe, aby zobaczyć duży obraz – Jim

2
public final class Ping implements Callable<Boolean> { 

    private final InetAddress peer; 

    public Ping(final InetAddress peer) { 
    this.peer = peer; 
    } 

    public Boolean call() { 
    /* do the ping */ 
    ... 
    } 
} 
... 
final Future<Boolean> result 
    = executorService.submit(new Ping(InetAddress.getByName("google.com"))); 
System.out.println("google.com is " + (result.get() ? "UP" : "DOWN")); 
+5

Co to jest za przykład? – Jim

+0

@Jim artykuł w Wikipedii na temat wzorca wspomina wprost następujące kwestie: "* Typowa klasa puli wątków ogólnego zastosowania może mieć publiczną metodę' addTask', która dodaje element pracy do wewnętrznej kolejki zadań oczekujących na wykonanie ... Elementy w kolejce są obiektami poleceń, zazwyczaj obiekty te implementują wspólny interfejs, taki jak 'java.lang.Runnable', który pozwala puli wątków na wykonanie polecenia, mimo że sama klasa puli wątków została napisana bez żadnej wiedzy konkretnych zadań, dla których byłby używany. * " – oldrinb

+0

@Jim jest to taki przykład w Javie, z wyjątkiem użycia' Callable' w przeciwieństwie do 'Runnable' w połączeniu z [' ExecutorService'] (http: // docs. oracle.com/javase/7/docs/api/java/util/concurrent/ExecutorService.html). Podobny przykład można zobaczyć w dyskusji dotyczącej samego artykułu Wikipedii [tutaj] (http://en.wikipedia.org/wiki/Talk%3ACommand_pattern#Python_examples). – oldrinb

1

Wzory poleceń są używane w wielu miejscach.

  1. Oczywiście to, co widzisz wszędzie, to bardzo trywialny przykład implementacji GUI, przełączników. Jest również szeroko stosowany do tworzenia gier. Dzięki temu wzorowi użytkownik może również skonfigurować swoje przyciski na ekranie.
  2. Jest również używany w sieci, jeśli polecenie ma zostać przekazane do drugiego końca.
  3. Gdy programiści chcą przechowywać wszystkie polecenia wykonywane przez użytkownika, np. czasami gra pozwala ci odtworzyć cały poziom.
  4. Służy do realizacji połączeń zwrotnych.

Oto strona, która podaje przykład wzorca polecenia używanego do wywołania zwrotnego. http://www.javaworld.com/article/2077569/core-java/java-tip-68--learn-how-to-implement-the-command-pattern-in-java.html?page=2

  1. Oto kolejny link, który pokazuje wzór polecenia z bazą danych. Kod znajduje się w C#. http://www.codeproject.com/Articles/154606/Command-Pattern-at-Work-in-a-Database-Application
0

You have to define undo(), redo() operations along with execute() in Command interface itself.

przykład:

interface ChangeI { 
    enum State{ READY, DONE, UNDONE, STUCK } ; 
    State getState() ; 

    void execute() ;  
    void undo() ;  
    void redo() ; 
} 

Zdefiniuj państwo w swojej klasie ConcreteCommand. W zależności od aktualnej metody State po execute(), musisz zdecydować, czy polecenie powinno zostać dodane do Undo Stack lub Redo Stack i podjąć odpowiednią decyzję.

abstract class AbstractChange implements ChangeI { 
    State state = State.READY ; 

    public State getState() { return state ; } 

    public void execute() { 
     assert state == State.READY ; 
     try { doHook() ; state = State.DONE ; } 
     catch(Failure e) { state = State.STUCK ; } 
     catch(Throwable e) { assert false ; } 
    } 

    public void undo() { 
     assert state == State.DONE ; } 
     try { undoHook() ; state = State.UNDONE ; } 
     catch(Failure e) { state = State.STUCK ; } 
     catch(Throwable e) { assert false ; } 
    } 

    public void redo() { 
     assert state == State.UNDONE ; 
     try { redoHook() ; state = State.DONE ; } 
     catch(Failure e) { state = State.STUCK ; } 
     catch(Throwable e) { assert false ; } 
    } 

    protected abstract void doHook() throws Failure ; 

    protected abstract void undoHook() throws Failure ; 

    protected void redoHook() throws Failure { doHook() ;} ; 
} 

Zapoznaj się z artykułem o komendzie undo-redo, aby uzyskać lepsze zrozumienie.

Powiązane problemy