Try English version of Quizful



Раздаем бесплатные Q! подробности в группе Quizful.Alpha-test
Топ контрибуторов
loading
loading
Знаете ли Вы, что

После прохождения теста можно комментировать вопросы теста, а Ваши комментарии увидят модераторы теста и пользователи, которым когда-либо эти вопросы попадались.

Лента обновлений
ссылка 14:04:08
Комментарий от coven:
а почему разные маски? разве у второго ПК не долдна быть т...
ссылка 12:42:02
Комментарий от zyurii:
Вибачаюсь за свого співвітчизника. І погоджуюсь з Вашим т...
ссылка Jul 21 23:10
Комментарий от KlimAndr:
если бы речь шла об одной акции и 99 споров и вопросов ...
ссылка Jul 21 22:36
Комментарий от KlimAndr:
? по первым двум буквам , видно,что три младшие линии ...
ссылка Jul 21 21:46
Комментарий от KlimAndr:
мне понравилось.+
Статистика

Тестов: 153, вопросов: 8599. Пройдено: 411050 / 2001594.

Паттерн Command и лямбда выражения

head tail Статья
категория
Java
дата17.11.2014
авторezozulya
голосов19

Паттерн Command инкапсулирует обработку команды в виде объекта, что позволяет сохранять, передавать в качестве параметров методам, а также возвращать его в виде результата и выполнять иные манипуляции как и с любым другим объектом.

Лучше всего паттерн Command использовать, если:

  • необходимо управлять отменой и повторным выполнением команд;
  • необходимо поддерживать регистрацию выполненных команд;
  • необходимо обеспечить постановку команд в очередь и их выполнением в заданное время;
  • требуется отделить источник запроса от объекта, отвечающего на запрос.
  • UML-диаграмма классов паттерна Command представлена ниже:

Command

Описание элементов диаграммы:

Command- предоставляет интерфейс (либо абстрактный класс) для выполнения команды, которые использует Invoker. Invoker- класс, вызывающий методы для выполнения команд.

Receiver- объект, которому предназначен объект Command и располагает всею информациею о способах выполнения операций, необходимых для удовлетворения запроса. В качестве получателя может выступать любой класс и который выполняет указанный в команде метод.

ConcreteCommand- реализует интерфейс Command. В нем хранится ссылка для выполнения конкретной команды объекта Receiver.

Client- создает объект класса ConcreteCommand и устанавливает ему объект Receiver.

Рассмотрим пример реализованный без использования лямбда выражений. Есть документ в который можно добавлять записи в начало документа, в конец и в средину. Есть менеджер для выполнения команд по обработке документа.

  • описание интерфейса Command и ConcreteCommand:

 //Command
public interface Command {           
   public void execute();           
}

//ConcreteCommand
public class AddStringBegin implements Command {
  private Document document;           
  private String str;
  public AddStringBegin(Document document, String str) {                       
     this.document= document;                       
     this.str= str;           
  }
  @Override           
  public void execute() {                       
     document.addStringBefore(str);                       
     document.output("Add string ("+str+") before document");           
  }
}

//ConcreteCommand
public class AddStringEnd implements Command {
  private Document document;           
  private String str;
  public AddStringEnd(Document document, String str) {                       
     this.document= document;                       
     this.str= str;           
  }
  @Override           
  public void execute() {                       
     document.addStringAfter(str);                       
     document.output("Add string ("+ str+") after document");           
  }
}

//ConcreteCommand
public class InsertStringCommand implements Command{
private Document document;
private String str;
private int position;
public InsertStringCommand(Document document, String str, intposition) {                       
   this.document= document;                       
   this.str= str;                       
   this.position = position;           
}
@Overridepublic void execute() {                       
   document.insertString(str, position);                       
   document.output("Insert string ("+ str+")to position "+ position);           
  }
}
  • реализация Receiver (получатель) – располагает информацией о способах выполнения операций :

 //Receiver
public class Document {
   private StringBuffer document= new StringBuffer("test");
           
   public void addStringBefore(String str){                       
      document= new StringBuffer(str).append(document);           
   }
   public void insertString(String str, int position){               
      document.insert(position, str);           
   }
   public void addStringAfter(String str){                       
      document.append(str);           
   }
   public void output(String str){                       
      System.out.println("Operation [ "+ str + " ]: result = "+ document.toString());
   }
}
  • реализация Invoker (инициатор)-обращается к командам для их выполнения :

//Invoker 
import java.util.ArrayList;
public class ManagerCommands {
   private ArrayList listCommands= new ArrayList();
   public void addCommand(Command command){
      listCommands.add(command);           
   }
   public void run(){                       
      for(Command command:listCommands){                                  
          command.execute();                       
      }           
   }
}

Следующий класс используется для запуска примера:


public class TestRun {
   public static void main(String[] args) {                       
      String textBefore = "before-";                       
      String textAfter = "-after";                      
      String insert = "insert";                       
      Document document = new Document();                       
      Command addBefore = new AddStringBegin(document, textBefore);                       
      Command addAfter = new AddStringEnd(document, textAfter);                       
      Command insertStr = new InsertStringCommand(document, insert, 2);
      ManagerCommands manager = new ManagerCommands();                       
      manager.addCommand(addBefore);                       
      manager.addCommand(addAfter);                       
      manager.addCommand(insertStr);                       
      manager.run();           
   }
}

Результат выполнения программы:


Operation [ Add string (before-) before document ] : result = before-test

Operation [ Add string (-after) after document ] : result = before-test-after

Operation [ Insert string (insert)to position 2 ] : result = beinsertfore-test-after

Благодаря лямбда-выражениям весь паттерн можно значительно упростить, полностью отказавшись от обертывающих классов. Теперь класс для запуска приложения принимает следующий вид:


public class TestRun {
   public static void main(String[] args){                       
      String textBefore= "before-";                       
      String textAfter= "-after";                       
      String insert= "insert";                       
      Document document= new Document();                       
      ManagerCommands manager= new ManagerCommands();
       manager.addCommand(()-> {
           document.addStringBefore(textBefore); 
           document.output("Add string ("+ textBefore+") before document");                       
      });                       
      manager.addCommand(()-> {          
         document.addStringAfter(textAfter);         
         document.output("Add string ("+ textAfter+") after document");                       
      });
      manager.addCommand(()-> {                                  
          document.insertString(insert,2);                                  
          document.output("Insert string ("+ insert+")to position "+ 2);                       
      });                       
      manager.execute();           
   } 
}

Паттерн Command изначально служил заменой отсутствующим в языке лямбда-выражениям. Пользуясь настоящими лямбда-выражениями, можно код сделать чище, убрав лишние служебные конструкции и прояснив его назначение.

Если Вам понравилась статья, проголосуйте за нее

Голосов: 19  loading...
ezozulya   demonoid2013   t_nikolya2013   fiests   nvgup   opnikol2013   cntower   VVATOR   dimon_lvov   apolonxviii   andrewwonder   Nadya2308   SamTan   roman19   GosDep   alex83231   tarasmonamach   Airat_Gimaev   museab