JavaRush /Java блог /Random /Кофе-брейк #233. Шаблон проектирования Command (Команда)....

Кофе-брейк #233. Шаблон проектирования Command (Команда). 8 самых каверзных вопросов по Java для новичков

Статья из группы Random

Шаблон проектирования Command (Команда)

Источник: Medium Благодаря этому руководству вы узнаете, для чего необходим шаблон проектирования Command (Команда) и ознакомитесь с его реализацией на языке Java. Кофе-брейк #233. Шаблон проектирования Command (Команда). 8 самых каверзных вопросов по Java для новичков - 1Шаблон Command (Команда) — это поведенческий шаблон (паттерн) проектирования, который превращает запрос (действие или операцию) в автономный объект, содержащий всю информацию о запросе. Шаблон проектирования Command оборачивает (упаковывает) объекты, которые выполняют запросы пользователя. Таким образом, одна и та же структура кода может использоваться снова и снова. Каждый процесс, который должен выполняться в шаблоне Command, упаковывается как объект. Обработанные объекты команды могут быть разными. Сначала объект для обработки передается классу Command в качестве параметра, а затем над этим объектом выполняются различные операции. Преимуществом создания команды виде объектов является то, что при необходимости их можно научить отменять свои действия. В результате можно выполнять операции Redo (Повторить) или Undo (Отменить) и создать функцию макроса. Шаблон Command включает в себя следующие ключевые компоненты:
  • Command — это интерфейс или абстрактный класс, который объявляет метод execute(). Этот метод определяет операцию, которую необходимо выполнить.
  • Concrete Command — это реализации интерфейса Command. Каждая конкретная команда инкапсулирует конкретный запрос и привязывает его к получателю, вызывая соответствующую операцию на получателе.
  • Receiver (Получатель) — это объект, который выполняет фактическую операцию во время выполнении команды. Receiver знает, как выполнить запрос.
  • Invoker (Вызывающий) — Invoker отвечает за инициирование выполнения команды. Он содержит ссылку на объект команды и может выполнить команду, вызвав ее метод execute().
  • Client — Клиент отвечает за создание объектов команды, настройку их получателей и связывание их с вызывающими.
Теперь взглянем на реализацию шаблона:

// Шаг 1: Создаем интерфейс Command
interface Command {
    void execute();
}

// Шаг 2: Создание классов Concrete Command
class LightOnCommand implements Command {
    private Light light;

    public LightOnCommand(Light light) {
        this.light = light;
    }

    public void execute() {
        light.turnOn();
    }
}

class LightOffCommand implements Command {
    private Light light;

    public LightOffCommand(Light light) {
        this.light = light;
    }

    public void execute() {
        light.turnOff();
    }
}

class LightChangeColorCommand implements Command {
  private Light light;

  public LightChangeColorCommand(Light light) {
    this.light = light;
  }

  public void execute() {
    light.changeColor();
  }
}

// Шаг 3: Создаем класс Receiver
class Light {
    public void turnOn() {
        System.out.println("Light is on");
    }

    public void turnOff() {
        System.out.println("Light is off");
    }

    public void changeColor() {
      System.out.println("Light color has been changed");
    }
}

// Шаг 4: Создайте класс Invoker
class RemoteControl {
    private Command command;

    public void setCommand(Command command) {
        this.command = command;
    }

    public void pressButton() {
        command.execute();
    }
}

// Шаг 5: Создаем класс Client
class Client {
    public static void main(String[] args) {
        // Создаем receiver
        Light light = new Light();

        // Создаем команды
        LightOnCommand lightOnCommand = new LightOnCommand(light);
        LightOffCommand lightOffCommand = new LightOffCommand(light);
        LightChangeColorCommand lightChangeColorCommand = new LightChangeColorCommand(light);

        // Создаем invoker
        RemoteControl remoteControl = new RemoteControl();

        // Устанавливаем команды в invoker
        remoteControl.setCommand(lightOnCommand);

        // Нажмите кнопку, чтобы включить свет
        remoteControl.pressButton();

        // Устанавливаем другую команду в invoker
        remoteControl.setCommand(lightOffCommand);

        // Нажмите кнопку, чтобы выключить свет
        remoteControl.pressButton();

        // Устанавливаем другую команду в invoker
        remoteControl.setCommand(lightChangeColorCommand);

        // Нажмите кнопку, чтобы изменить цвет света
        remoteControl.pressButton();
    }
}
Шаблоны Command (Команда) и Strategy (Стратегия) оба являются поведенческими шаблонами проектирования. Они могут выглядеть одинаково, потому что вы можете использовать их для параметризации объекта с помощью определенного действия. Однако они служат разным целям. Шаблон Стратегия предназначен для динамического выбора и переключения алгоритмов, а шаблон Команда — для инкапсуляции и разделения запросов как объектов.

Области использования

