你TM敢信,小面竟然用java制作酸菜鱼,还跟我扯设计模式

简介: 你TM敢信,小面竟然用java制作酸菜鱼,还跟我扯设计模式

引言

今天我将以制作酸菜鱼谈谈java抽象思想和处理问题的思路,一方面分享酸菜鱼的制作步骤,另外一方面结合过程谈谈我联想到的设计模式和一些思想,随着编程经验的增加,再加上自己喜欢制作一些美食,越来越觉得编程思想都是来源于生活,抽象于生活,如果觉得可以请帮忙点赞、收藏、转发

我们先来看下整体流程:

整个制作过程真的简单,作为程序员的我们如果不知道吃什么,可以亲手实践下这道菜,接下我将详细叙述制作过程

一. 买鱼

1.选鱼

就近选择可靠的店,1人到2人建议选择2斤左右的,酸菜鱼制作我选择的是花鲢鱼,个人可根据口味和爱好选择喜欢的鱼,3人到5人建议选择3斤到4斤重的,我今天选择的是一般重的正好3斤,5人吃,还有其他菜,只吃鱼5人建议可以整2条3斤重的或者6斤重的,一般这种店都会售卖煮鱼调料,可以直接选择酸菜鱼调料,烹饪步骤也可按调料包说明进行操作,一般做出来味道都不错的,我这里直接选用的是酸菜包,也就3元一袋约200g酸菜

2.杀鱼

如果自身动手能力强,可以选择自己回家杀鱼并完成后面打整步骤,这里我们一般都是直接交给摊贩打理,摊贩将鱼拍晕,打鳞,破肚,清理内脏,清理鱼鳃,分解鱼头、鱼骨,切鱼片,打包装袋,我要求的是切片,摊贩会将带骨的和鱼片分开装袋,这个过程就是大家常谈的代理模式,我们将此项工作完全交给摊贩,在编程中我们也需要使用代理模式来完成某些需要的工作,接下来就摊贩帮我们处理鱼实现一下代理模式

定义接口,处理鱼

public interface HandleFish {
    /**
     * 处理鱼
     * @param fish
     */
    void handleFish(String fish);
}

真实处理鱼的摊贩处理

@Service
public class RealPersonHandleFish implements HandleFish{
    /**
     * 处理鱼
     *
     * @param fish
     */
    @Override
    public void handleFish(String fish) {
        System.out.println("我是摊贩,开始处理:" + fish);
    }
}

自己处理鱼

@Service
public class MySelfHandleFist implements HandleFish {
    private  RealPersonHandleFish realPersonHandleFish;
    /**
     * 处理鱼
     *
     * @param fish
     */
    @Override
    public void handleFish(String fish) {
        if (realPersonHandleFish == null) {
            realPersonHandleFish = new RealPersonHandleFish();
        }
        System.out.println("开始处理:");
        //调用其他类进行处理
        realPersonHandleFish.handleFish(fish);
    }
}

开始处理鱼

public class ProxyPatternDemo {
    public static void main(String[] args) {
        HandleFish handleFish = new MySelfHandleFist();
        handleFish.handleFish("鱼");
    }
}

执行结果

开始处理:
我是摊贩,开始处理:鱼
Process finished with exit code 0

代理模式意图:为其他的对象提供一种代理,从而控制对这个对象的访问

代理模式主要解决:直接访问对象时带来的影响,比如说:要访问的对象在远程的机器上。

代理模式何时使用:访问一个类时,我们需要做一些控制的时候,不直接访问这个类,通过它的代理类进行访问。

代理模式如何解决:增加中间代理层。

代理模式关键代码:实现与被代理类组合,和被代理类具有同样的功能。

二. 清洗整理鱼肉,备好需要调料

1.清理鱼肉

尽管摊贩已经清洗过鱼肉,但可能有的摊贩打扫的不是那么令人满意,回家后务必自己重新清理干净,特别是鱼鳃(这个东西吃着是苦的,别问我怎么知道的),清理后将带骨的和鱼片分开装盆滤干水分,准备腌制

2.调料准备

