Шаблон расширенного проектирования Java № 8 — шаблон цепочки ответственности и шаблон команд

Java задняя часть Шаблоны проектирования
Шаблон расширенного проектирования Java № 8 — шаблон цепочки ответственности и шаблон команд

предисловие

существуетПредыдущийВ , мы узнали о шаблонах Приспособленца и Прокси структурных шаблонов. В этой статье мы изучим два паттерна поведенческих паттернов: паттерн цепочки ответственности и паттерн команд.

Модель цепочки ответственности

Введение

Шаблон цепочки ответственности, как следует из его названия, создает цепочку объектов-получателей для запроса. Этот шаблон указывает тип запроса, разделяя отправителя и получателя запроса. Этот тип шаблона проектирования является поведенческим шаблоном. В этом шаблоне обычно каждый получатель содержит ссылку на другой получатель. Если объект не может обработать запрос, он передаст тот же запрос следующему получателю и так далее.

Простое понимание заключается в выполнении иерархической обработки. В жизни чаще встречаются заявления об отпуске, командировке, повышении зарплаты и т. д., а в работе чаще встречаются перехватчики и фильтры. Если заявление на отпуск подано предыдущим способом, инициатор должен подать заявление с каждым ответственным лицом, что будет более проблематично, но теперь обычно используется процесс ОД, и требуется только одно заявление ОД. Это также типичная модель цепочки ответственности.Инициатору нужно только отправить запрос в цепочку ответственности, и ему не нужно заботиться о деталях обработки и передаче запроса.

Модель цепочки ответственности в основном состоит из этих трех ролей: интерфейса получателя запроса (Handler), класса реализации запроса (ConcreteHandler) и отправителя запроса (Client).

  • Интерфейс получателя запроса: определяет интерфейс, который может обрабатывать запрос клиента, включая ссылку на объект, которая «может быть связана со следующим, который также может обрабатывать запрос».
  • Класс реализации запроса: реализует интерфейс обработки запроса и определяет, может ли сам объект обработать запрос.Если запрос не может быть выполнен, он будет передан преемнику для обработки.
  • Отправитель запроса: отправляет запрос первому объекту-получателю и ожидает ответа на запрос.

Здесь для удобства понимания мы используем простой пример для иллюстрации. В определенном отделе компании, чтобы активизировать атмосферу в отделе, руководитель спросил мнение членов отдела, поэтому члены отдела активно выдвигали предложения, и, наконец, руководитель принял выдвинутое предложение. xuwujing и сообщил о предложении подать заявку на финансирование деятельности. Затем мы можем использовать модель цепочки ответственности для развития по примеру здесь.Во-первых, есть три уровня лидеров для ускорения.У них есть общая черта, то есть они могут управлять делами на своих соответствующих уровнях.Тогда мы можем определить абстрактный класс для лидеров и определить абстрактный метод для обработки вещей и установки уровня параметров, то код этого абстрактного класса выглядит следующим образом:


abstract class Learder{

   protected Learder learder;
   
   protected void setLearder(Learder learder){
   	this.learder=learder;
   }
   
   protected Learder getLearder(){
   	return learder;
   }
   
   abstract void handler(int  level);
}

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

class Supervisor extends Learder{
    private String name;
    private String something;
    public Supervisor(String name,String something) {
   	this.name=name;
   	this.something=something;
   }
   
   @Override
   void handler(int level) {
   	//如果级别在自己的处理范围之内
   	if(level>1){
   		System.out.println("主管同意了  "+name+"所述的<"+something+">事情!");
   	}else{
   		System.out.println("主管未能处理  "+name+"所述的<"+something+">事情!转交给上级!");
   		getLearder().handler(level);
   	}
   }
}


class BranchManager extends Learder{
    private String name;
    private String something;
    public BranchManager(String name,String something) {
   	this.name=name;
   	this.something=something;
   }
   
   @Override
   void handler(int level) {
   	boolean flag=true;
   	//如果级别在自己的处理范围之内
   	if(level>0){
   		//这就就直接设置同意了
   		if(flag){
   			System.out.println("部门经理同意了  "+name+"所述的<"+something+">事情!");
   		}else{
   			System.out.println("部门经理不同意  "+name+"所述的<"+something+">事情!");
   		}
   	}else{
   		System.out.println("部门经理未能处理  "+name+"所述的<"+something+">事情!转交给上级!");
   		getLearder().handler(level);
   	}
   }
}


class GeneralManager extends Learder{
    private String name;
    private String something;
    public GeneralManager(String name,String something) {
   	this.name=name;
   	this.something=something;
   }
   
   @Override
   void handler(int level) {
   	boolean flag=false;
   	//如果级别在自己的处理范围之内
   	if(level>-1){
   		//这就就直接设置不同意了
   		if(flag){
   			System.out.println("总经理同意了  "+name+"所述的<"+something+">事情!");
   		}else{
   			System.out.println("总经理不同意  "+name+"所述的<"+something+">事情!");
   		}
   		
   	}else{
   		System.out.println("总经理未能处理  "+name+"所述的<"+something+">事情!转交给上级!");
   		getLearder().handler(level);
   	}
   }
}

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


public static void main(String[] args) {
   	String name = "xuwujing";
   	String something = "去聚餐";
   	String something2 = "去旅游";
   	Learder learder1 =new Supervisor(name, something);
   	Learder learder2 =new BranchManager(name, something);
   	Learder learder3 =new GeneralManager(name, something);
   	learder1.setLearder(learder2);
   	learder2.setLearder(learder3);
   	learder1.handler(1);
   	
   	Learder learder4 =new Supervisor(name, something2);
   	Learder learder5 =new BranchManager(name, something2);
   	Learder learder6 =new GeneralManager(name, something2);
   	learder4.setLearder(learder5);
   	learder5.setLearder(learder6);
   	learder4.handler(0);

}

