2015-04-15 37 views
6

Vì vậy, tôi có một chương trình mà bạn có thể đăng nhập và thêm/xóa bạn bè đến và đi từ friends ArrayList. Ngoài ra tôi có thể thích một thứ nhất định và thứ đó sẽ được lưu trữ trong danh sách mảng likes. Tôi được yêu cầu thực hiện các tùy chọn hoàn tác và làm lại cho bất kỳ hành động nào tôi thực hiện.Sử dụng mẫu Command cho Undo và Redo trong ArrayLists

Vì vậy, tôi muốn thêm apple làm bạn. Sau đó khi tôi chọn tùy chọn hoàn tác, tôi có thể hoàn tác hành động để táo sẽ không là bạn của tôi. Làm thế nào tôi có thể tiếp cận này với một Command Pattern khi đầu vào là bất cứ tên hoặc chữ I đầu vào để lưu trữ vào friends ArrayList?

tôi đã làm một số nghiên cứu và thấy rằng việc sử dụng một mô hình lệnh có thể là lựa chọn tốt nhất của tôi kể từ khi điều này đã được thực hiện dưới sự Lớp Facebook tôi đã có. Tôi giả sử tôi sẽ phải sử dụng hai ngăn xếp khác nhau, nhưng tôi bị mất một chút trong chủ đề.

Tôi quyết định thêm các phần của những gì tôi có để tôi có thể được trợ giúp thêm một chút về những gì tôi cần làm và những gì chương trình của tôi làm.

Trong chương trình lái xe

Facebook facebook1 = new Facebook(); 

      if (userInput == 6) 
      { 
       System.out.println("Login"); 
       String operand1 = getOperand("What is the Username? "); 
       String operand2 = getOperand("What is the Password? "); 
       System.out.println("Enter a friend to be added. "); 
       String operand3 = getOperand("What is the Username? "); 
       facebook1.friend(operand3); 
      } 

      if (userInput == 7) 
      { 
       System.out.println("Login"); 
       String operand1 = getOperand("What is the Username? "); 
       String operand2 = getOperand("What is the Password? "); 
       System.out.println("Enter a friend to be removed. "); 
       String operand3 = getOperand("What is the Username? "); 
       facebook1.defriend(operand3); 
      } 
      if (userInput == 12) 
      { 
       System.out.println("Login"); 
       String operand1 = getOperand("What is the Password? "); 
       facebook1.undo(); 
      } 

      if (userInput == 13) 
      { 
       System.out.println("Login"); 
       String operand1 = getOperand("What is the Password? "); 
       facebook1.redo(); 
      } 

Trong Facebook Lớp

ArrayList<FacebookUser> recommendedFriends = new ArrayList<FacebookUser>(); 

void friend(String newFriend) 
    { 
     boolean positiveChecker = false; 

     for (int i = 0; i < recommendedFriends.size(); i++) 
     { 

      if (recommendedFriends.get(i).toString().equalsIgnoreCase(newFriend)) 
      { 
       System.out.println("Error: This friend already exists."); 
       positiveChecker = true; 
      } 

     } 
     if (positiveChecker == false) 
     { 
      FacebookUser friend = new FacebookUser(newFriend, newFriend); 
      recommendedFriends.add(friend); 
      System.out.println(friend + " is now your friend."); 
     } 
     positiveChecker = false; 
    } 

    void defriend(String formerFriend) 
    { 
     boolean positiveChecker = false; 

      for (int i = 0; i < recommendedFriends.size(); i++) 
      { 

       if (recommendedFriends.get(i).toString().equalsIgnoreCase(formerFriend)) 
       { 
        recommendedFriends.remove(i); 
        System.out.println(formerFriend + " has been removed from your friends list."); 
        positiveChecker = true; 
       } 
       if (recommendedFriends.size() == (i + 1) && recommendedFriends.get(i).toString() != formerFriend 
         && positiveChecker == false) 
       { 
        System.out.println("Error: There is no friend with this username."); 

       } 

      } 
      positiveChecker = false; 
    } 

public interface Command 
    { 
     public void undo(); 
     public void redo(); 
    } 
+0