今天煮酸菜鱼用到的调料基本上大家家里都有,具体可看上图调料工厂说明,胡椒粉建议家里可以备一瓶,买最小规格的,没有就不用,猪油能增加层次感,没有也可不用,还有就是去腥的料酒,少做饭的买个小规格的就好,大葱一般都可以不用,烹饪荤菜都少不了料酒,然后就是平常必备的那些了不一一赘述,其实我们所使用的调料,抽象一下就像我们平常使用的java基本数据类型以及集合类,每一样都会在我们的代码中使用,必不可少。注意1:生姜两用

  • 切片 > 腌制时使用,给鱼肉去腥
  • 直接拍(不用很细,只是把姜拍破) > 爆香烧汤,增加烫的味道

注意2:酸菜包,打开后用清水清洗1到2遍,挤干水分,然后切成大块

然后用锅开中火直接炒制酸菜,将多余的水分炒干后装盘备用,这样做的目的是为了炒制时能更加的激发酸菜的酸味和香味,怎么判断炒干  > 锅边无明显水分,炒制时无多余的水蒸气冒出

注意3:做啥菜都可以放点小葱,香菜根据个人口味放或不放

注意4:我这里没有选用现成的鱼调料,直接用少许火锅料(味道稍稍带点甜味,不辣),火锅料可根据个人口味选择,能吃辣的可以选择辣味重的,量大概就100g到300g足够了,直接用鱼调料包的按照说明操作即可

注意5:我使用了少量嫩肉粉,主要目的是适度增加鱼肉的爽滑口感,没有可以不用或者用少量淀粉替代

三. 腌制

鱼头鱼骨和鱼片分别用不同的容器腌制,腌制方法一致,腌制方法:放入适量的盐(不会就少一点少一点的慢慢增加,拌匀后直接尝,带有咸味稍重即可),盐是鱼肉入味的关键,盐少了烹饪出来的味道可能会很淡以至不好吃,然后放入少许胡椒粉,鸡精,料酒,嫩肉粉,姜片搅拌均匀,腌制时间不小于20分钟

四. 炒制汤料

  1. 放入食用油(我这里放的猪油和菜籽油)烧热
  2. 加入姜蒜(拍碎)大葱小火炒香
  3. 放入炒干的酸菜并加入少许食盐大火炒制20s到40s
  4. 加入火锅料,多一点花椒粒中火炒制30s左右
  5. 加入适量清水,淹没过鱼最好

五. 分时分段下入鱼肉

微信图片_2022080616250614.jpg

  1. 水烧开后中火煮1分钟然后先下入鱼头
  2. 过30s后下入带鱼骨的其他部分
  3. 煮2分钟后下入鱼片,让鱼片被烫淹没,再煮1分钟后捞出

六. 点缀装饰

出锅装盘后放上葱段和香菜

一份简单的酸菜鱼就制作完成,其实这个过程按照顺序一步一步操作就像是职责链模式

责任链模式

责任链模式(Chain of Responsibility Pattern),属于行为型模式,为请求创建了一个接收者对象的一条链。这种设计模式给予了请求的类型,对请求的发送端和接收端进行解耦操作。

在这种设计模式中,一般说来每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传递给下一个接收者,依此类推,知道这条链走完。

意图

避免请求发送者与接收者强耦合在一起,让多个对象都有可能接收到请求,且将这些对象连接成一条链,沿着这条链持续传递请求,直到有对象处理它为止。

主要解决

职责链上的每一个处理者负责处理请求,上游只需要将请求发送到职责链上即可,不用关心请求的处理细节和请求的传递,所以职责链将请求的发送者和请求的处理者解耦了。

何时使用

在处理消息的时候以过滤很多道,比如权限校验的各个环节,参数,合法性校验等等。

如何解决

拦截的类都实现统一接口。

关键代码

Handler 里面聚合它自己,在 HandlerRequest 里判断是否合适,如果没达到条件则向下传递,向谁传递之前 set 进去。

使用场景

1、有多个对象可以处理同一个请求,具体哪个对象处理该请求由运行时刻自动确定。

2、在不明确指定接收者的情况下,向多个对象中的一个提交一个请求。

3、可动态指定一组对象处理请求。

简单实现

我们创建抽象类 AbstractCookingFish,带有详细制作酸菜鱼步骤。然后我们创建六个顺序的处理类,都扩展了 AbstractCookingFish。每个处理类的级别是否属于自己的级别,如果是则相应地打印出来,否则将不打印并把消息传给下一个处理类。

责任链模式的 UML 图

步骤 1

创建抽象的鱼处理类。

