«Это четвертый день моего участия в первом испытании обновлений 2022 года. Подробную информацию о мероприятии см.:Вызов первого обновления 2022 г."
предисловие
Всем привет, я Кано, инженер полного стика, стремящийся стать полноценным!
Первые три главы описывают Lambda в виде теории + кейса, который должен в основном решить проблемы Lambda, с которыми каждый сталкивается в ежедневной разработке.Чтобы лучше продемонстрировать прелесть Lambda и углубить и закрепить точки знаний Lambda, сегодня мы обсудим как Lambda выполняет рефакторинг шаблонов проектирования!
О шаблонах проектирования
Как мы все знаем, шаблон проектирования — это схема, в которой группа крупных программистов обобщает опыт программирования. Это не спецификация синтаксиса, а набор решений для улучшения повторного использования кода, удобства сопровождения, удобочитаемости, надежности и безопасности.
В этой статье не будет слишком много объяснений о шаблонах проектирования.По умолчанию каждый имеет определенное представление о шаблонах проектирования (позже я объясню все шаблоны проектирования отдельно).
Шаблон проектирования лямбда-рефакторинга
Далее я перечислю несколько часто используемых шаблонов проектирования.Сравнивая традиционные и лямбда-формы, пусть каждый почувствует различные шаблоны проектирования лямбда-версии!
Простой заводской шаблон
Поскольку внутренние методы часто определяются как статические, шаблон простого фабричного метода также называют шаблоном статического фабричного метода.заводской объектЭкземпляр класса продукта создается по типу, требуемому клиентом.Простой фабричный паттерн является самым простым и практичным паттерном в семействе фабричных паттернов.Его можно понимать как специальную реализацию различных фабричных паттернов.
Кейс: Фруктовая фабрика
Содержит апельсины, бананы, яблоки
- традиционное письмо
/**
* 简单工厂
* @author : uu
* @version : v1.0
* @Date 2022/1/20
*/
public class FruitFactory {
public static Fruit getFruit(String fruitName) {
Fruit fruit = null;
switch (fruitName) {
case "Banana":
fruit = new Banana();
break;
case "Apple":
fruit = new Apple();
break;
}
return fruit;
}
}
Суть фабричного паттерна в том, чтобы вернуть объект при его вызове.Вспомним внимательно, во встроенном функциональном интерфейсе JavaSupplierКажется, он это делает, так что давайте просто перепишем это, не говоря много.
- лямбда письмо
/**
* Lambda形式工厂模式
* @author : uu
* @version : v1.0
* @Date 2022/1/20
*/
public class FruitLambdaFactory {
/**
* 初始化工厂数据
*/
private static Map<String, Supplier<Fruit>> FRUIT_FACTORY = new HashMap<String, Supplier<Fruit>>(){{
put("Banana", Banana::new);
put("Apple", Apple::new);
}};
public static Fruit getLambdaFruit(String fruit) {
Supplier<Fruit> fruitSupplier = FRUIT_FACTORY.get(fruit);
return Objects.nonNull(fruitSupplier) ? fruitSupplier.get() : null;
}
}
Не по теме:На самом деле в приведенном выше способе написания есть недостатки: например, чтобы добавить новую категорию фруктов, необходимо изменить статический метод фабрики, что нарушает принцип открытого-закрытого, и легко вызвать проблемы с орфографией, передавая в форме строки.В реальном бизнесе мы можем использовать отражение для решения этой проблемы.
- отражение письмо
/**
* 反射形式的工厂模式
*
* @author : uu
* @version : v1.0
* @Date 2022/1/20
*/
public class FruitReflectFactory {
public static <T extends Fruit> T getLambdaFruit(Class<T> fruitCls) {
try {
return fruitCls.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
}
режим стратегии
Шаблон стратегии состоит в том, чтобы инкапсулировать ряд алгоритмов, чтобы эти алгоритмы можно было заменить друг другом во время выполнения, что может решить проблему чрезмерного использования.
if...else if...else
Эта проблема!
Случай: Несколько каналов для отправки информации
Включить: почтовый канал, канал веб-сокета
- традиционный режим
/**
* 发送通道策略
* @author : uu
* @version : v1.0
* @Date 2022/1/20 20:18
*/
public interface SendChannelStrategy {
/**
* 发送接口
* @param msg
*/
void send(String msg);
}
/**
* 邮箱策略
* @author : uu
* @version : v1.0
* @Date 2022/1/20 20:19
*/
public class EmailChannelStrategy implements SendChannelStrategy{
@Override
public void send(String msg) {
System.out.println("使用email发送:" + msg);
}
}
/**
* websocket策略
* @author : uu
* @version : v1.0
* @Date 2022/1/20 20:19
*/
public class WebSocketChannelStrategy implements SendChannelStrategy{
@Override
public void send(String msg) {
System.out.println("使用websocket发送:" + msg);
}
}
/**
* 消息服务,使用发送策略
* @author : uu
* @version : v1.0
* @Date 2022/1/20
*/
@AllArgsConstructor
@Getter@Setter
public class SendService {
private SendChannelStrategy sendChannelStrategy;
public void send(String msg) {
sendChannelStrategy.send(msg);
}
}
// 使用方式如下
public void test(){
SendService sendService = new SendService(new EmailChannelStrategy());
sendService.send("卡诺"); // 使用email发送:卡诺
sendService.setSendChannelStrategy(new WebSocketChannelStrategy());
sendService.send("卡诺"); // 使用websocket发送:卡诺
}
Здесь мы можем обнаружить, что приведенный выше интерфейс режима стратегии на самом деле является функциональным интерфейсом (есть только один абстрактный метод).Метод имеет один входной параметр и не имеет возвращаемого значения.Вы сразу подумали о встроенном функциональном интерфейсе Java?Consumer
Шерстяная ткань? Давайте посмотрим, как Lambda справляется с этим!
- лямбда письмо
public void testLambda(){
SendService sendService = new SendService(msg -> System.out.println("使用lambda email发送:" + msg));
sendService.send("卡诺"); // 使用email发送:卡诺
sendService.setSendChannelStrategy(msg -> System.out.println("使用websocket发送:" + msg));
sendService.send("卡诺"); // 使用websocket发送:卡诺
}
Код соответствует ожиданиям, используйтеConsumer
Чтобы заменить, мы можем сразу опуститьEmailChannelStrategy
а такжеWebSocketChannelStrategy
определение класса!
Шаблон метода шаблона
Шаблон метода шаблона означает, что родительский класс определяет процесс и позволяет подклассу реализовать один или несколько шагов в процессе. Таким образом, подклассы могут реализовывать свои персонализированные операции без изменения общего процесса.
Кейс: процесс игры
Выберите игровое положение для игры (лежа/сидя), начните игру, завершите игру
- традиционное письмо
/**
* 游戏
* @author : uu
* @version : v1.0
* @Date 2022/1/20 20:49
*/
public abstract class Game {
public void play(String posture) {
selectPlayPosture(posture);
System.out.println("开始游戏");
System.out.println("结束游戏");
}
/**
* 选择游戏姿势
*/
public abstract void selectPlayPosture(String posture);
}
/**
* 躺着玩
* @author : uu
* @version : v1.0
* @Date 2022/1/20 20:53
*/
public class LieGame extends Game{
@Override
public void selectPlayPosture(String posture) {
System.out.println("沙发上:" + posture);
}
}
/**
* 坐着玩
* @author : uu
* @version : v1.0
* @Date 2022/1/20 20:52
*/
public class SitGame extends Game{
@Override
public void selectPlayPosture(String posture) {
System.out.println("板凳上:" + posture);
}
}
// 测试
public void test(){
Game game = new LieGame();
game.play("躺着");
game = new SitGame();
game.play("坐着");
}
С помощью приведенного выше кода мы можем обнаружить, что абстрактный интерфейс, который должен быть реализован подклассами в шаблоне шаблона,Абстрактный метод без возвращаемого значения, встроенный функциональный интерфейс JavaConsumer
Точно сопоставив его, мы можем передать методы, которые должны быть реализованы подклассамиConsumer
Извлечение параметров по ходу игры может значительно сократить код следующим образом:
- лямбда письмо
/**
* Lambda形式的模版方法
* @author : uu
* @version : v1.0
* @Date 2022/1/20 20:49
*/
public class LambdaGame {
public void play(String posture, Consumer<String> consumer) {
consumer.accept(posture);
System.out.println("开始游戏");
System.out.println("结束游戏");
}
}
// 使用方式
public void testLambda(){
LambdaGame game = new LambdaGame();
game.play("躺着", System.out::println);
game.play("坐着", System.out::println);
}
Переписывание через Lambda выглядит намного проще?
исходный код
Суммировать
-
В этой главе показано удобство, привнесенное Lambda в написание кода в форме использования Lambda для рефакторинга шаблона проектирования;
-
На этот раз перечислены только несколько наиболее часто используемых переписываний шаблонов проектирования.Если вам интересно, вы можете вместе обсудить переписывания других шаблонов;
-
Код в этом случае относительно прост, и фактическая разработка все равно должна опираться на потребности бизнеса и не может быть слепо кратким в угоду краткости.
Статьи по Теме
наконец
-
Спасибо за терпение, чтобы посмотреть конец, если вы найдете эту статью полезной, пожалуйста, дайте мне сообщениеНравится👍илиПодписаться ➕;
-
В связи с моей ограниченностью в технологиях, в статье и коде могут быть ошибки, надеюсь вы прокомментируете и укажете на это, большое спасибо🙏;
-
В то же время вы также можете вместе обсудить изучение интерфейса и знаний Java и вместе добиться прогресса.