前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >你TM敢信,小面竟然用java制作酸菜鱼,还跟我扯设计模式

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

作者头像
灬沙师弟
发布2023-03-20 15:58:40
2290
发布2023-03-20 15:58:40
举报
文章被收录于专栏:Java面试教程

引言

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

我们先来看下整体流程:

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

一. 买鱼

1.选鱼

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

2.杀鱼

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

定义接口,处理鱼

代码语言:javascript
复制
public interface HandleFish {
    /**
     * 处理鱼
     * @param fish
     */
    void handleFish(String fish);
}

真实处理鱼的摊贩处理

代码语言:javascript
复制
@Service
public class RealPersonHandleFish implements HandleFish{

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

自己处理鱼

代码语言:javascript
复制
@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);
    }
}

开始处理鱼

代码语言:javascript
复制
public class ProxyPatternDemo {
    public static void main(String[] args) {
        HandleFish handleFish = new MySelfHandleFist();
        handleFish.handleFish("鱼");
    }
}

执行结果

代码语言:javascript
复制
开始处理:
我是摊贩,开始处理:鱼

Process finished with exit code 0

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

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

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

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

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

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

1.清理鱼肉

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

2.调料准备

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

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

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

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

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

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

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

三. 腌制

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

四. 炒制汤料

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

五. 分时分段下入鱼肉

微信图片_2022080616250614.jpg

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

六. 点缀装饰

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

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

责任链模式

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

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

意图

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

主要解决

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

何时使用

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

如何解决

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

关键代码

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

使用场景

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

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

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

简单实现

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

责任链模式的 UML 图

步骤 1

创建抽象的鱼处理类。

代码语言:javascript
复制
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

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

代码语言:javascript
复制
public class BuyFish extends AbstractCookingFish {

    public BuyFish(int level){
        this.level = level;
    }

    @Override
    protected void cooke(String message) {
        System.out.println("BuyFish:买鱼步骤--" + message);
    }
}


代码语言:javascript
复制
public class CleanFish extends AbstractCookingFish {

    public CleanFish(int level){
        this.level = level;
    }

    @Override
    protected void cooke(String message) {
        System.out.println("CleanFish:清理鱼,准备调料步骤--" + message);
    }
}
代码语言:javascript
复制
public class PickleFish extends AbstractCookingFish {
   
       public PickleFish(int level){
           this.level = level;
       }
   
       @Override
       protected void cooke(String message) {
           System.out.println("PickleFish:腌制鱼步骤--" + message);
       }
   }
代码语言:javascript
复制
public class CookedSoupFish extends AbstractCookingFish {

    public CookedSoupFish(int level){
        this.level = level;
    }

    @Override
    protected void cooke(String message) {
        System.out.println("CookedSoupFish:炒制汤料步骤--" + message);
    }
}
代码语言:javascript
复制
public class AddFish extends AbstractCookingFish {

    public AddFish(int level){
        this.level = level;
    }

    @Override
    protected void cooke(String message) {
        System.out.println("AddFish:分时段加入鱼骨鱼肉步骤--" + message);
    }
}

代码语言:javascript
复制
public class DecorateFish extends AbstractCookingFish {

    public DecorateFish(int level){
        this.level = level;
    }

    @Override
    protected void cooke(String message) {
        System.out.println("最后一步DecorateFish:点缀装饰步骤--" + message);
    }
}
步骤 3

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

代码语言:javascript
复制
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

执行程序,输出结果:

代码语言:javascript
复制
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

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

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-09-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Java面试教程 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 引言
    • 一. 买鱼
      • 1.选鱼
      • 2.杀鱼
    • 二. 清洗整理鱼肉,备好需要调料
      • 1.清理鱼肉
      • 2.调料准备
    • 三. 腌制
      • 四. 炒制汤料
        • 五. 分时分段下入鱼肉
          • 六. 点缀装饰
            • 责任链模式
        相关产品与服务
        容器服务
        腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档