快速了解设计模式(装饰器模式,责任链模式)

模式

目的

包含内容

简介

创建型模式

隐式创建对象,而不是简单的使用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)

空对象模式(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();
}

 责任链模式

使用场景举例:

例一:

对前端输入的数据保存至数据库需要通过层层校验

  1. 是否有js脚本攻击
  2. 是否有敏感字段
  3. 是否有带入非法链接

例二:

对前端访问需要做如下校验:

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;
    }
}

Guess you like

Origin blog.csdn.net/weixin_48470176/article/details/116328666