Есть чувства, есть галантерейные товары, поиск в WeChat【Третий принц Ао Бин] Подпишитесь на этого программиста, у которого есть кое-что.
эта статьяGitHub github.com/JavaFamilyВключено, и есть полные тестовые площадки, материалы и мой цикл статей для интервью с производителями первой линии.
Недавно в статье, в которой я делилась с вами серией шаблонов проектирования, школьница спросила меня:Командный режим, стратегический режим, заводской режимВ чем разница между ними? Вы видите разницу в реализации кода?
Я поделился этим с вами раньшережим стратегииа такжезаводской узорЗаинтересованные студенты могут просмотреть его еще раз.Сегодня мы сосредоточимся сначала на анализе.командный режимТогда давайте посмотрим, в чем разница между ними?
Прошлые отзывы:
- одноэлементный шаблон
- заводской узор
- Движок процесса
- режим строителя
- режим прототипа
- Модель цепочки ответственности
- Шаблон наблюдателя
- режим стратегии
- Метод шаблона
- шаблон итератора
- прокси-режим
- Пул объектов и режим интерпретатора
командный режим
определение
- Предоставьте унифицированный метод для инкапсуляции команд и определите, какое командное действие выбрать для выполнения с помощью условий параметров.
- Позволяет хранить каждую команду в очереди.
Общая структурная схема выглядит следующим образом:
Объяснение важных ролей на структурной схеме:
- Команда (класс команд): абстрактный класс инкапсуляции, определяющий команды.
- ConcreteCommand (конкретный класс команд): Реализуйте класс Command, который является фактическим классом реализации конкретной команды.
- Receiver: класс действия, связанный с командой выполнения.
- Invoker (вызывающий): Класс команды Trigger, т. е. события внешней операции запускают выполнение.
- Клиент (клиент): создайте конкретный объект команды и фактический класс получателя.
Вся структура на самом деле кажется довольно сложной для понимания, но, поскольку вы изучаете шаблоны проектирования, вы должны иметь представление о каждом шаблоне проектирования, чтобы улучшить свои знания.
Чтобы углубить понимание, я все же приведу хороший пример для понимания:
Каждый должен быть знаком с древней китайской монархической системой. Император может разрешить им принимать или вручать памятники тестям, которые служат под его началом. На самом деле, я лично считаю, что это может отражать командный режим.
Тесть приравнивается к приемнику командного режима, исполняет приказ императора, получает ранний придворный мемориал (ConcreteCommand) или обнародует императорский указ (ConcreteCommand)
Император эквивалентен вызывающей стороне командного режима (Invoker)
Старые правила, после завершения примера посмотрите код
// 定义 命令类
public interface Command {
// 执行的方法
void execute();
}
// 定义接收者-公公的角色
public class Receiver {
public void Charge(){
System.out.println("收取奏折");
}
public void Issue(){
System.out.println("颁布圣旨");
}
}
//具体命令类one,收取奏折命令
public class ConcreteCommandOne implements Command {
// 接受者,这里可以理解为公公
private Receiver receiver;
public ConcreteCommandOne(Receiver receiver) {
this.receiver = receiver;
}
@Override
public void execute() {
// 收取奏折
receiver.Charge();
}
}
// 具体命令类two,颁布圣旨
public class ConcreteCommandTwo implements Command {
// 接受者,这里可以理解为公公
private Receiver receiver;
public ConcreteCommandTwo(Receiver receiver) {
this.receiver = receiver;
}
@Override
public void execute() {
// 颁布圣旨
receiver.Issue();
}
}
// 调用者,皇帝
public class Invoker {
private Command command;
public Invoker(Command command) {
this.command = command;
}
// 本次需要执行的命令
public void action() {
command.execute();
}
}
// 测试demo
public static void main(String[] args) {
// 实例化一个公公 接收者
Receiver receiver =new Receiver();
// 公公 当前能有接收到的几种命令
Command commandOne = new ConcreteCommandOne(receiver);
Command commandTwo = new ConcreteCommandTwo(receiver);
// 皇帝 发号命令 触发执行方法
Invoker invoker =new Invoker(commandOne);
invoker.action();
// result: 收取奏折
Invoker invokerTwo =new Invoker(commandTwo);
invokerTwo.action();
// result:颁布圣旨
}
Вышеупомянутое является простой реализацией кода.Благодаря выбору Призывателя (императора) Получатель (тесть) может определить, какую команду выполнять. На самом деле это простое воплощение шаблона команды.
Внимательные ученики не знают, нашли ли они проблему в определении
- Позволяет хранить каждую команду в очереди.
Мы не отражаем здесь очередь, на самом деле эта реализация тоже очень проста. Просто добавьте очередь в основной метод
public static void main(String[] args) {
// 实例化一个公公 接收者
Receiver receiver = new Receiver();
// 公公 当前能有接收到的几种命令
Command commandOne = new ConcreteCommandOne(receiver);
Command commandTwo = new ConcreteCommandTwo(receiver);
// 存储命令
Queue<Command> queue = new LinkedList<>();
queue.add(commandOne);
queue.add(commandTwo);
// 批量执行
for (Command command : queue) {
Invoker invoker = new Invoker(command);
invoker.action();
}
}
Здесь я хочу сделать для вас точку расширения, которая также является методом проверки письма, который я видел раньше.
В реальной работе вы обязательно столкнетесь с большим количеством проверок интерфейса, как написать эту логику проверки, как переиспользовать и абстрагировать код и т. д. На самом деле это довольно сложная проблема!
Давайте внимательнее посмотрим на структурную схему! ! !
Я также написал для вас демонстрационный код.Следует отметить, что нам нужно реализовать метод afterPropertiesSet в ApplicationContextAware.
// 定义抽象校验方法
public abstract class ValidatePlugin {
public abstract void validate();
}
// 抽象规则执行器
public abstract class ValidatePluginExecute {
protected abstract List<ValidatePlugin> getValidatePlugins();
public void execute() {
final List<ValidatePlugin> validatePlugins = getValidatePlugins();
if (CollectionUtils.isEmpty(validatePlugins)) {
return;
}
for (ValidatePlugin validatePlugin : validatePlugins) {
// 执行校验逻辑,这里大家可以根据自己的实际业务场景改造
validatePlugin.validate();
}
}
}
// 具体测试规则
@Component("validatePluginOne")
public class ValidatePluginOne extends ValidatePlugin {
@Override
public void validate() {
System.out.println("validatePluginOne 规则校验");
}
}
// 具体执行器,把需要执行的规则添加到 validatePlugins 中
@Component("testValidatePlugin")
public class TestValidatePlugin extends ValidatePluginExecute implements ApplicationContextAware, InitializingBean {
protected ApplicationContext applicationContext;
private List<ValidatePlugin> validatePlugins;
@Override
public void afterPropertiesSet() {
// 添加规则
validatePlugins = Lists.newArrayList();
validatePlugins.add((ValidatePlugin) this.applicationContext.getBean("validatePluginOne"));
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
@Override
protected List<ValidatePlugin> getValidatePlugins() {
return this.validatePlugins;
}
}
// 测试demo
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
TestValidatePlugin testValidatePlugin = (TestValidatePlugin) applicationContext.getBean("testValidatePlugin");
testValidatePlugin.execute();
}
Это всего лишь простая тестовая демонстрация, чтобы каждый мог подумать, что шаблон проектирования не обязательно копировать код. Это больше о расширении вашего кругозора и улучшении вашей способности решать проблемы.
Для некоторых разных интерфейсов нам нужно только добавить определенные правила проверки в TestValidatePlugin, общая масштабируемость станет выше, и он будет выглядеть выше.
Так в чем же разница между упомянутым выше командным режимом, режимом стратегии и заводским режимом?
- Командный режим: он относится к режиму поведенческого дизайна.В командном режиме разные команды будут иметь разные цели и результаты в процессе выполнения, и разные команды не могут быть заменены.
- Шаблон стратегии: он принадлежит шаблону поведенческого проектирования, В шаблоне стратегии основное внимание уделяется выполнению каждой стратегии и решению проблемы выбора различных стратегий из набора стратегий в соответствии с состоянием времени выполнения.
- Фабричный режим: он относится к режиму творческого проектирования.В фабричном режиме основное внимание уделяется процессу создания инкапсуляции объектов.Здесь объекты не ограничены какими-либо бизнес-сценариями.Они могут быть стратегиями, но они также могут быть другими вещами .
То, что касается шаблонов проектирования, на самом деле я понимаю только для иллюстрации одной проблемы: разные шаблоны проектирования предназначены для работы с разными сценариями, а разные бизнес-сценарии имеют разные методы написания.
модель посредника
Посреднический режим, см. это имя, может понять, установить среднюю структуру для облегчения управления нижестоящими организациями.
Так что же такое промежуточная модель?
Объяснение в «Шаблонах проектирования» GoF: Шаблон посредничества определяет один (посреднический) объект для инкапсуляции взаимодействия между набором объектов. Делегирование взаимодействия между этим набором объектов взаимодействию с промежуточным объектом позволяет избежать прямого взаимодействия между объектами.
Давайте еще раз взглянем на эту структуру:
Медиатор (абстрактный посредник): используется для определения взаимодействия между участниками и посредниками.
ConcreteMediator: Для реализации операций, определенных посредником, то есть для реализации режима взаимодействия.
Коллега (абстрактная роль коллеги): абстрактный класс или интерфейс, в основном используемый для определения того, как взаимодействуют участники.
Бетонэколга (с ролью коллеги): Очень просто, это специфическая реализация методов в коллеге.
Вышеуказанное определение структуры происходит от красоты конструктивных узоров
Посмотрите на эту структурную схему, чтобы понять, на самом деле она такая же, как та, которую я написал для вас раньше.Шаблон наблюдателяНемного то же самое, заинтересованные студенты могут снова пойти на просмотр.
Старые правила или конкретный пример кода для реализации
Каждый в системе высокоскоростных железных дорог должен знать, что существует диспетчерский центр, который контролирует порядок въезда каждого высокоскоростного поезда.Если нет диспетчерского центра, когда три высокоскоростных в то же время, они должны общаться друг с другом. Если предположить, что один из электропоездов не сможет связаться, произойдет неизмеримая ошибка, поэтому диспетчерскому центру необходимо обработать эту логику связи и в то же время управлять тем, сколько транспортных средств в настоящее время ожидает прибытия на станцию.
// 抽象参与者, 也可以使用abstract 写法
public interface Colleague {
// 沟通消息
void message();
}
// 抽象中介者
public interface Mediator {
// 定义处理逻辑
void doEvent(Colleague colleague);
}
// 具体参与者
@Component
public class MotorCarOneColleague implements Colleague {
@Override
public void message() {
// 模拟处理业务逻辑
System.out.println("高铁一号收到消息!!!");
}
}
@Component
public class MotorCarTwoColleague implements Colleague {
@Override
public void message() {
System.out.println("高铁二号收到消息!!!");
}
}
@Component
public class MotorCarThreeColleague implements Colleague {
@Override
public void message() {
System.out.println("高铁三号收到消息!!!");
}
}
// 具体中介者
@Component
public class DispatchCenter implements Mediator {
// 管理有哪些参与者
@Autowired
private List<Colleague> colleagues;
@Override
public void doEvent(Colleague colleague) {
for(Colleague colleague1 :colleagues){
if(colleague1==colleague){
// 如果是本身高铁信息,可以处理其他的业务逻辑
// doSomeThing();
continue;
}
// 通知其他参与
colleague1.message();
}
}
}
// 测试demo
public static void main(String[] args) {
// 初始化spring容器
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:applicationContext.xml");
// 获取中介者,调度中心
DispatchCenter dispatchCenter = (DispatchCenter) applicationContext.getBean("dispatchCenter");
// 一号高铁 发送消息出去
MotorCarOneColleague motorCarOneColleague = (MotorCarOneColleague) applicationContext.getBean("motorCarOneColleague");
// 通过调度中心沟通信息
dispatchCenter.doEvent(motorCarOneColleague);
// result:高铁三号收到消息!!!
// 高铁二号收到消息!!!
// 二号高铁 发送消息出去
MotorCarTwoColleague motorCarTwoColleague = (MotorCarTwoColleague)applicationContext.getBean("motorCarTwoColleague");
dispatchCenter.doEvent(motorCarTwoColleague);
// result:高铁一号收到消息!!!
// 高铁三号收到消息!!!
}
Даже если демонстрационный код режима посредника завершен, через эту демонстрацию каждый сможет обнаружить, что посредник все еще хорошо понятен.
Тем не менее, сценарии применения посредника все еще относительно редки: для некоторых классов, которые сильно зависят и образуют сетевую структуру, они меняются на структуру, подобную структуре одуванчика, которая распространяется от середины для достижения эффект развязки.
Это более распространено в элементе управления интерфейса пользовательского интерфейса.Конечно, в Java java.util.Timer также можно понимать как режим посредника, поскольку он может контролировать, как работает внутренний поток, например, как часто он выполняется.
Упомянутые выше шаблоны посредника и наблюдателя очень похожи, и вы также можете найти это в демонстрационном коде.
В шаблоне наблюдателя наблюдатель и наблюдаемое в основном фиксированы, в то время как в шаблоне посредника наблюдатель и наблюдаемое не фиксированы, и посредник может в конечном итоге стать огромным примитивным классом.
Суммировать
Командный режим: хотя он не очень распространен, нам все же нужно различать, в чем разница между ним и заводским режимом и режимом стратегии, каков сценарий приложения и что мы можем об этом думать.
Например, в моем последнем примере командный режим может реализовать хранение команд, суть в том, чтобы поддерживать команды в очереди, так почему бы нам также не поддерживать некоторые зависимости проверки интерфейса через массив в нашем бизнес-коде, который хранит требуемый проверенный экземпляр bean-компонента. Для улучшения возможности повторного использования и масштабируемости кода.
Режим посредничества: Вообще говоря, это менее применимо. Хотя он может отделять объекты, он также имеет побочные эффекты, и мы редко сталкиваемся с такими сценариями в наших реальных бизнес-сценариях. Просто поймите принцип реализации. Что касается отличия от наблюдателей, как уже упоминалось. выше, возможно, мы уже используем некоторые очереди сообщений промежуточного слоя для их обработки.
Я Ао Бин,Чем больше вы знаете, тем больше вы не знаете, спасибо за ваши таланты:как,собиратьиКомментарий, увидимся в следующий раз!
Статья постоянно обновляется, вы можете искать в WeChat "Третий принц Ао Бин"Прочтите это в первый раз, ответьте [материал] Подготовленные мной материалы интервью и шаблоны резюме крупных заводов первой линии, эта статьяGitHub github.com/JavaFamilyОн был включен, и есть полные тестовые сайты для интервью с крупными заводами.Добро пожаловать в Star.