có thể trùng lặp của [hoàn tác và thực hiện lại trong Java] (http://stackoverflow.com/questions/7374545/the-undo-and-redo-implementation-in-java) –

+0

iirc, bạn chỉ cần một ngăn xếp . –

Trả lời

3

Khi bạn lùi lại 2 điều sau đó làm một hành động hoàn toàn mới, bạn cần phải "quên" "làm lại lịch sử" và thay thế bằng lệnh mới, phải không?

Ví dụ ...

  1. Thêm Bạn bè Jim
  2. Thêm Bạn bè Bill
  3. Thêm Bạn bè Jill
  4. Di Jim
  5. Undo
  6. Undo

Nhà nước nên là "Jim" và "Bill".

Vì vậy, bạn chỉ thực sự cần một danh sách và một con trỏ đến "lệnh" hiện nay, ví dụ ...

// Note: NOT thread safe! 
public class CommandStack { 
    private List<Command> commands = Collections.emptyList(); 
    private int nextPointer = 0; 

    public void doCommand(Command command) { 
     List<Command> newList = new ArrayList<>(nextPointer + 1) 

     for(int k = 0; k < nextPointer; k++) { 
      newList.add(commands.get(k)); 
     } 

     newList.add(command); 

     commands = newList; 
     nextPointer++; 

     // Do the command here, or return it to whatever called this to be done, or maybe it has already been done by now or something 
     // (I can only guess on what your code currently looks like...) 
     command.execute(); 
    } 

    public boolean canUndo() { 
     return nextPointer > 0; 
    } 

    public void undo() { 
     if(canUndo()) { 
      nextPointer--; 
      Command commandToUndo = commands.get(nextPointer); 
      // Undo the command, or return it to whatever called this to be undone, or something 
      command.undo(); 
     } else { 
      throw new IllegalStateExcpetion("Cannot undo"); 
     } 
    } 

    public boolean canRedo() { 
     return nextPointer < commands.size(); 
    } 

    public void redo() { 
     if(canRedo()) { 
      commandToDo = commands.get(nextPointer); 
      nextPointer++; 
      // Do the command, or return it to whatever called this to be re-done, or something 
      commandToDo.execute(); 
     } else { 
      throw new IllegalStateException("Cannot redo"); 
     } 
    } 
} 

Nếu tôi có ...

interface Command { /* execute/undo etc */ } 

public class AddFriendCommand implements Command { 
    private String friendName; 

    // ... other fields, constructor/getters etc ... 

    public void execute() { 
     // Actually do it... 
     System.out.println("Added friend " + name); 
    } 

    public void undo() { 
     // Undo it... 
     System.out.println("Removed friend " + name); 
    } 
} 

public class RemoveFriendCommand implements Command { 
    private String friendName; 

    // ... other fields, constructor/getters etc ... 

    public void execute() { 
     // Actually do it, maybe throw exception if friend does not exist? 
     // (that would have to be a runtime exception unless you want the interface's method to throw stuff); 
     System.out.println("Removed friend " + name); 
    } 

    public void undo() { 
     // Undo it... 
     System.out.println("Added friend " + name); 
    } 
} 

Bạn có thể lặp lại trình tự ở trên sử dụng ...

CommandStack stack = new CommandStack(); 

stack.doCommand(new AddFriendCommand("Jim")); 
stack.doCommand(new AddFriendCommand("Bill")); 
stack.doCommand(new AddFriendCommand("Jill")); 
stack.doCommand(new RemoveFreindCommand("Jim")); 

stack.undo(); 
stack.undo(); 

Nếu bây giờ bạn đã làm một lệnh mới (thông qua doCommand) nó sẽ quên rằng bạn đã bao giờ nói thêm "Jill" hoặc gỡ bỏ "Jim", nhưng thay vào đó bây giờ sẽ nhớ những lệnh mới và phần còn lại của lịch sử lệnh đó đã không được hoàn tác.

Hy vọng điều này sẽ hữu ích.

+0

Tôi đã thêm nhiều mã hơn để giúp bạn dễ dàng hơn. Vậy điều này có nghĩa là tôi phải tạo một lớp mới và sử dụng một con trỏ cho giao diện lệnh? – Ultimania

+0

@ user2904667 Đó là một cách để thực hiện ... – BretC

+0

Nevermind. Tôi nghĩ rằng tôi đã nhận nó ngay bây giờ. Cảm ơn bạn! – Ultimania

0

Bạn đang hiểu nhầm như thế nào mô hình lệnh hoạt động. Bạn muốn có một số riêng biệt List trong số Commands của mình, trong đó mỗi phiên bản Lệnh đại diện cho một hành động .

Vì vậy, bạn sẽ muốn có một cái gì đó như:

List<Command> actionStack; 

và sau đó có những thứ như

public class AddCommand implements Command { 
    private final void List<FacebookUser> userList; 
    private final void FacebookUser newUser; 

    public AddCommand(List<FacebookUser> userList, FacebookUser newUser) { 
     this.userList = userList; 
     this.newUser = newUser; 
    } 

    @Override 
    public void undo() { 
     userList.remove(newUser); 
    } 

    @Override 
    public void redo() { 
     userList.add(newUser); 
    } 
} 
+0

Tôi vẫn cần một chút trợ giúp về vấn đề này. Tôi có thể cung cấp cho bạn mã của tôi để làm cho mọi việc dễ dàng hơn một chút không? – Ultimania

+0

@ user2904667 vui lòng ** chỉnh sửa ** câu hỏi của bạn với ** vấn đề ** cụ thể của bạn. Không chỉ đổ tất cả mã của bạn. – durron597

+0

Hy vọng điều này sẽ giúp bạn giúp tôi nhiều hơn một chút. – Ultimania

Các vấn đề liên quan