前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >观察者模式和Spring的结合

观察者模式和Spring的结合

作者头像
令仔很忙
发布2018-09-14 16:46:14
4480
发布2018-09-14 16:46:14
举报
文章被收录于专栏:令仔很忙令仔很忙

这周给分了一个任务,就是对查询回来的数据进行各种各样的过滤,有七种不同的过滤条件。过滤条件是在数据库中存着的。在我们项目中有一个热发,就是定时的从数据库中把数据取出来进行分类保存到Property中或者Map中。所以一开始想的一个笨的方法就是把七种不同的过滤条件热发到七个不同的Map中去。然后再定义一个过滤的类,所有的查询回来的数据都要经过这个类的处理。 后来想了想,这样做的话,不利于扩展,要是后期还有其他的过滤的话,耦合性太强了。所以这个时候就想到了设计模式中的观察者模式。应用在这个场景下再合适不过了。定义了七个Filter,当热发执行之后,通知所有的观察者来我这拿最新的数据。而且当新添一个新的过滤的过滤条件的话,只需要新加一个过滤的类,并在spring的监听器中配置上该类就可以了,其实这就实现了对内修改关闭,对外扩展。 下面试具体的代码实现。先贴一张图,很经典。

这里写图片描述
这里写图片描述

被观察者


代码语言:javascript
复制
package com.flight.inter.otaadapter.filters;

import java.util.ArrayList;
import java.util.List;

/**
 * 观察者模式抽象通知者类--报价拦截
 * Created by ling.zhang on 2016/12/2.
 */
public abstract class AbstractPriceFilter {
    private List<IPriceFilterListener> listeners=new ArrayList<IPriceFilterListener>();

    public void registerListener(List<IPriceFilterListener> listener){
        this.listeners=listener;
    }

    public void notifyListenner(){
        for(int i=0;i<listeners.size();i++){
            IPriceFilterListener priceFilterListener=listeners.get(i);
            priceFilterListener.actionPerformed();
        }
    }
}

在这个地方需要注意的是,registerListener是需要有注册者的,你总不用说有通知者但是没有被通知者,那时间长了通知者不得倒闭啦,哈哈。在这是通过spring来注册的,就不用在代码中写了,要不然每来一个观察者都写注册方法。我是注册了多个,所以用的是List,如果只有一个的话,不用List,具体看你怎么注册了。当在来一个新的观察者的时候,只需要在list下在新加一个ref就可以注册进去了。

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
  http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
  http://www.springframework.org/schema/context
  http://www.springframework.org/schema/context/spring-context-3.2.xsd">


    <bean id="divCabinFilter" class="com.flight.inter.otaadapter.filters.DivCabinFilter"/>
    <bean id="divFilter" class="com.flight.inter.otaadapter.filters.DivFilter"/>
    <bean id="flightFilter" class="com.flight.inter.otaadapter.filters.FlightFilter"/>
    <bean id="flightGroupFilter" class="com.flight.inter.otaadapter.filters.FlightGroupFilter"/>
    <bean id="operatingCarrierFilter" class="com.flight.inter.otaadapter.filters.OperatingCarrierFilter"/>
    <bean id="shareCarriersFilter" class="com.flight.inter.otaadapter.filters.ShareCarriersFilter"/>
    <bean id="validatingCarrierFilter" class="com.flight.inter.otaadapter.filters.ValidatingCarrierFilter"/>

    <bean id="hotDeployManager" class="com.flight.inter.otaadapter.manage.HotDeployManager"/>

    <bean id="priceFilterListener" class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
        <property name="targetObject">
            <ref local="hotDeployManager"/>
        </property>
        <property name="targetMethod">
            <value>registerListener</value>
        </property>

        <property name="arguments">
            <list>
                <ref bean="divCabinFilter"/>
                <ref bean="divFilter"/>
                <ref bean="flightFilter"/>
                <ref bean="flightGroupFilter"/>
                <ref bean="operatingCarrierFilter"/>
                <ref bean="shareCarriersFilter"/>
                <ref bean="validatingCarrierFilter"/>
            </list>

        </property>
    </bean>
</beans>

上边的是抽象通知者,具体的可以看下子类。子类会去调用通知的方法。下面是个样例。

代码语言:javascript
复制
public class HotDeployManager extends AbstractPriceFilter
{
    //满足你的条件时,去通知观察者们
    notifyListenner();
}

观察者


定义了一个接口先。

代码语言:javascript
复制
public interface IPriceFilterListener {
    void actionPerformed();
}

然后是具体的实现类。用一个来做个示范。通知者通知到该类的时候,这个类就回去得到自己想要的数据。

代码语言:javascript
复制
public class DivCabinFilter implements IPriceFilterListener{
    private static final Logger logger = LoggerFactory.getLogger(DivCabinFilter.class);

    static Map<String,Map<String,String>> divCabinMap=new HashMap<>();

    @Override
    public void actionPerformed(){
        Map<String,String> map=HotDeployManager.getPriceFilter("divCabin");

        if (map!=null){
            Set set=map.entrySet();
            Map<String,Map<String,String>> divCabinGetMap=new HashMap<>();
            for (Iterator iterator=set.iterator();iterator.hasNext();){
                Map.Entry entry=(Map.Entry)iterator.next();
                String configKey=(String)entry.getKey();
                String divCabin=(String)entry.getValue();
                Map<String,String> forbidresult=forbidDivCabin(divCabin);
                divCabinGetMap.put(configKey,forbidresult);
            }
            divCabinMap=divCabinGetMap;
        }
    }
}

很多的知识不是会了就会了,在自己的脑子里存着是一回事,能在特定的业务场景下能用上是另一回事。有些知识没用时觉得难,但是用过了之后就觉得真的不是很难。多实践。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2016年12月18日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 被观察者
  • 观察者
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档