Выходной результат:


		主管未能处理  xuwujing所述的<去聚餐>事情!转交给上级!
		部门经理同意了  xuwujing所述的<去聚餐>事情!
		主管未能处理  xuwujing所述的<去旅游>事情!转交给上级!
		部门经理未能处理  xuwujing所述的<去旅游>事情!转交给上级!
		总经理不同意  xuwujing所述的<去旅游>事情!

Преимущества модели цепочки ответственности:

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

Недостатки шаблона цепочки ответственности:

Это в определенной степени снизит производительность программы, а при неправильной настройке могут возникнуть циклические вызовы. Когда цепочка слишком длинная, это снижает читабельность кода и увеличивает его сложность.

используемые сцены:

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

Меры предосторожности:

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

командный режим

Введение

Шаблон команды, как следует из его названия, представляет собой шаблон проектирования, управляемый данными, который относится к поведенческому шаблону. Запрос оборачивается в объект в виде команды и передается вызывающему объекту. Вызывающий объект ищет подходящий объект, который может обработать команду, и передает команду соответствующему объекту, который ее выполняет. То есть инкапсулировать запрос в объект, чтобы можно было использовать разные запросы для параметризации клиента.

Командный режим в основном состоит из этих трех ролей: объект команды (команда), объект выполнения команды (полученный) и объект запроса команды (вызывающий).

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

Здесь мы по-прежнему используем простой пример для иллюстрации. В определенной школе учащиеся должны подчиняться приказам учителя, например, учитель может попросить учеников убрать класс, выполнить незаконченную домашнюю работу и т. д., но учащиеся имеют ограниченное время и могут выполнять определенные задания только в течение определенного времени. Во-первых, в это время два учителя только что отдали приказ ученику Сюйуцзин. Учитель Ли сначала попросил Сюйуцзин убрать класс после уроков, а учитель Ван попросил Сюйуцзин закончить незаконченную домашнюю работу и передать ее ему до идти домой. , но время контроля доступа в школу ограничено, поэтому Сюйуцзин просто убрала класс, а затем ускользнула. . . Ну, согласно этому примеру, мы можем сделать это, используя шаблон команды. Во-первых, определите класс учащихся и укажите, что этот ученик может делать. код показывает, как показано ниже:


class Student{
	void cleanClassRoom(String name){
		System.out.println(name+" 开始打扫教室...");
	}
	void doHomeWork(String name){
		System.out.println(name+" 开始做作业...");
	}
}

Затем определите абстрактный класс команды и задайте метод для выполнения.


abstract class Command{
	protected Student student;
	public Command(Student student){
		this.student = student;
	}
	abstract void execute(String name);
}

Затем определите два объекта выполнения команд и задайте команды для выполнения соответственно.


class LiTeacher extends Command{
	public LiTeacher(Student student) {
		super(student);
	}
	@Override
	void execute(String name) {
		student.cleanClassRoom(name);
	}
}

class WangTeacher extends Command{
	public WangTeacher(Student student) {
		super(student);
	}
	@Override
	void execute(String name) {
		student.doHomeWork(name);
	}
}

Наконец, определите объект запроса команды для выполнения запроса и управления командой, например добавления команды, отмены команды, выполнения команды и т. д. Тогда код следующий:


class Invoker {
	private List<Command> commands = new ArrayList<Command>();
	
	public void setCommand(Command command) {
		if(commands.size()>0) {
			System.out.println("不执行 WangTeacher 的命令!");
		}else {
			commands.add(command);
		}
	}
	
	public void executeCommand(String name) {
		commands.forEach(command->{
			command.execute(name);
		});
	}
	
	public void undoCommand(Command command) {
		commands.remove(command);
		System.out.println("撤销该命令!");
	}	
}

Наконец, давайте протестируем код. Код теста выглядит следующим образом:


public static void main(String[] args) {
		String name = "xuwujing";
		Student student = new  Student();
		Command command1 = new LiTeacher(student);
		Command command2 = new WangTeacher(student);
		Invoker invoker =new Invoker();
		invoker.setCommand(command1);
		invoker.setCommand(command2);
		invoker.executeCommand(name);
	}

Выходной результат:

不执行 WangTeacher 的命令!
xuwujing 开始打扫教室...

Преимущества командного режима:

Степень связи низкая, и запросчик и исполнитель не обязательно связаны; Хорошая расширяемость, подклассы Command могут быть очень легко расширены.

Недостатки командного режима:

Если команд слишком много, это усложнит систему.

используемые сцены:

Если есть что-то вроде命令Если вам нужно указать, вы можете использовать командный режим, например, ведение журнала, команды отмены операций и т. Д.

разное

музыкальная рекомендация

Делитесь очень легкой и легкой музыкой!

код проекта

java-study Это некоторый код, который я записал в процессе изучения Java, включая код, использованный в предыдущих сообщениях в блоге. Если самочувствие хорошее, надеюсь дать старт, конечно, если есть недостатки, тоже надеюсь поднять. адрес гитхаба:GitHub.com/Netherworld/Срочно…

Оригинал не просто, если вы чувствуете себя хорошо, я надеюсь дать рекомендацию! Ваша поддержка - самая большая мотивация для моего письма! Уведомление об авторских правах: Автор: ничтожество
Источник блога сада:www.cnblogs.com/xuwujingИсточник CSDN:blog.csdn.net/qazwsxpcm  Источник личного блога:www.panchengming.com