你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

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

相关文章
|
3月前
|
设计模式 消息中间件 搜索推荐
Java 设计模式——观察者模式:从优衣库不使用新疆棉事件看系统的动态响应
【11月更文挑战第17天】观察者模式是一种行为设计模式,定义了一对多的依赖关系,使多个观察者对象能直接监听并响应某一主题对象的状态变化。本文介绍了观察者模式的基本概念、商业系统中的应用实例,如优衣库事件中各相关方的动态响应,以及模式的优势和实际系统设计中的应用建议,包括事件驱动架构和消息队列的使用。
|
3月前
|
设计模式 Java 数据库连接
Java编程中的设计模式:单例模式的深度剖析
【10月更文挑战第41天】本文深入探讨了Java中广泛使用的单例设计模式,旨在通过简明扼要的语言和实际示例,帮助读者理解其核心原理和应用。文章将介绍单例模式的重要性、实现方式以及在实际应用中如何优雅地处理多线程问题。
56 4
|
4月前
|
设计模式 Java 程序员
[Java]23种设计模式
本文介绍了设计模式的概念及其七大原则,强调了设计模式在提高代码重用性、可读性、可扩展性和可靠性方面的作用。文章还简要概述了23种设计模式,并提供了进一步学习的资源链接。
92 0
[Java]23种设计模式
|
3月前
|
设计模式 JavaScript Java
Java设计模式:建造者模式详解
建造者模式是一种创建型设计模式,通过将复杂对象的构建过程与表示分离,使得相同的构建过程可以创建不同的表示。本文详细介绍了建造者模式的原理、背景、应用场景及实际Demo,帮助读者更好地理解和应用这一模式。
114 0
|
4月前
|
设计模式 监控 算法
Java设计模式梳理:行为型模式(策略,观察者等)
本文详细介绍了Java设计模式中的行为型模式,包括策略模式、观察者模式、责任链模式、模板方法模式和状态模式。通过具体示例代码,深入浅出地讲解了每种模式的应用场景与实现方式。例如,策略模式通过定义一系列算法让客户端在运行时选择所需算法;观察者模式则让多个观察者对象同时监听某一个主题对象,实现松耦合的消息传递机制。此外,还探讨了这些模式与实际开发中的联系,帮助读者更好地理解和应用设计模式,提升代码质量。
Java设计模式梳理:行为型模式(策略,观察者等)
|
5月前
|
存储 设计模式 安全
Java设计模式-备忘录模式(23)
Java设计模式-备忘录模式(23)
|
5月前
|
设计模式 存储 算法
Java设计模式-命令模式(16)
Java设计模式-命令模式(16)
|
5月前
|
设计模式 存储 缓存
Java设计模式 - 解释器模式(24)
Java设计模式 - 解释器模式(24)
|
5月前
|
设计模式 安全 Java
Java设计模式-迭代器模式(21)
Java设计模式-迭代器模式(21)
|
5月前
|
设计模式 缓存 监控
Java设计模式-责任链模式(17)
Java设计模式-责任链模式(17)