public abstract class AbstractCookingFish {
    public static final int FIRST = 1;
    public static final int SECOND = 2;
    public static final int THIRD = 3;
    public static final int FOURTH = 4;
    public static final int FIFTH = 5;
    public static final int SIXTH = 6;
    protected int level;
    protected AbstractCookingFish nextCookingFish;
    public void setNextCookingFish(AbstractCookingFish nextCookingFish){
        this.nextCookingFish = nextCookingFish;
    }
    public void cookingFish(int level,String message){
        if(this.level == level){ cooke(message);
        }
        if(nextCookingFish !=null){
            nextCookingFish.cookingFish(level, message);
        }
    }
    abstract protected void cooke(String message);
}

步骤 2

创建扩展了该鱼处理类的实体类。

public class BuyFish extends AbstractCookingFish {
    public BuyFish(int level){
        this.level = level;
    }
    @Override
    protected void cooke(String message) {
        System.out.println("BuyFish:买鱼步骤--" + message);
    }
}
public class CleanFish extends AbstractCookingFish {
    public CleanFish(int level){
        this.level = level;
    }
    @Override
    protected void cooke(String message) {
        System.out.println("CleanFish:清理鱼,准备调料步骤--" + message);
    }
}
public class PickleFish extends AbstractCookingFish {
       public PickleFish(int level){
           this.level = level;
       }
       @Override
       protected void cooke(String message) {
           System.out.println("PickleFish:腌制鱼步骤--" + message);
       }
   }
public class CookedSoupFish extends AbstractCookingFish {
    public CookedSoupFish(int level){
        this.level = level;
    }
    @Override
    protected void cooke(String message) {
        System.out.println("CookedSoupFish:炒制汤料步骤--" + message);
    }
}
public class AddFish extends AbstractCookingFish {
    public AddFish(int level){
        this.level = level;
    }
    @Override
    protected void cooke(String message) {
        System.out.println("AddFish:分时段加入鱼骨鱼肉步骤--" + message);
    }
}
public class DecorateFish extends AbstractCookingFish {
    public DecorateFish(int level){
        this.level = level;
    }
    @Override
    protected void cooke(String message) {
        System.out.println("最后一步DecorateFish:点缀装饰步骤--" + message);
    }
}

步骤 3

创建不同类型的处理实现类。赋予它们不同的顺序,并在每个处理类中设置下一个处理类。每个处理类的下一个处理类代表的是链的一部分。

public class CookingFishDemo {
    private static AbstractCookingFish getCookingFish(){
        AbstractCookingFish buyFish = new BuyFish(AbstractCookingFish.FIRST);
        AbstractCookingFish cleanFish = new CleanFish(AbstractCookingFish.SECOND);
        AbstractCookingFish pickleFish = new PickleFish(AbstractCookingFish.THIRD);
        AbstractCookingFish cookedSoupFish = new CookedSoupFish(AbstractCookingFish.FOURTH);
        AbstractCookingFish addFish = new AddFish(AbstractCookingFish.FIFTH);
        AbstractCookingFish decorateFish = new DecorateFish(AbstractCookingFish.SIXTH);
        buyFish.setNextCookingFish(cleanFish);
        cleanFish.setNextCookingFish(pickleFish);
        pickleFish.setNextCookingFish(cookedSoupFish);
        cookedSoupFish.setNextCookingFish(addFish);
        addFish.setNextCookingFish(decorateFish);
        return buyFish;
    }
    public static void main(String[] args) {
        AbstractCookingFish cookingFish = getCookingFish();
        cookingFish.cookingFish(AbstractCookingFish.FIRST, "一");
        cookingFish.cookingFish(AbstractCookingFish.SECOND, "二");
        cookingFish.cookingFish(AbstractCookingFish.THIRD, "三");
        cookingFish.cookingFish(AbstractCookingFish.FOURTH, "四");
        cookingFish.cookingFish(AbstractCookingFish.FIFTH, "五");
        cookingFish.cookingFish(AbstractCookingFish.SIXTH, "六");
    }
}

步骤 4

执行程序,输出结果:

Connected to the target VM, address: '127.0.0.1:55215', transport: 'socket'
BuyFish:买鱼步骤--一
CleanFish:清理鱼,准备调料步骤--二
PickleFish:腌制鱼步骤--三
CookedSoupFish:炒制汤料步骤--四
AddFish:分时段加入鱼骨鱼肉步骤--五
最后一步DecorateFish:点缀装饰步骤--六
Disconnected from the target VM, address: '127.0.0.1:55215', transport: 'socket'
Process finished with exit code 0