Паттерн Command можно применять в различных областях, в том числе:
  1. Пользовательские интерфейсы. Шаблон Command обычно используется в средах и приложениях с графическим интерфейсом для обработки действий и операций пользователя. Каждое действие пользователя инкапсулируется в виде объекта Command, что позволяет приложению управлять ими и выполнять их по мере необходимости.
  2. Транзакционные системы. Шаблон Command подходит для реализации транзакционных систем, где ряд действий необходимо выполнить или откатить как единую атомарную единицу. Каждый объект команды представляет собой отдельное действие, а менеджер транзакций организует их выполнение.
  3. Системы меню и сочетания клавиш. Приложения, использующие меню и сочетания клавиш, также могут использовать шаблон Command. Каждый пункт меню или ярлык может быть связан с объектом команды, который при вызове выполняет соответствующее действие.
  4. Многоуровневая отмена/возврат. Шаблон Command облегчает реализацию функций отмены и повтора в приложениях. Сохраняя историю выполненных команд, вы можете легко отменить или повторно применить их для выполнения операций отмены и повтора.
  5. Планирование задач и очереди заданий. В системах, требующих планирования и постановки задач или заданий в очередь, можно использовать шаблон Command. Каждая задача или задание могут быть инкапсулированы в виде командного объекта, что позволяет системе планировать, расставлять приоритеты и выполнять их соответствующим образом.
  6. Удаленные вызовы процедур и работа в сети.Шаблон Command можно использовать в распределенных системах, особенно для реализации удаленных вызовов процедур. Объект команды содержит необходимые данные и логику, необходимые для вызова удаленных методов или выполнения операций в удаленных системах.
Это всего лишь несколько примеров областей использования шаблона Command. Его гибкость и способность инкапсулировать запросы делают его применимым в различных сценариях, где нужны слабая связанность (loose coupling), расширяемость и гибкость.

8 самых каверзных вопросов по Java для новичков

Источник: Medium Перед вами подборка из восьми каверзных вопросов по Java, которые могут встретиться начинающим разработчикам во время технического собеседования.

1. Почему Java не является 100% объектно-ориентированным языком?

Java использует примитивные типы данных, такие как byte, char, boolean, int, float, double, long и short. Они не рассматриваются как объекты, а являются предопределенными неизменяемыми типами. Чтобы сделать их объектно-ориентированными, созданы классы-оболочки, которые предоставляют способ преобразования примитивного типа данных в объект и наоборот. Еще одна причина, по которой Java не является 100% объектно-ориентированным языком, это использование Static. Каждый раз, когда класс объявляется статическим, его можно использовать без объекта.

2. Почему в Java не используются указатели?

Java не использует указатели (pointers), потому что с помощью указателя можно получить прямой доступ к области памяти, а это представляет проблему безопасности.

3. Что такое JIT-компилятор в Java?

JIT-компилятор (Just-In-Time Compiler) является частью JVM и используется для преобразования байтового кода в машинный код, что повышает производительность приложения. JIT-компилятор включен по умолчанию. Когда метод скомпилирован, JVM вызывает скомпилированный код этого метода напрямую, а не интерпретирует его. Вы можете отключить JIT-компилятор, но в этом случае будет интерпретироваться вся Java-программа. Поэтому отключение JIT-компилятора не рекомендуется

4. Почему строки неизменяемы в Java?

Строка неизменяема в Java, потому что пулы строк (String pool) требуют, чтобы строка оставалась неизменной. Пул строк — это пространство хранения в куче памяти Java, где хранятся строковые литералы. Кроме того, строка используется в разных областях, таких как файловая система или соединения с базой данных, она может быть идентификатором пользователя или паролем. Поэтому будет крайне небезопасно, если такие строки не являются неизменными и могут быть изменены любым сторонним лицом или программным обеспечением.

5. Можно ли переопределить частный (private) или статический (static) метод в Java?

Вы не можете переопределить частный или статический метод в Java. Если вы создадите аналогичный метод с тем же типом возвращаемого значения и теми же аргументами метода в дочернем классе, то он скроет метод суперкласса; это известно как сокрытие метода. Что касается частного метода, то точно так же вы не можете переопределить частный метод в подклассе, потому что он там недоступен. Что вы можете сделать, так это создать еще один частный метод с тем же именем в дочернем классе.

6. Всегда ли блок finally выполняется в Java?

В большинстве случаев да, но не всегда. Например, блок finally не выполняется:
  1. Если вы вызываете System.exit().
  2. Если вы вызываете Runtime.getRuntime().halt(exitStatus).
  3. Если JVM достигает бесконечного цикла в блоке try или catch.
  4. Если операционная система принудительно завершает процесс JVM.
  5. Если хост-система выключается, например, из-за сбоя питания или аппаратной ошибки.
  6. Если блок finally будет выполняться потоком демона (daemon thread), а все остальные потоки, не являющиеся демонами, завершатся до вызова finally.

7. Что такое класс Object и какие у него методы?

Класс Object находится в пакете java.lang. Он работает как корень иерархии наследования в любой программе Java. Важные методы класса Object:
  • equals — этот метод используется для проверки равенства содержимого между двумя объектами в соответствии с указанной бизнес-логикой, тогда как == проверяет ссылки.
  • clone — создает и возвращает копию этого объекта.
  • finalize — этот метод запускается, когда нет ссылок на какой-либо объект, и он скоро будет собран сборщиком мусора.
  • public final Class getClass() — возвращает класс времени выполнения объекта.
  • public int hashCode() — возвращает значение хэш-кода для объекта.
  • public String toString() — возвращает строковое представление объекта.

8. Как сделать класс неизменяемым в Java?

Чтобы класс сделать неизменяемым в Java, выполните следующее:
  • Объявите класс final, чтобы его нельзя было расширить.
  • Сделайте все поля private, чтобы прямой доступ был запрещен.
  • Не предоставляйте методы установки для переменных.
  • Сделайте все изменяемые поля final, чтобы их значение можно было назначить только один раз.
  • Инициализируйте все поля с помощью метода Constructor, выполняющего глубокое копирование.
  • Выполните клонирование объектов в методах getter, чтобы вернуть копию, а не реальную ссылку на объект.
Комментарии (1)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
King Kazzzma 007 Уровень 45
22 апреля 2024
пункт 7: как насчет notify и wait?