Режим стратегии оказался таким простым!

Шаблоны проектирования

предисловие

Только лысина может стать сильнее

Оглядываясь назад на фронт:

Будь то собеседование или личное совершенствование, шаблоны проектирования необходимо изучить. Давайте объясним сегодняСтратегиярежим~

1. Введение в режим стратегии

Впервые я услышал термин «шаблон стратегии», когда впервые изучал JDBC. Я не знаю, использовали ли вы компонент DBUtils. В то время, когда я был новичком, я следил за обучением по видео.Г-н Фанг Лисюнь сначала попросил нас инкапсулировать некоторые общие операции JDBC (на самом деле это имитация компонента DBUtils).

Проблема в то время заключалась в следующем: мы собирались инкапсулироватьquery()Метод запроса, переданные параметры:String sql , Object[] objects(Укажите оператор SQL и соответствующие параметры). мы хотим основатьдругой бизнесвозвращает другое значение.

  • Например, иногда мы возвращаем часть данных, а затем хотим инкапсулировать эти данные в объект Bean.
  • Например, иногда мы возвращаем несколько фрагментов данных, а затем хотим инкапсулировать эти фрагменты данных в один.List<Bean>собирать
  • Например, иногда мы возвращаем данные xxxx, а затем хотим инкапсулировать эти несколько фрагментов данных в один.Map<Bean>собирать
  • ........подожди подожди подожди

Решение на тот момент было такое:

  • Сначала определите интерфейс: ResultSetHandler(Что вызывающая сторона хочет сделать с результирующим набором, просто реализуйте этот интерфейс)
    • Этот интерфейс определяет поведение.Object hanlder(ResultSet resultSet);
  • Затем реализуем вышеуказанный интерфейс, например, мы хотим инкапсулировать его в объект Bean, то естьpublic class BeanHandler implements ResultSetHandler
  • При вызове на самом делеquery()Метод запроса с еще одним параметромquery(String sql, Object[] objects, ResultSetHandler rsh). Какой тип хочет вернуть вызывающий объект, просто передайте соответствующий класс реализации ResultSetHandler.

