当前位置: 首页 > news >正文

java 策略模式 + 工厂模式 实例

一 前言

经常听说各种设计模式,知道理论,也知道应该使用,但具体怎么用,什么时候用,使用的优点一直比较模糊,今天写一个项目中经常用到的模式,来具体理解。项目中经常用到工厂模式或者策略模式,偶尔也会一起使用来增强代码管理,今天就一起使用来理解。

二 实现

不废话,直接上代码,最后解释
先写一个接口 Person 类

package com.fcy.demo.entity;public interface Person {void eat();void run();
}

然后使用策略模式,根据不同的人的类型,创建不同的人,实现该接口,这里有三种类型 Teacher, Doctor, Worker, 首先定义一个常量类,包含这三种类型的人。

package com.fcy.demo.constant;public class PersonType {public static final String TEACHER = "teacher";public static final String DOCTOR = "doctor";public static final String WORKER = "worker";
}

接着写三种人的实现类

package com.fcy.demo.entity;import com.fcy.demo.constant.PersonType;
import org.springframework.stereotype.Component;@Component(PersonType.TEACHER)
public class Teacher implements Person{@Overridepublic void eat() {System.out.println("老师吃");}@Overridepublic void run() {System.out.println("老师跑");}
}
package com.fcy.demo.entity;import com.fcy.demo.constant.PersonType;
import org.springframework.stereotype.Component;@Component(PersonType.DOCTOR)
public class Doctor implements Person{@Overridepublic void eat() {System.out.println("医生吃");}@Overridepublic void run() {System.out.println("医生跑");}
}
package com.fcy.demo.entity;import com.fcy.demo.constant.PersonType;
import org.springframework.stereotype.Component;@Component(PersonType.WORKER)
public class Worker implements Person{@Overridepublic void eat() {System.out.println("工人吃");}@Overridepublic void run() {System.out.println("工人跑");}
}

到此,为什么使用策略模式呢,因为如果不使用策略模式,所有代码都写在一个实现类里,当用户想让一个老师吃的时候,代码会变得比较繁琐,类似:

public void eat(PersonType type){if (PersonType.TEACHER.equals(type)){System.out.println("老师吃");} else if (PersonType.DOCTOR.equals(type)){System.out.println("医生吃");} else (PersonType.WORKER.equals(type)){System.out.println("工人吃");}
}

这里只有三种人,如果有十种甚至更多,会有更多的 if…else…, 同理对 run 操作也会有这么多的判断,实在难以维护,后续对某一类型的 eat 行为做更改时,也会影响其他代码,违背了开闭原则,即对扩展开放,对修改关闭。因此使用策略模式,使不同类型的人实现同一接口,当对某一类型的行为做更改时,不会影响其他类型的代码。
接下来说工厂模式
上面代码中重点是 @Component(PersonType.WORKER), 定义了 @Component 里的参数使得之后使用工厂模式时可以知道工厂该生产那种人。
到此,为什么使用工厂模式呢,如果不使用工厂模式,仅使用策略模式,同理当我想要一个老师吃的时候我需要自己实例一个老师类,类似下面代码:

public void eat(PersonType type){if (PersonType.TEACHER.equals(type)){Teacher teacher = new Teacher();teacher.eat();} else if (PersonType.DOCTOR.equals(type)){Doctor doctor = new Doctor();doctor.eat();} else (PersonType.WORKER.equals(type)){Worker worker = new Worker();worker.eat();}
}

虽然我们使用了策略模式,使代码满足开闭原则,易于维护,但并没有解决这么多 if…else… 的问题,所以我们使用工厂模式,减少判断,上代码:

package com.fcy.demo.factory;import com.fcy.demo.entity.Person;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;@Component
public class PersonFactor {@Autowiredprivate Map<String, Person> personTypeMap;public Person getPerson(String personType) {return personTypeMap.get(personType);}
}

至此我们就不需要这么多的判断了,当需要某种类型的人时,直接告诉工厂就可以了,controller 代码如下:

package com.fcy.demo.controller;import com.fcy.demo.entity.Person;
import com.fcy.demo.factory.PersonFactor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/person")
public class PersonController {@Autowiredpublic PersonFactor personFactor;@GetMapping("/teacher")public void getTeacher(){Person teacher = personFactor.getPerson("teacher");teacher.eat();}
}

启动代码,访问 http://localhost:8080/person/teacher, 发现控制台输出 “老师吃”, 测试成功,至此代码完成,也可以在 controller 中写其他的方法。

三 总结

在上面中解释了为什么使用 策略模式以及工厂模式,以及使用的优点,还有一个问题没有说,就是什么时候使用该模式, 在一类事物有共同的行为,但行为模式不同时就可以使用。
就到这吧,至此,关于 策略模式与工厂模式有了一个基本理解,也可以实现了。

http://www.lryc.cn/news/11020.html

相关文章:

  • 本地生成动漫风格 AI 绘画 图像|Stable Diffusion WebUI 的安装和部署教程
  • 华为OD机试 - 异常的打卡记录 | 备考思路,刷题要点,答疑 【新解法】
  • 「机器学习笔记」之深度学习基础概念(基于Pytorch)
  • 概率和似然
  • 前期软件项目评估偏差,如何有效处理?
  • Xline v0.2.0: 一个用于元数据管理的分布式KV存储
  • CompletableFuture
  • 面试不到10分钟就被赶出来了,问的实在是太变态了...
  • 【C++】类与对象 (四)初始化列表 static成员 友元 内部类 匿名对象 拷贝对象时的一些编译器优化
  • 04:进阶篇 - 编译 CTK
  • SQL73 返回所有价格在 3美元到 6美元之间的产品的名称和价格
  • 【Linux 多线程互斥】如何保证锁的原子性(互斥的原理)
  • Android 实现沉浸式全屏
  • 数据分析与SAS学习笔记6
  • 自动化完成1000个用户的登录并获取token并生成tokens.txt文件
  • 2023年全国最新安全员精选真题及答案1
  • NoMachine 输入用户名密码后 闪断 解决办法
  • WebADI - 参数的使用
  • 【OJ】两个圆
  • 一文读懂澳洲医疗:白菜价的药物怎么领?
  • scrum看板视图切换时间线视图做项目管理
  • 10、MySQL查询优化
  • C++模板(一)
  • 【TypeScript】TypeScript的基础类型(string,number,boolean,void,null,undefined):
  • 【C语言】 详谈指针
  • 内网渗透(三十八)之横向移动篇-pass the key 密钥传递攻击(PTK)横向攻击
  • 教你快速学会画动漫人物表情
  • Qt系列:调用Edge浏览器示例
  • 内推|香港外企急招ETL工程师!数据分析师+Python开发+运营专家
  • zlib压缩原理