面试题:熟悉设计模式吗?谈谈简单工厂模式和策略模式的区别

news2025/1/12 21:49:17

刚刚接触设计模式的时候,我相信单例模式和工厂模式应该是用的最多的,毕竟很多的底层代码几乎都用了这些模式。自从接触了一次阿里的公众号发的一次文章关于 DDD的使用 以后,就逐渐接触了策略模式。现在在项目中运用最多的也是这几种设计模式了,用了设计模式给我的感受就是感觉代码没那么冗余了,再注入一点贫血,充血模型之后,感觉在 service 层面代码看上去很舒服很简洁。

首先,我个人感觉策略模式和我们常说的微服务我觉得思想上很像,尤其记得当时介绍DDD时候的举例说的是关于银行的转账案例,用的事务和领域驱动设计做的比较,让人一目了然的逻辑,代码也再也没有那么冗余了。(具体的文章地址找不到了,不过网上现在比较多的介绍DDD的,大体意思是一样的)

其实工厂模式和设计模式一直给人一种错觉,总感觉是一样的,没有丝毫的区别。可以看下两种模式的UML图。

在这里插入图片描述
从图上来看,并没有多大的区别,话不多说,从具体的代码入手。

先写一个人的接口类,有eat,run,wear 3个方法

public interface People {
 
    public void eat();
 
    public void run();
 
    public void wear();
}

分别写两个实现类,一个是小明的实现类,一个是小红的实现类

public class Xiaoming implements People{
 
    @Override
    public void eat() {
        System.out.println("小明吃饭");
    }
 
    @Override
    public void run() {
        System.out.println("小明跑步");
    }
 
    @Override
    public void wear() {
        System.out.println("小明穿衣");
    }
}
 
 
public class Xiaohong implements People{
 
    @Override
    public void eat() {
        System.out.println("小红吃饭");
    }
 
    @Override
    public void run() {
        System.out.println("小红跑步");
    }
 
    @Override
    public void wear() {
        System.out.println("小红穿衣");
    }
}

简单工厂模式的代码

public class PeopleFactory {
 
    public People getPeople(String name){
        if(name.equals("Xiaoming")){
            return new Xiaoming();
        }else if(name.equals("Xiaohong")){
            return new Xiaohong();
        }
        return null;
    }
}

再来看下策略模式的代码

public class StrategySign {
 
    private People people;
 
    public StrategySign(People people){
        this.people = people;
    }
 
    public StrategySign(String name){
        if(name.equals("Xiaoming")){
            this.people = new Xiaoming();
        }else if(name.equals("Xiaohong")){
            this.people = new Xiaohong();
        }
    }
 
    public void run(){
        people.run();
    }
}

策略模式的两种构造方法都可以用,我多写了一种是为了让大家看到和工厂模式的区别和联系

然后我们通过测试类运行两种模式

@Test
public void testSign(){
    PeopleFactory peopleFactory = new PeopleFactory();
    People people = peopleFactory.getPeople("Xiaohong");
    System.out.print("工厂模式-------------"); people.run();
    StrategySign strategySign = new StrategySign("Xiaohong");
    System.out.print("策略模式-------------");strategySign.run();
}

在这里插入图片描述
可以看到,两种设计模式的运行结果是一模一样的,那么区别到底在哪呢。

从工厂模式的代码中可以看到 工厂模式主要是返回的接口实现类的实例化对象,最后返回的结果是接口实现类中的方法,而策略模式是在实例化策略模式的时候已经创建好了,我们可以再策略模式中随意的拼接重写方法,而工厂模式是不管方法的拼接这些的,他只关注最后的结果,不注重过程,而策略模式注重的是过程。

用一个具体的例子可以看下,如果我想小红先吃饭再跑步再吃饭的话,那么我需要在测试类中写3种,而我只需要在策略模式的方法中直接定义即可。

可以看以下代码:

public class StrategySign {
 
    private People people;
 
    public StrategySign(People people){
        this.people = people;
    }
 
    public StrategySign(String name){
        if(name.equals("Xiaoming")){
            this.people = new Xiaoming();
        }else if(name.equals("Xiaohong")){
            this.people = new Xiaohong();
        }
    }
 
    public void run() {
        people.eat();
        people.run();
        people.eat();
    }
}
 
	@Test
    public void testSign(){
        PeopleFactory peopleFactory = new PeopleFactory();
        People people = peopleFactory.getPeople("Xiaohong");
        System.out.print("工厂模式-------------"); people.eat();
        System.out.print("工厂模式-------------"); people.run();
        System.out.print("工厂模式-------------"); people.eat();
        StrategySign strategySign = new StrategySign("Xiaohong");
        System.out.print("策略模式-------------");strategySign.run();
    }

