设计模式读书笔记第一期

工厂模式

工厂模式大致结构

image-20230331205536431

  • 图中实现了一个计算器的功能
  • Operation为抽象父类,Sub,Add两个子类去继承抽象父类,然后实现抽象父类的方法,抽象父类的方法可以是有实现的方法,因此我这边用了一个具体实现的方法,写成抽象方法也可以,但子类就需要必须实现了,而非抽象方法不一定要实现,我这种只写了两个功能,4个功能也是一样的,为了篇幅减少一下。
  • OperationFactory作为一个简单的工厂,接受字符串,然后再给予相对应的实现子类的实例对象。比如你写”+”,就对应new Add()。

工厂的具体实现方法

public class OperationFactory {
public static Operation createOperate(String operate){
Operation op = null;
switch (operate){
case "+":
op = new Add();
break;
case "-":
op = new Sub();
break;
}
return op;
}
}

好处:其实很明显,本来这段switch case,你可能会放在控制层或者业务层,而将这些代码抽象出来,放在一个工厂中,输入一个你想要的操作,便会给你相对应的实例对象,减少了耦合度。但结合下面要讲的策略模式,还可以进一步减少耦合度。

测试方法

public class TestFactory {
public static void main(String[] args) {
Operation operate = OperationFactory.createOperate("+");
double result = operate.getResult(520, 1314);
System.out.println(result);
}
}

策略模式

策略模式大致结构图

image-20230331211346849

  • 图中CashSuper的抽象父类,其中acceptCash是抽象方法

  • 三个具体子类继承了CashSuper并且重写了CashSuper的方法,CashNormal表示在商场正常购买商品,double price价格,int num数量,CashReturn 代表买xxx返xxx,值得注意的是他们接受的参数相同,只是具体实现不同而已,CashRebate代表打折情况。

  • CashContext里面其实还包含了一个构造器

  • 用工厂模式+策略模式结合,将CashContext用作一个Context上下文,用来维护CashSuper这个变量,将构造器的参数改变一个就可以实现传输功能类型,然后将变量赋值成相对应的实现子类。用getResult方法获取具体结果,这样一来获取具体对象交给上下文,具体执行方法也交给上下文。那么客户端只要知道Context一个上下文就可以直接获取结果。

public class CashContext {
private CashSuper cs;

public CashContext(int cashType) {
switch (cashType){
case 1:
this.cs = new CashNormal();
break;
case 2:
this.cs = new CashRebate(0.8);
break;
case 3:
this.cs = new CashReturn(300,100);
break;
}

}
public double getResult(double price,int num){
return this.cs.acceptCash(price,num);
}
}

测试方法

public class TestFactoryAndStrategy {
public static void main(String[] args) {
CashContext cashContext = new CashContext(1);
double result = cashContext.getResult(400, 2);
System.out.println(result);
}
}

对比一下工厂模式

public class TestFactory {
public static void main(String[] args) {
Operation operate = OperationFactory.createOperate("+");
double result = operate.getResult(520, 1314);
System.out.println(result);
}
}

工厂模式需要知道createOperate这个方法,而策略+工厂模式,直接利用上下文构造器传入参数,然后直接获取对应的实现子类,直接调用方法,降低了客户端的使用难度。调用起来更方法,后面像鱼皮讲的适配器模式,门面模式,大致都相同,为了简单调用,降低耦合,扩展性更强。

⭐项目和个人博客

项目:

项目是比较老套的图书管理系统,SpringBoot+Vue2+ElementUI

套个皮,直接改下数据库,宠物管理系统,车辆管理系统,甜品管理系统,全部都一个样。

主要是管理系统的话,后端用组件库比较方便,我用的elementUI,推荐可以试一试Ant Design Vue,Vue也是可以利用后端swagger直接生成接口的,前提要VUE3+TS可以玩。

亮点可能是:1.登录拦截器(也可以用AOP的切面玩)2.Token(可以增加redis)3.Echarts可以展示借阅量,你也可以增加活跃用户4.里面内置爬虫,可以爬数据5.swagger+knife4j测试接口

可扩展点:可以增加图书推荐,进行大数据分析,这个应该是不难的,或者你添加ES,然后做下搜索引擎的优化,这个也不难,按后端数据库表,构建下索引就行,然后你可以设置定时任务进行数据库和ES同步,或者直接logstash中间件传输、处理数据也行,使用插件比较方便。你还阔以添加图书秒杀,用上RabbitMQ。但一切技术其实是用于业务,其实单个人项目完全用不着消息队列,redis,因为毫无并发量可言。毕设做微服务属实有点离谱了,属于是只是用技术,但是实际业务完全不至于用上,建议还是做个小而美的项目或者比较有创新点的和GPT接轨的项目,把GPT当作一个后台接口测试。

小建议:不用焦虑chatGPT,反而是要学习如何将GPT和学习和工作结合,会使用好AI的人,比不会用AI的人淘汰率应该会小很多(个人想法)。

项目部署地址

欢迎在读者留言组件进行留言(采用的是移动弹幕形式)

项目GitHub地址

项目Gitee地址

欢迎⭐Star和⭐互关,有问题可以私信我咯

个人博客地址