код показывает, как показано ниже:


	query方法:

    //这个方法的返回值是任意类型的,所以定义为Object。
    public static Object query(String sql, Object[] objects, ResultSetHandler rsh) {

        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;

        try {
            connection = getConnection();
            preparedStatement = connection.prepareStatement(sql);

            //根据传递进来的参数,设置SQL占位符的值
            if (objects != null) {
                for (int i = 0; i < objects.length; i++) {
                    preparedStatement.setObject(i + 1, objects[i]);
                }
            }


            resultSet = preparedStatement.executeQuery();

            //调用调用者传递进来实现类的方法,对结果集进行操作
            return rsh.hanlder(resultSet);
    }

	接口:

	/*
    * 定义对结果集操作的接口,调用者想要对结果集进行什么操作,只要实现这个接口即可
    * */
    public interface ResultSetHandler {
         Object hanlder(ResultSet resultSet);
    
    }

	接口实现类(Example):

	//接口实现类,对结果集封装成一个Bean对象
	public class BeanHandler implements ResultSetHandler {
	
	
	    //要封装成一个Bean对象,首先要知道Bean是什么,这个也是调用者传递进来的。
	    private Class clazz;
	
	    public BeanHandler(Class clazz) {
	        this.clazz = clazz;
	    }
	
	    @Override
	    public Object hanlder(ResultSet resultSet) {
	
	        try {
	
	            //创建传进对象的实例化
	            Object bean = clazz.newInstance();
	
	            if (resultSet.next()) {
	
	                //拿到结果集元数据
	                ResultSetMetaData resultSetMetaData = resultSet.getMetaData();
	
	                for (int i = 0; i < resultSetMetaData.getColumnCount(); i++) {
	
	                    //获取到每列的列名
	                    String columnName = resultSetMetaData.getColumnName(i+1);
	
	                    //获取到每列的数据
	                    String columnData = resultSet.getString(i+1);
	
	                    //设置Bean属性
	                    Field field = clazz.getDeclaredField(columnName);
	                    field.setAccessible(true);
	                    field.set(bean,columnData);
	                }
	
	                //返回Bean对象
	                return bean;
	            }

Это шаблон стратегии? ? Вот и все? ? Разве это не использование полиморфизма? ?

1.1 Объяснение режима стратегии

Дзен шаблонов проектирования:

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

Диаграмма классов шаблона стратегии выглядит следующим образом:

策略模式通用类图

Интерфейс и конкретная реализация стратегии должны быть хорошо понятны:

  • Интерфейс стратегии аналогичен упомянутому выше интерфейсу ResultSetHandler (который определяет поведение стратегии).
  • Конкретная реализация эквивалентна реализации BeanHandler, о которой мы упоминали выше (конкретная реализация интерфейса).
    • Обычно существует несколько конкретных реализаций, таких как ListBeanHandler, MapBeanHandler и т. д.

Что может сбивать с толку, так это то, что существует другой шаблон стратегии.Объект контекста контекста. Для чего используется этот объект?

Дзен шаблонов проектирования:

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

Аналогичный вопрос есть и на Zhihu (почему бы не назвать напрямую, а передать Person?):

知乎问题

Грубо говоря, вызовите его через Personболее объектно-ориентированный(блокирует прямой доступ к конкретной реализации).

Прежде всего, мы должны понять истину, а именно - это "народный" туризм или поезда, автомобили, велосипеды и самолеты?

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

Конкретные ссылки:

Итак, давайте вернемся к приведенной выше общей диаграмме классов, мы можем посмотреть на нее так:

DBUtils策略模式类图

1.2 Примеры паттернов стратегии

Теперь у 3y есть общедоступная учетная запись Java3y. 3y хочет, чтобы больше людей узнали об общедоступной учетной записи Java3y. Так что каждый день я думаю о том, как увеличить число своих поклонников (хахах

Итак, 3y начал придумывать способ (убитый горем), и в то же время 3y узнал за этот период времениЕсть много способов вырастить. Для удобства определите общий интерфейс для облегчения управления и использования.

интерфейс:


/**
 * 增加粉丝策略的接口(Strategy)
 */
interface IncreaseFansStrategy {

    void action();
}

Конкретные меры по увеличению числа вентиляторов, например, поручить военно-морскому флоту:


/**
 * 请水军(ConcreteStrategy)
 */
public class WaterArmy implements IncreaseFansStrategy {
    
    @Override
    public void action() {
        System.out.println("3y牛逼,我要给你点赞、转发、加鸡腿!");
    }
}

Конкретные меры по увеличению числа поклонников, например, серьёзно пишут оригиналы:


/**
 * 认真写原创(ConcreteStrategy)
 */
public class OriginalArticle implements IncreaseFansStrategy{

    @Override
    public void action() {
        System.out.println("3y认真写原创,最新一篇文章:《策略模式,就这?》");

    }
}

3y также думал о многих способах увеличить количество поклонников, таких как раздача книг, продвижение бизнеса и т. д. (я не буду вдаваться в подробности здесь)

В конечном счете, каким бы ни был метод поднятия веера, он осуществляется через 3 года.


/**
 * 3y(Context)
 */
public class Java3y {

    private IncreaseFansStrategy strategy ;

    public Java3y(IncreaseFansStrategy strategy) {
        this.strategy = strategy;
    }

    // 3y要发文章了(买水军了、送书了、写知乎引流了...)。
    // 具体执行哪个,看3y选哪个
    public void exec() {
        strategy.action();
    }
}

Итак, когда пришло время твитнуть, 3y может выбрать, каким образом получить подписчиков:

public class Main {

    public static void main(String[] args) {

        // 今天2018年12月24日
        Java3y java3y = new Java3y(new WaterArmy());
        java3y.exec();

        // 明天2018年12月25日
        Java3y java4y = new Java3y(new OriginalArticle());
        java4y.exec();
        
        // ......
    }
}

Результаты:

执行结果

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

преимущество:

  • Алгоритмы можно свободно переключать
    • Легко изменить свою стратегию
  • Хорошая масштабируемость
    • Чтобы добавить стратегию, просто добавьте еще один класс.

недостаток:

  • Увеличено количество классов стратегий
    • Каждая стратегия представляет собой класс, возможность повторного использования мала, а количество классов увеличивается
  • Все классы политик должны быть доступны извне.
    • Модуль верхнего уровня должен знать, какие политики доступны, а затем решить, какую стратегию использовать

调用方必须要知道有哪些策略

1.4 Приложение режима стратегии JDK

Я не знаю, можете ли вы все еще думать о ThreadPoolExecutor (пул потоков):Вы действительно хотите знать о пуле потоков?

Чтобы изучить ThreadPoolExecutor (пул потоков), вы должны знать значение каждого параметра его конструктора:


    /**
     * Handler called when saturated or shutdown in execute.
     */
    private volatile RejectedExecutionHandler handler;

	public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler) {
        //....
        this.handler = handler;
    }

    /**
     * Invokes the rejected execution handler for the given command.
     * Package-protected for use by ScheduledThreadPoolExecutor.
     */
    final void reject(Runnable command) {
        handler.rejectedExecution(command, this);
    }

Среди них мы можем найти RejectedExecutionHandler, который представляет стратегию отклонения (существует четыре конкретных реализации: прямое генерирование исключения, использование потока вызывающей стороны для обработки, непосредственное удаление задачи, удаление самой старой задачи)

По сути, это воплощение модели стратегии.

Наконец

Считаете ли вы режим стратегии очень простым после прочтения? Просто оберните его интерфейсом алгоритма, несколькими реализациями алгоритма и контекстом, и все готово.

Рекомендуемое чтение и ссылки:

С удовольствием делюсь и экспортируюгалантерейные товарыОбщедоступный номер технологии Java: Java3y.

帅的人都关注了

статьиНавигация по каталогу: