设计模式之观察者

本文介绍了一种使用观察者模式实现回调机制的方案,通过具体的微信公众号开发案例,展示了如何利用该模式更新接口调用凭证(AccessToken),并在多公众号环境下进行数据库操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

当对象间存在一对多关系时,则使用观察者模式(Observer Pattern)。意图:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。主要解决:一个对象状态改变给其他对象通知的问题,而且要考虑到易用和低耦合,保证高度的协作。使用:一个对象(目标对象)的状态发生改变,所有的依赖对象(观察者对象)都将得到通知,进行广播通知。观察者模式属于行为型模式。

示例

观察者模式使用三个类 Subject、Observer 和 Client。Subject 对象带有绑定观察者到 Client 对象和从 Client 对象解绑观察者的方法。我们创建 Subject 类、Observer 抽象类和扩展了抽象类 Observer 的实体类。
ObserverPatternDemo,我们的演示类使用 Subject 和实体类对象来演示观察者模式。
这里写图片描述

观察着模式在平常开发中,有可能各位博友有引用到,只是自己没发现而已,博主在这就以项目实例来进行说明。
场景介绍:
微信公众号开发,获取接口调用凭证AccessToken,AccessToken的expires_in凭证有效时间(expires_in-当前时间>0),此时需要对AccessToken入库,AccessToken失效重新获取并更新数据库(AccessToken入库一般在服务器对于多公众号支持时)。

第一步定义Subject

清除的知道Subject的作用:Subject 对象带有绑定观察者到 Client 对象和从 Client 对象解绑观察者的方法
WxConfig微信基本参数配置类,需单例

package com.bigbigbu.wx.tools.api;

import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

import com.bigbigbu.wx.tools.bean.WxAccessToken;
import com.bigbigbu.wx.tools.exception.WxErrorException;
import com.bigbigbu.wx.tools.util.StringUtils;

/**
* <p>Title: WxAccessToken</p>
* <p>Description:  微信全局配置对象-从配置文件读取,原作者antgan于2016/12/14码</p>
* <p>Company: BIGBIGBU</p>
* @author    FANQIBU 
* @date       2017年12月7日
*/
public class WxConfig {
    private static WxConfig config = null;
    //内存更新
    private volatile String accessToken;
    private  volatile  long expiresTime;
    //多公众号模式下自定义系统回调===========重点==观察者模式=============
    private  IWxManySysService wxManySysService;
    /**   
     * @Title:  WxConfig   
     * @Description:    FANQIBU 动态加载配置文件   
     * @param:    
     * @throws   
     */  
    public WxConfig() {
    }
    /**
     * 同步获取/加载单例
     * @return
     */
    public static synchronized WxConfig getInstance(){
        if(config == null){
            config = new WxConfig();
        }
        return config;
    }
    /**
     * 同步获取/加载单例
     * @return
     */
    public static synchronized void refreshInstance(){
        config = new WxConfig();
    }
    public String getAccessToken() {
        return accessToken;
    }
    public boolean isAccessTokenExpired() {
        return System.currentTimeMillis() > this.expiresTime;
    }
    public void expireAccessToken() {
        this.expiresTime = 0;
    }
    /**
    * <p>Title: updateAccessToken</p>
    * <p>Description: 更新接口调用凭证</p>
    * @param WxAccessToken accessToken
    * @param boolean       isCallback   是否调用系统回调
    */
    public synchronized void updateAccessToken(WxAccessToken accessToken,boolean isCallback) {
        updateAccessToken(accessToken.getAccess_token(), accessToken.getExpires_in(),isCallback);
    }
    /**
    * <p>Title: updateAccessToken</p>
    * <p>Description: FANQIBU修改更新接口调用凭证</p>
    * @param String accessToken
    * @param long       expiresInSeconds
    * @param boolean isCallback   是否调用系统回调
    */
    public synchronized void updateAccessToken(String accessToken, long expiresInSeconds,boolean isCallback) {
        this.accessToken = accessToken;
        this.expiresTime = System.currentTimeMillis() + (expiresInSeconds - 200) * 1000l;
        //调用微信WxSysCallback
        if(this.getWxManySysService()!=null && isCallback){
            //微信刷新access_token接口调用凭证回调(PS:针对多公众号情况下access_token更新入库操作)(在这里了)
            //通知更新access_token啦。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
            this.getWxManySysService().wxAccessTokenCallback(this.accessToken, this.expiresTime);
        }
    }
    public IWxManySysService getWxManySysService() {
        return wxManySysService;
    }
    public void setWxManySysService(IWxManySysService wxManySysService) {
        this.wxManySysService = wxManySysService;
    }
}

第二步定义Observer

/**
* <p>Title: IWxManySysService</p>
* <p>Description: 多公众号模式下动态加载配置信息和接口调用凭证access_token更新</p>
* <p>Company: DINGGE</p>
* @author    FANQIBU
* @date       2017年12月7日
*/
public interface IWxManySysService {
    /**
    * <p>Title: wxAccessTokenCallback</p>
    * <p>Description: 微信刷新access_token接口调用凭证回调(PS:一般针对多公众号情况下access_token更新入库操作)</p>
    * @param accessToken
    * @param expiresInSeconds
    */
    public void wxAccessTokenCallback(String accessToken, long expiresInSeconds);
    /**
     * <p>Title: loadWxProperties</p>
     * <p>Description:多公众号动态加载微信配置参数 </p>
     * @param String wxsystoken 本地系统wx令牌(从数据库查找当前公众号配置参数)
     */
    public default boolean loadWxProperties(String newwxsystoken){
        if(StringUtils.isEmpty(newwxsystoken)){
            return false;
        }
        try {
                //WxConfig微信基本参数配置类,需单例
                WxConfig.refreshInstance();
                //=============绑定观察者=======重点在这里==================
                WxConfig.getInstance().setWxManySysService(this);
            }else{
                return false;
            }
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
        return true;
    }
}
package com.lh.wx.service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.inject.Inject;

import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;

import com.lh.wx.dao.WeixinAccessTokenMapper;
import com.lh.wx.dao.WeixinConfigMapper;
import com.lh.wx.model.WeixinAccessTokenDto;
import com.lh.wx.servlet.InitServlet;
import com.bigbigbu.wx.tools.api.IWxManySysService;
import com.bigbigbu.wx.tools.bean.WxAccessToken;
import com.bigbigbu.wx.tools.bean.many.WxBaseConfig;

/**
* <p>Title: WxSysCallback</p>
* <p>Description: 自定义系统回调</p>
* <p>Company: DINGGE</p>
* @author    FANQIBU
* @date       2017年12月7日
*/
@Service
public class WxManySysService implements IWxManySysService{
    private @Inject WeixinConfigMapper weixinConfigMapper;
    private @Inject WeixinAccessTokenMapper weixinAccessTokenMapper;
    private  @Inject  Environment  environment;
    @Override
    public void wxAccessTokenCallback(String accessToken, long expiresInSeconds) {
        //会通知这里
        //更新数据库AccessToken
    }
}

第三步简单使用

package com.lh.wx.service;

import javax.inject.Inject;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;

@Service
public class WechatService {
     private  @Inject  Environment  environment;
    private @Inject WxManySysService wxManySysService;
    public boolean loadWxSysConfigure(String wxsystoken,boolean isMust){
       //调用绑定观察者
        wxManySysService.loadWxProperties(wxsystoken,environment.getProperty("wx.wxsystoken"));
    }
}

本文博主只是在简单一对一条件下,使用观察者模式模式实现回调。详细请参阅菜鸟教程,本文头部介绍均引用自菜鸟教程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值