Поиск в WeChat【Третий принц Ао Бин] Обратите внимание на этого жадного программиста.
эта статьяGitHub github.com/JavaFamilyВключено, и есть полные тестовые площадки, материалы и мой цикл статей для интервью с производителями первой линии.
предисловие
В цикле статей о паттернах проектирования мы писали ранеезаводской узор,одноколоночный режим,режим строителя, в режиме создания, то, чем я хочу поделиться с вами сегодня, эторежим прототипа
На самом деле шаблон прототипа очень часто встречается в нашем коде, но мы легко упускаем его из виду.Так что же такое шаблон прототипа?
Режим прототипа на самом деле является методом клонирования объектов, который очень распространен в нашем программировании, например, наш часто используемыйBeanUtils.copyPropertiesявляется объектомМелкая копия, на самом деле операция инстанцирования объектов не особо затратна, поэтому для некоторых особых сценариев нам все равно нужно клонировать те объекты, которые были инстанцированы:
- Использование внешних ресурсов или аппаратно-интенсивных операций, таких как запросы к базе данных или некоторые сценарии с операциями ввода-вывода.
- Получить копию того же объекта в том же состоянии, чтобы не было необходимости повторять операцию получения состояния
Взгляните на нашу диаграмму классов:
На диаграмме выше мы видим, что шаблон прототипа на самом деле довольно прост:
- Первый — это абстрактный прототип (прототип), который объявляет метод клонирования, который может быть интерфейсом или базовым классом.В простых сценариях мы можем напрямую конкретизировать классы без базового класса.
- Во-вторых, конкретный класс-прототип (concreteprototype) реализует или расширяет метод клонирования.Когда у нас есть объектный метод в конкретном классе-прототипе, он возвращает абстрактный объект-прототип базового класса.
Учитывая вышеизложенное теоретическое знание, приведем реальный пример!
Пример
Допустим, у нас сейчас такой сценарий, что компания проводит мероприятие и в мероприятии участвует 50 000 товаров.Нам нужно иметь возможность регулярно синхронизировать продажи каждого товара из фона, чтобы мы могли делать анализ товара для последующих событий.Как Имеем ли мы дело с этой проблемой синхронизации продаж?
Во-первых, данные о продажах и запасах являются здесь горячими данными, но они должны быть изолированы друг от друга, потому что запасы требуют высокой производительности в режиме реального времени, а продажи могут иметь короткую задержку, при условии, что данные могут быть гарантированно достоверными. в конечном итоге согласовано, поэтому размещайте заказ. В то же время мы можем обновлять продажи товаров в нашей базе данных в соответствии с MQ.
Когда мы идем проверять продажи, мы не можем каждый раз проверять БД, поэтому мы можем обрабатывать ее через кеш Redis, а время обновления нашего текущего запроса записываем в кеш.
При повторном запросе время обновления в данных Redis используется в качестве условия запроса для запроса времени обновления в БД, которое больше, чем время записи в нашем текущем Redis, что уменьшает количество строк в сканировании таблицы SQL (т. обновленные данные сравниваются с полным объемом данных) , объем обновленных данных по-прежнему составляет меньшинство)
Основываясь на описанном выше процессе, мы начали писать демо
В этой демонстрации мы сначала создаем класс ItemSold и класс SkuSold, в то время как ItemSold переопределяет метод клонирования в Cloneable. Затем в последнем методе тестового класса я вызываю метод clone, чтобы скопировать новый класс продаж продуктов.
Внимательные студенты не знают, нашли ли они проблему при просмотре результатов? Внутри цикла for я распечатываю адреса памяти объектов ItemSold и SkuSold соответственно.
Адрес памяти скопированного SkuSold фактически совпадает с адресом прототипа.Такой же, копия ItemSold совпадает с адресом прототипаРазныеНу вот мы и поговорим об этом вопросережим прототипадве реализациимелкая копияиглубокая копия.
Здесь мы объясняем, что мы делаем преобразование данных в цикле for.Вообще говоря, мы не обращаемся к базовой модели, чтобы вернуть модель результата.Нам нужно сделать слой преобразования для достижения эффекта антикоррозии. Чтобы отразить глубокую и поверхностную копию, написать относительно просто, и вам все равно нужно сделать это самостоятельно в соответствии с реальной ситуацией.
Мелкие и глубокие копии
Поверхностное копирование: если скопированный объект содержит только простые типы данных, такие как int, float или неизменяемые объекты (строки), эти поля копируются непосредственно в новый объект. Ссылочный объект не копируется, но адрес ссылочного объекта копируется в клонированный объект
Глубокая копия: независимо от простого типа данных или типа ссылочного объекта в скопированном объекте, в новый объект будет сделана полная копия.
Например, это как два брата, которые могут купить одежду каждому человеку, а потом дом и все живут в доме (мелкая копия).
Прочитав эту картинку, все поймут, что демо выше — поверхностная копия, так что же нам делать, чтобы добиться глубокой копии?
Во-первых, давайте посмотрим, что предоставляет Java.Cloneableинтерфейс
Глядя на приведенное выше объяснение интерфейса, его можно примерно понять как:
Класс реализует интерфейс Cloneable для реализации метода клонирования этого класса, чтобы экземпляр класса мог быть законно скопирован по полю.Если метод clone() объекта вызывается для экземпляра этого класса, который не реализует Cloneable интерфейс, это вызовет исключение CloneNotSupporteddException.
Итак, как мы реализуем глубокую копию здесь?
Первый: при переопределении метода клонирования в ItemSold сделайте копию для SkuSold (поскольку мы здесь только для того, чтобы получить неглубокую копию объекта List, а затем пройти через неглубокую копию объекта List, а затем вызвать метод клонирования эталонного объекта. реализовать глубокую копию)
Здесь, если есть несколько уровней ссылочных объектов, мы можем рассмотреть возможность реализации рекурсии, но код будет выглядеть намного сложнее.
Второй: записать объект в поток сериализацией и потом вынуть из потока
Вышеупомянутые два метода записи на самом деле достижимы, но независимо от того, какой метод используется, глубокое копирование занимает больше времени и места, чем поверхностное копирование, поэтому его следует рассматривать как целесообразное. На самом деле уже существует множество инструментов для мелкого и глубокого копирования.
- Глубокая копия: SerializationUtils
- Мелкая копия: BeanUtils
считать
Для приведенных выше бизнес-сценариев мы также можем подсчитывать продажи товаров другими способами.Мы можем использовать MQ для увеличения продаж, а затем обновлять кеш Redis, но нам нужно обратить внимание на некоторые основные бизнес-данные и неосновные бизнес-данные. насколько это возможно. Не делитесь группой потребителей, чтобы не повлиять на скорость потребления основных данных. При этом мы больше думаем о преимуществах и недостатках этого при проектировании и стоимости разработки.
На самом деле, мы можем использовать режим прототипа и в других местах, например, в PUSH-уведомлении о нашей активности, когда мы рассылаем уведомления миллионам, десяткам миллионов или даже сотням миллионов пользователей на платформе, содержимое уведомления в основном то же самое, просто нажмите на пользователя.Если это не то же самое или есть небольшие изменения в значениях специальных полей, то мы можем использовать режим прототипа, чтобы сделать это здесь, и открыть несколько потоков, чтобы сделать push на Следует отметить, что здесь есть проблемы с безопасностью потоков, поэтому копируйте объекты внутри каждого потока.
Суммировать
Режим прототипа прост в использовании, но каждый раз, когда мы клонируем базовый класс или имеем ссылочный объект, нам нужно модифицировать метод клонирования объекта-прототипа, что не соответствует нашему принципу открытости-закрытости.
В обычных условиях не рекомендуется использовать этот режим, если только стоимость создания объектов не особенно велика, или он используется в каких-то особых сценариях.Наконец, я не буду подробно рассказывать вам о некоторых режимах, которые обычно не используются, но Я поделюсь ею позже, а подытоживая, я поделюсь с вами поведенческой моделью позже.
Я Ао Бин,Чем больше вы знаете, тем больше вы не знаете, спасибо за ваши таланты:как,собиратьиКомментарий, увидимся в следующий раз!
Статья постоянно обновляется, вы можете искать в WeChat "Третий принц Ао Бин"Прочтите это в первый раз, ответьте [материал] Подготовленные мной материалы интервью и шаблоны резюме крупных заводов первой линии, эта статьяGitHub github.com/JavaFamilyОн был включен, и есть полные тестовые сайты для интервью с крупными заводами.Добро пожаловать в Star.