在这里插入图片描述
有人可能会说如果我在实现类中直接拼接好这些方法不是就好了么?可是那样的话我们每变更一次逻辑就要新增一个方法,一次两次还好,但是当逻辑多了以后,这些代码会变得很冗余,难以维护。而且从目前情况来看,工厂模式可以做到的事情,策略模式都可以做到。策略模式可以做到的事情,工厂模式也可以做到,只是会变得麻烦。

从上述的描述来看,策略模式就和我们常说的微服务很像,比如我们写的3个接口,吃饭是一个微服务,跑步是一个微服务,穿衣是一个微服务。策略模式的宗旨就是将各项方法之间连接起来,达到一个新的方法,微服务的宗旨也是防止服务的多次调用,降低代码的耦合度,因此这么看来策略模式和微服务还是比较相像的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1058184.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

使用mysql的cmd窗口,运行项目中的mapper层xml里的sql语句,查看运行结果

使用mysql的cmd窗口,运行项目中的mapper层xml里的sql语句,查看运行结果 项目代码或者从控制台复制sql语句从控制台搜索方式 运行效果或者使用idea的console窗口运行查看结果点击进入,查看表结构与字段 其他技巧根据from 表名寻找对应的sql代码…

Linux系统编程系列之线程属性

一、什么是线程属性 线程属性就是线程的属性,是一个用于控制线程行为和功能的参数集合。它可以影响线程的优先级、调度、同步行为和资源管理等方面。线程有许多属性,如分离属性,继承策略,调度策略等。看图 二、线程属性的特性 1、…

ctfshow 命令执行(40-50)