今天这个例子简单叙述了酸菜鱼的烹饪步骤,给大家讲述了设计模式中的代理模式和职责链模式,后期会随机更新其他设计模式,欢迎关注博主公众号,发现更多精彩内容!

相关文章
|
2月前
|
设计模式 Java Spring
Java 设计模式之责任链模式:优雅处理请求的艺术
责任链模式通过构建处理者链,使请求沿链传递直至被处理,实现发送者与接收者的解耦。适用于审批流程、日志处理等多级处理场景,提升系统灵活性与可扩展性。
278 2
|
2月前
|
设计模式 网络协议 数据可视化
Java 设计模式之状态模式:让对象的行为随状态优雅变化
状态模式通过封装对象的状态,使行为随状态变化而改变。以订单为例,将待支付、已支付等状态独立成类,消除冗长条件判断,提升代码可维护性与扩展性,适用于状态多、转换复杂的场景。
312 0
|
4月前
|
设计模式 缓存 Java
Java设计模式(二):观察者模式与装饰器模式
本文深入讲解观察者模式与装饰器模式的核心概念及实现方式,涵盖从基础理论到实战应用的全面内容。观察者模式实现对象间松耦合通信,适用于事件通知机制;装饰器模式通过组合方式动态扩展对象功能,避免子类爆炸。文章通过Java示例展示两者在GUI、IO流、Web中间件等场景的应用,并提供常见陷阱与面试高频问题解析,助你写出灵活、可维护的代码。
|
2月前
|
设计模式 算法 搜索推荐
Java 设计模式之策略模式:灵活切换算法的艺术
策略模式通过封装不同算法并实现灵活切换,将算法与使用解耦。以支付为例,微信、支付宝等支付方式作为独立策略,购物车根据选择调用对应支付逻辑,提升代码可维护性与扩展性,避免冗长条件判断,符合开闭原则。
319 35
|
2月前
|
设计模式 消息中间件 传感器
Java 设计模式之观察者模式:构建松耦合的事件响应系统
观察者模式是Java中常用的行为型设计模式,用于构建松耦合的事件响应系统。当一个对象状态改变时,所有依赖它的观察者将自动收到通知并更新。该模式通过抽象耦合实现发布-订阅机制,广泛应用于GUI事件处理、消息通知、数据监控等场景,具有良好的可扩展性和维护性。
265 8
|
7月前
|
设计模式 缓存 安全
【高薪程序员必看】万字长文拆解Java并发编程!(8):设计模式-享元模式设计指南
🌟 ​大家好,我是摘星!​ 🌟今天为大家带来的是并发编程中的经典对象复用设计模式-享元模式,废话不多说让我们直接开始。
172 0
|
4月前
|
设计模式 安全 Java
Java设计模式(一):单例模式与工厂模式
本文详解单例模式与工厂模式的核心实现及应用,涵盖饿汉式、懒汉式、双重检查锁、工厂方法、抽象工厂等设计模式,并结合数据库连接池与支付系统实战案例,助你掌握设计模式精髓,提升代码专业性与可维护性。
|
4月前
|
设计模式 XML 安全
Java枚举(Enum)与设计模式应用
Java枚举不仅是类型安全的常量,还具备面向对象能力,可添加属性与方法,实现接口。通过枚举能优雅实现单例、策略、状态等设计模式,具备线程安全、序列化安全等特性,是编写高效、安全代码的利器。
|
9月前
|
设计模式 Java 数据安全/隐私保护
Java 设计模式:装饰者模式(Decorator Pattern)
装饰者模式属于结构型设计模式,允许通过动态包装对象的方式为对象添加新功能,提供比继承更灵活的扩展方式。该模式通过组合替代继承,遵循开闭原则(对扩展开放,对修改关闭)。
|
设计模式 消息中间件 搜索推荐
Java 设计模式——观察者模式:从优衣库不使用新疆棉事件看系统的动态响应
【11月更文挑战第17天】观察者模式是一种行为设计模式,定义了一对多的依赖关系,使多个观察者对象能直接监听并响应某一主题对象的状态变化。本文介绍了观察者模式的基本概念、商业系统中的应用实例,如优衣库事件中各相关方的动态响应,以及模式的优势和实际系统设计中的应用建议,包括事件驱动架构和消息队列的使用。
219 6