模式 | 目的 | 包含内容 | 简介 |
创建型模式 | 隐式创建对象,而不是简单的使用new 一个对象。 | 工厂模式(Factory Pattern) | 实用 |
抽象工厂模式(Abstract Factory Pattern) | |||
单例模式(Singleton Pattern) | 简单实用,不介绍 | ||
建造者模式(Builder Pattern) | |||
原型模式(Prototype Pattern) | |||
结构型模式 | 组合接口或对象获得新功能或增强原功能 | 适配器模式(Adapter Pattern) | |
桥接模式(Bridge Pattern) | |||
过滤器模式(Filter、Criteria Pattern) | |||
组合模式(Composite Pattern) | |||
装饰器模式(Decorator Pattern) | 实用程度:⭐⭐⭐⭐⭐ 定义:在不改变原对象的基础上,加强原对象的功能 经典使用场景:java中IO流的设计 | ||
外观模式(Facade Pattern) | |||
享元模式(Flyweight Pattern) | |||
代理模式(Proxy Pattern) | |||
行为型模式 | 关注对象中之间的通信 | 责任链模式(Chain of Responsibility Pattern) | 定义:对同一资源有多种不同逻辑的处理链。 使用场景:如对前端输入信息进行js脚本过滤,SQL注入过滤,敏感词过滤,URL过滤。这其中不同的过滤器的规则可能会发生变化,所以可以使用责任链模式。 实际场景:不同条件下筛选用户处理。 |
命令模式(Command Pattern) | |||
解释器模式(Interpreter Pattern) | |||
迭代器模式(Iterator Pattern) | |||
中介者模式(Mediator Pattern) | |||
备忘录模式(Memento Pattern) | |||
观察者模式(Observer Pattern) | 定义:观察者模式定义了一种一对多的依赖关系,让多个观察者对象监听某一个主题对象。这个主题对象在状态发生改变时,会通知所有观察对象。 使用场景: | ||
状态模式(State Pattern) | 使用场景: 当处理业务有多种不同的状态时,满足如下特征即可使用状态模式: 1.状态之前存在不同条件下的转换关系 2.不同的状态下有相同的处理操作逻辑不一样(单单只有这个特点可以使用策略模式,但是策略模式不存在转换关系) 策略模式与状态模式是双胞胎 实例: | ||
空对象模式(Null Object Pattern) | |||
策略模式(Strategy Pattern) | 实用程度:⭐⭐⭐⭐⭐ 定义了算法族,分别封装起来,让他们之间可相互替换。 经典应用:实现Comparetor接口后的实体可以使用 方法一:Collections.sort(List<T extends Comparable> t);
方法二:Collections.sort(List<T> t,Comparator);(这个才是Strategy模式)。
前面的方法不够灵活,因为当前面的类本身实现了comparable 接口后,如果再想让该类更换一种排序算法呢?这个时候就能使用第二个方法。自己实现一个类单独实现comparator方法,作为参数传入。 实际应用: 不同的前端对象需要查询并展示预批结果。 | ||
模板模式(Template Pattern) | |||
访问者模式(Visitor Pattern) |
装饰器模式(Decorator Pattern)
定义:
在不改变原对象的基础上,加强原对象的功能。
Java中的IO对象实现就是经典的装饰器模式使用:
InputStream -> FileInputString -> BufferedInputStream
实际应用场景:
需求一:查询一个接口的数据展示到前端
1.先定义一个查询接口
public interface QueryInterface{
Object query();
}
2.实现
@Resource(name="queryInterfaceImp")
public class QueryInterfaceImp implements QueryInterface{
@override
public Object Query(){
//调用Http接口
Object obj = HttpUtils.get("/api/query");
return obj;
}
}
需求二:由于接口网络不稳定,在查询的时候需要存入数据库,以防网络不通时查询本地数据库
3.这是大多数人选择的改造方式,对QueryInterfaceImp进行改造
// 反例
@Service("queryInterfaceImp")
public class QueryInterfaceImp implements QueryInterface{
@override
public Object Query(){
//调用Http接口
Object obj = HttpUtils.get("/api/query");
saveDb(obj);
return obj;
}
}
4.使用装饰器模式改造
@Service("saveInterfaceImp")
public class SaveInterfaceImp extends QueryInterfaceImp{
@override
public Object Query(){
//调用Http接口
Object obj = super(query());
saveDb(obj);
return obj;
}
}
这样在使用时我会根据具体场景,选择不用的使用方式
@Resource(name="saveInterfaceImp")
QueryInterface saveInterfaceImp;
@Resource(name="queryInterfaceImp")
QueryInterface queryInterfaceImp;
@Test
public void test(){
saveInterfaceImp.query();
}
@Test
public void test2(){
queryInterfaceImp.query();
}
责任链模式
使用场景举例:
例一:
对前端输入的数据保存至数据库需要通过层层校验
- 是否有js脚本攻击
- 是否有敏感字段
- 是否有带入非法链接
例二:
对前端访问需要做如下校验:
1.请求频率 -> 2.登录认证 -> 3.权限访问->4.敏感词过滤
对例一的场景代码做如下实现
public class ResponseChain2 {
public static void main(String[] args) {
String m = "Hello 大家好,我是梦想家 <script>alert(做鸡)</script> SB,请见网址:http://www.jc.com";
Msg msg = new Msg();
msg.setMsg(m);
MsgFilterChain chain = new MsgFilterChain()
.add(new HtmlFilter()).add(new SensitiveFilter());
MsgFilterChain chain2 = new MsgFilterChain().add(new UrlFilter());
chain.add(chain2);
chain.filter(msg);
System.out.println(msg.getMsg());
}
}
interface MsgFilter{
boolean filter(Msg msg);
}
class MsgFilterChain implements MsgFilter{
private List<MsgFilter> chains = new ArrayList<>();
public MsgFilterChain add(MsgFilter filter){
chains.add(filter);
return this;
}
public boolean filter(Msg msg){
for (MsgFilter chain : chains) {
if(!chain.filter(msg)){
return false;
}
}
return true;
}
}
class HtmlFilter implements MsgFilter{
@Override
public boolean filter(Msg msg) {
String m = msg.getMsg();
msg.setMsg(m.replace("<","[").replace(">","]"));
return true;
}
}
class SensitiveFilter implements MsgFilter{
//可以使用return false 中断该链,直接返回
@Override
public boolean filter(Msg msg) {
String m = msg.getMsg();
msg.setMsg(m.replace("做鸡","**")
.replace("SB","**"));
return true;
}
}
class UrlFilter implements MsgFilter{
@Override
public boolean filter(Msg msg) {
String m = msg.getMsg();
msg.setMsg(m.replace("http://www.jc.com","虚假链接,请勿点击"));
return true;
}
}
class Msg{
private String msg;
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}