web40 题目过滤了很多 if(isset($_GET[c])){$c $_GET[c];if(!preg_match("/[0-9]|\~|\|\|\#|\\$|\%|\^|\&|\*|\&#xff08;|\&#xff09;|\-|\|\|\{|\[|\]|\}|\:|\|\"|\,|\<|\.|\>|\/|\?|\\\\/i", $c)){eval($c);}}else{highlight_file(__FILE_…

pycharm 中的一个非常好使用的智能提示tabnine(大大提高代码的书写效率)

一. pycharm 中的代码智能提示插件 有时候,我们总是在写代码的时候,敲全部的代码,太过于麻烦了,如果有一个软件可以预知你的后续的操作,提前将代码给你写出来,你只需要检查对错,就可以了,这样就大大提高了工作的效率. 上面的一个插件是汉化pycharm的软件包,也是非常好用的一款…

小谈设计模式(14)—建造者模式

小谈设计模式&#xff08;14&#xff09;—建造者模式 专栏介绍专栏地址专栏介绍 建造者模式角色分类产品&#xff08;Product&#xff09;抽象建造者&#xff08;Builder&#xff09;具体建造者&#xff08;Concrete Builder&#xff09;指挥者&#xff08;Director&#xff0…

分享一款开源的QT的串口示波器

分享一款开源的QT的串口示波器&#xff0c;完全开源&#xff0c;支持串口、TCP、波形显示、通信协议。 Sailor Project功能说明 串口调试助手功能 支持传统的串口调试助手的基本收发功能&#xff0c;同时可以刷新大量的数据而不卡顿 支持保存接收的数据 支持最大200条可编辑…

cadence SPB17.4 S032 - Update Symbols失败的问题

文章目录 cadence SPB17.4 S032 - Update Symbols失败的问题概述笔记END cadence SPB17.4 S032 - Update Symbols失败的问题 概述 铺铜后, 进行DRC, 发现安装孔不太合适, 有DRC警告. 安装孔是一大孔, 上面打了一圈小孔. 这些小孔有警告, 说孔和孔之间不能干涉. 开始将这些DRC…

vue3+ts创建前端blog项目

vue3创建blog项目 cmd创建Manually select featuresChoose Vue versionUse class-style component syntax? (Y/n)Use Babel alongside TypeScript (required for modern mode, auto-detected polyfills, transpiling JSX)? (Y/n)Use history mode for router?Pick a CSS pre…

基于SpringBoot的科研工作量获奖项目管理平台设计与实现(源码+lw+部署文档+讲解等)

文章目录 前言具体实现截图论文参考详细视频演示为什么选择我自己的网站自己的小程序&#xff08;小蔡coding&#xff09;有保障的售后福利 代码参考源码获取 前言 &#x1f497;博主介绍&#xff1a;✌全网粉丝10W,CSDN特邀作者、博客专家、CSDN新星计划导师、全栈领域优质创作…

TinyWebServer学习笔记-MySQL数据库连接

为什么要用数据库连接池&#xff1f; 我们的网站允许用户注册&#xff0c;在没有池的情况下&#xff0c;假设只有一个人&#xff0c;那么流程就是&#xff0c;用户点击注册&#xff0c;通过socket将用户的账号和密码发送到服务器&#xff0c;然后就需要创建MySQL数据库连接&am…

C#制做一个 winform下的表情选择窗口

能力有限&#xff0c;别人可能都是通过其他方式实现的&#xff0c;我这里简单粗暴一些&#xff0c;直接通过点击按钮后弹出个新窗体来实现。 1、先在form1上增加一个toolstrip控件&#xff0c;再增加个toolstripbutton按钮&#xff0c;用来点击后弹出新窗体&#xff0c;如图&a…

【Linux】文件权限详解

&#x1f341; 博主 "开着拖拉机回家"带您 Go to New World.✨&#x1f341; &#x1f984; 个人主页——&#x1f390;开着拖拉机回家_Linux,Java基础学习,大数据运维-CSDN博客 &#x1f390;✨&#x1f341; &#x1fa81;&#x1f341; 希望本文能够给您带来一定的…

【C++】可变参数模板使用,在emplace中应用

&#x1f30f;博客主页&#xff1a; 主页 &#x1f516;系列专栏&#xff1a; C ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ &#x1f60d;期待与大家一起进步&#xff01; 文章目录 一、可变参数模板1.参数包的展开方式1.递归方式展开2.逗号表达式展开参数包 二、empl…

王杰国庆作业day6

服务器 #include <stdio.h> #include <string.h> #include <stdlib.h> #include <my_head.h> #define PORT 2324 //端口号 #define IP "192.168.10.107" //本机IP int main(int argc, const char *argv[]) {sqlite3* d…

FPGA project : TFT_LCD

实验目标&#xff1a; 驱动TFT_LCD显示十色彩条。 重点掌握的知识&#xff1a; 1&#xff0c;液晶显示器&#xff0c;简称LCD(Liquid Crystal Display)&#xff0c;相对于上一代CRT显示器(阴极射线管显示器)&#xff0c;LCD显示器具有功耗低、体积小、承载的信息量大及不伤眼…

pwnable_hacknote

pwnable_hacknote Arch: i386-32-little RELRO: Partial RELRO Stack: Canary found NX: NX enabled PIE: No PIE (0x8047000)32位&#xff0c;没开PIE main部分就不贴了&#xff0c;直接贴主要的函数 unsigned int ADD() {int v0; // ebxint i; // [e…

堆栈与堆(Stack vs Heap)有什么区别?

​编写有效的代码需要了解堆栈和堆内存&#xff0c;这使其成为学习编程的重要组成部分。不仅如此&#xff0c;新程序员或职场老手都应该完全熟悉堆栈内存和堆内存之间的区别&#xff0c;以便编写有效且优化的代码。 这篇博文将对这两种内存分配技术进行全面的比较。通过本文的…

【考研复习】union有关的输出问题

文章目录 遇到的问题正确解答拓展参考文章 遇到的问题 首次遇到下面的代码时&#xff0c;感觉应该输出65,323。深入理解union的存储之后发现正确答案是&#xff1a;67,323. union {char c;int i; } u; int main(){u.c A;u.i 0x143;printf("%d,%d\n", u.c, u.i); …

Java 随机数的获得方法(5种)

1. Math.random() 静态方法 产生的随机数是 0 - 1 之间的一个 double&#xff0c;即 0 < random < 1 代码&#xff1a; 结果&#xff1a; 当调用 Math.random() 方法时&#xff0c;自动创建了一个伪随机数生成器&#xff0c;实际上用的是 new java.util.Random()。当接…

C++项目:仿mudou库one thread one loop式并发服务器实现

目录 1.实现目标 2.HTTP服务器 3.Reactor模型 3.1分类 4.功能模块划分: 4.1SERVER模块: 4.2HTTP协议模块: 5.简单的秒级定时任务实现 5.1Linux提供给我们的定时器 5.2时间轮思想&#xff1a; 6.正则库的简单使用 7.通用类型any类型的实现 8.日志宏的实现 9.缓冲区…