0

0

用Java设计模式中的观察者模式开发微信公众号的实例代码

高洛峰

高洛峰

发布时间:2017-03-28 14:20:33

|

1979人浏览过

|

来源于php中文网

原创

UQ云商B2B2C系统
UQ云商B2B2C系统

UQCMS云商是一款B2B2C电子商务软件 ,非常适合初创的创业者,个人及中小型企业。程序采用PHP+MYSQL,模板采用smarty模板,二次开发,简单方便,无需学习其他框架就可以自行模板设计。永久免费使用,操作简单,安全稳定。支持PC+WAP+微信三种浏览方式,支持微信公众号。

下载

这篇文章主要介绍了用java设计模式中的观察者模式开发微信公众号的例子,这里java的微信sdk等部分便不再详述,只注重关键部分和开发过程中观察者模式优点的体现,需要的朋友可以参考下

还记得警匪片上,匪徒们是怎么配合实施犯罪的吗?一个团伙在进行盗窃的时候,总有一两个人在门口把风——如果有什么风吹草动,则会立即通知里面的同伙紧急撤退。也许放风的人并不一定认识里面的每一个同伙;而在里面也许有新来的小弟不认识这个放风的。但是这没什么,这个影响不了他们之间的通讯,因为他们之间有早已商定好的暗号。
呵呵,上面提到的放风者、偷窃者之间的关系就是观察者模式在现实中的活生生的例子。

观察者(Observer)模式又名发布-订阅(Publish/Subscribe)模式。GOF给观察者模式如下定义:定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。
在这里先讲一下面向对象设计的一个重要原则——单一职责原则。因此系统的每个对象应该将重点放在问题域中的离散抽象上。因此理想的情况下,一个对象只做一件事情。这样在开发中也就带来了诸多的好处:提供了重用性和维护性,也是进行重构的良好的基础。
因此几乎所有的设计模式都是基于这个基本的设计原则来的。观察者模式的起源我觉得应该是在GUI和业务数据的处理上,因为现在绝大多数讲解观察者模式的例子都是这一题材。但是观察者模式的应用决不仅限于此一方面。


好了,对于定义的理解总是需要实例来解析的,如今的微信服务号相当火啊,下面就以微信服务号为背景,给大家介绍观察者模式。
看一张图:

用Java设计模式中的观察者模式开发微信公众号的实例代码

其中每个使用者都有上图中的3条线,为了使图片清晰省略了。
如上图所示,服务号就是我们的主题,使用者就是观察者。现在我们明确下功能:
1、服务号就是主题,业务就是推送消息
2、观察者只需要订阅主题,只要有新的消息就会送来
3、当不想要此主题消息时,取消订阅
4、只要服务号还在,就会一直有人订阅
好了,现在我们来看看观察者模式的类图:

用Java设计模式中的观察者模式开发微信公众号的实例代码

接下来就是代码时间了,我们模拟一个微信3D彩票服务号,和一些订阅者。
首先开始写我们的主题接口,和观察者接口:

package com.zhy.pattern.observer; 
 
/** 
 * 主题接口,所有的主题必须实现此接口 
 * 
 * @author zhy 
 * 
 */ 
public interface Subject 
{ 
  /** 
   * 注册一个观察着 
   * 
   * @param observer 
   */ 
  public void registerObserver(Observer observer); 
 
  /** 
   * 移除一个观察者 
   * 
   * @param observer 
   */ 
  public void removeObserver(Observer observer); 
 
  /** 
   * 通知所有的观察着 
   */ 
  public void notifyObservers(); 
 
} 
package com.zhy.pattern.observer; 
 
/** 
 * @author zhy 所有的观察者需要实现此接口 
 */ 
public interface Observer 
{ 
  public void update(String msg); 
 
}

接下来3D服务号的实现类:

package com.zhy.pattern.observer; 
 
import java.util.ArrayList; 
import java.util.List; 
 
public class ObjectFor3D implements Subject 
{ 
  private List<Observer> observers = new ArrayList<Observer>(); 
  /** 
   * 3D彩票的号码 
   */ 
  private String msg; 
 
  @Override 
  public void registerObserver(Observer observer) 
  { 
    observers.add(observer); 
  } 
 
  @Override 
  public void removeObserver(Observer observer) 
  { 
    int index = observers.indexOf(observer); 
    if (index >= 0) 
    { 
      observers.remove(index); 
    } 
  } 
 
  @Override 
  public void notifyObservers() 
  { 
    for (Observer observer : observers) 
    { 
      observer.update(msg); 
    } 
  } 
 
  /** 
   * 主题更新消息 
   * 
   * @param msg 
   */ 
  public void setMsg(String msg) 
  { 
    this.msg = msg; 
     
    notifyObservers(); 
  } 
 
}

模拟两个使用者:

package com.zhy.pattern.observer; 
 
public class Observer1 implements Observer 
{ 
 
  private Subject subject; 
 
  public Observer1(Subject subject) 
  { 
    this.subject = subject; 
    subject.registerObserver(this); 
  } 
 
  @Override 
  public void update(String msg) 
  { 
    System.out.println("observer1 得到 3D 号码 -->" + msg + ", 我要记下来。"); 
  } 
 
}
package com.zhy.pattern.observer; 
 
public class Observer2 implements Observer 
{ 
  private Subject subject ;  
   
  public Observer2(Subject subject) 
  { 
    this.subject = subject ; 
    subject.registerObserver(this); 
  } 
   
  @Override 
  public void update(String msg) 
  { 
    System.out.println("observer2 得到 3D 号码 -->" + msg + "我要告诉舍友们。"); 
  } 
   
   
 
}

可以看出:服务号中维护了所有向它订阅消息的使用者,当服务号有新消息时,通知所有的使用者。整个架构是一种松耦合,主题的实现不依赖与使用者,当增加新的使用者时,主题的代码不需要改变;使用者如何处理得到的数据与主题无关;
最后看下测试代码:

package com.zhy.pattern.observer.test; 
 
import com.zhy.pattern.observer.ObjectFor3D; 
import com.zhy.pattern.observer.Observer; 
import com.zhy.pattern.observer.Observer1; 
import com.zhy.pattern.observer.Observer2; 
import com.zhy.pattern.observer.Subject; 
 
public class Test 
{ 
  public static void main(String[] args) 
  { 
    //模拟一个3D的服务号 
    ObjectFor3D subjectFor3d = new ObjectFor3D(); 
    //客户1 
    Observer observer1 = new Observer1(subjectFor3d); 
    Observer observer2 = new Observer2(subjectFor3d); 
 
    subjectFor3d.setMsg("20140420的3D号码是:127" ); 
    subjectFor3d.setMsg("20140421的3D号码是:333" ); 
     
  } 
}

输出结果:

observer1 得到 3D 号码 -->20140420的3D号码是:127, 我要记下来。 
observer2 得到 3D 号码 -->20140420的3D号码是:127我要告诉舍友们。 
observer1 得到 3D 号码 -->20140421的3D号码是:333, 我要记下来。 
observer2 得到 3D 号码 -->20140421的3D号码是:333我要告诉舍友们。

对于JDK或者Andorid中都有很多地方实现了观察者模式,比如XXXView.addXXXListenter , 当然了 XXXView.setOnXXXListener不一定是观察者模式,因为观察者模式是一种一对多的关系,对于setXXXListener是1对1的关系,应该叫回调。

恭喜你学会了观察者模式,上面的观察者模式使我们从无到有的写出,当然了java中已经帮我们实现了观察者模式,借助于java.util.Observable和java.util.Observer。
下面我们使用Java内置的类实现观察者模式:

首先是一个3D彩票服务号主题:

package com.zhy.pattern.observer.java; 
 
import java.util.Observable; 
 
public class SubjectFor3d extends Observable 
{ 
  private String msg ;  
   
   
  public String getMsg() 
  { 
    return msg; 
  } 
 
 
  /** 
   * 主题更新消息 
   * 
   * @param msg 
   */ 
  public void setMsg(String msg) 
  { 
    this.msg = msg ; 
    setChanged(); 
    notifyObservers(); 
  } 
}

下面是一个双色球的服务号主题:

package com.zhy.pattern.observer.java; 
 
import java.util.Observable; 
 
public class SubjectForSSQ extends Observable 
{ 
  private String msg ;  
   
   
  public String getMsg() 
  { 
    return msg; 
  } 
 
 
  /** 
   * 主题更新消息 
   * 
   * @param msg 
   */ 
  public void setMsg(String msg) 
  { 
    this.msg = msg ; 
    setChanged(); 
    notifyObservers(); 
  } 
}

最后是我们的使用者:

package com.zhy.pattern.observer.java; 
 
import java.util.Observable; 
import java.util.Observer; 
 
public class Observer1 implements Observer 
{ 
 
  public void registerSubject(Observable observable) 
  { 
    observable.addObserver(this); 
  } 
 
  @Override 
  public void update(Observable o, Object arg) 
  { 
    if (o instanceof SubjectFor3d) 
    { 
      SubjectFor3d subjectFor3d = (SubjectFor3d) o; 
      System.out.println("subjectFor3d's msg -- >" + subjectFor3d.getMsg()); 
    } 
 
    if (o instanceof SubjectForSSQ) 
    { 
      SubjectForSSQ subjectForSSQ = (SubjectForSSQ) o; 
      System.out.println("subjectForSSQ's msg -- >" + subjectForSSQ.getMsg()); 
    } 
  } 
}

看一个测试代码:

package com.zhy.pattern.observer.java; 
 
public class Test 
{ 
  public static void main(String[] args) 
  { 
    SubjectFor3d subjectFor3d = new SubjectFor3d() ; 
    SubjectForSSQ subjectForSSQ = new SubjectForSSQ() ; 
     
    Observer1 observer1 = new Observer1(); 
    observer1.registerSubject(subjectFor3d); 
    observer1.registerSubject(subjectForSSQ); 
     
     
    subjectFor3d.setMsg("hello 3d'nums : 110 "); 
    subjectForSSQ.setMsg("ssq'nums : 12,13,31,5,4,3 15"); 
     
  } 
}

测试结果:

subjectFor3d's msg -- >hello 3d'nums : 110  
subjectForSSQ's msg -- >ssq'nums : 12,13,31,5,4,3 15

可以看出,使用Java内置的类实现观察者模式,代码非常简洁,对了addObserver,removeObserver,notifyObservers都已经为我们实现了,所有可以看出Observable(主题)是一个类,而不是一个接口,基本上书上都对于Java的如此设计抱有反面的态度,觉得Java内置的观察者模式,违法了面向接口编程这个原则,但是如果转念想一想,的确你拿一个主题在这写观察者模式(我们自己的实现),接口的思想很好,但是如果现在继续添加很多个主题,每个主题的ddObserver,removeObserver,notifyObservers代码基本都是相同的吧,接口是无法实现代码复用的,而且也没有办法使用组合的模式实现这三个方法的复用,所以我觉得这里把这三个方法在类中实现是合理的。

微信app下载
微信app下载

微信是一款手机通信软件,支持通过手机网络发送语音短信、视频、图片和文字。微信可以单聊及群聊,还能根据地理位置找到附近的人,带给大家全新的移动沟通体验,有需要的小伙伴快来保存下载体验吧!

下载

相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
Swift iOS架构设计与MVVM模式实战
Swift iOS架构设计与MVVM模式实战

本专题聚焦 Swift 在 iOS 应用架构设计中的实践,系统讲解 MVVM 模式的核心思想、数据绑定机制、模块拆分策略以及组件化开发方法。内容涵盖网络层封装、状态管理、依赖注入与性能优化技巧。通过完整项目案例,帮助开发者构建结构清晰、可维护性强的 iOS 应用架构体系。

3

2026.03.03

C++高性能网络编程与Reactor模型实践
C++高性能网络编程与Reactor模型实践

本专题围绕 C++ 在高性能网络服务开发中的应用展开,深入讲解 Socket 编程、多路复用机制、Reactor 模型设计原理以及线程池协作策略。内容涵盖 epoll 实现机制、内存管理优化、连接管理策略与高并发场景下的性能调优方法。通过构建高并发网络服务器实战案例,帮助开发者掌握 C++ 在底层系统与网络通信领域的核心技术。

12

2026.03.03

Golang 测试体系与代码质量保障:工程级可靠性建设
Golang 测试体系与代码质量保障:工程级可靠性建设

Go语言测试体系与代码质量保障聚焦于构建工程级可靠性系统。本专题深入解析Go的测试工具链(如go test)、单元测试、集成测试及端到端测试实践,结合代码覆盖率分析、静态代码扫描(如go vet)和动态分析工具,建立全链路质量监控机制。通过自动化测试框架、持续集成(CI)流水线配置及代码审查规范,实现测试用例管理、缺陷追踪与质量门禁控制,确保代码健壮性与可维护性,为高可靠性工程系统提供质量保障。

69

2026.02.28

Golang 工程化架构设计:可维护与可演进系统构建
Golang 工程化架构设计:可维护与可演进系统构建

Go语言工程化架构设计专注于构建高可维护性、可演进的企业级系统。本专题深入探讨Go项目的目录结构设计、模块划分、依赖管理等核心架构原则,涵盖微服务架构、领域驱动设计(DDD)在Go中的实践应用。通过实战案例解析接口抽象、错误处理、配置管理、日志监控等关键工程化技术,帮助开发者掌握构建稳定、可扩展Go应用的最佳实践方法。

59

2026.02.28

Golang 性能分析与运行时机制:构建高性能程序
Golang 性能分析与运行时机制:构建高性能程序

Go语言以其高效的并发模型和优异的性能表现广泛应用于高并发、高性能场景。其运行时机制包括 Goroutine 调度、内存管理、垃圾回收等方面,深入理解这些机制有助于编写更高效稳定的程序。本专题将系统讲解 Golang 的性能分析工具使用、常见性能瓶颈定位及优化策略,并结合实际案例剖析 Go 程序的运行时行为,帮助开发者掌握构建高性能应用的关键技能。

46

2026.02.28

Golang 并发编程模型与工程实践:从语言特性到系统性能
Golang 并发编程模型与工程实践:从语言特性到系统性能

本专题系统讲解 Golang 并发编程模型,从语言级特性出发,深入理解 goroutine、channel 与调度机制。结合工程实践,分析并发设计模式、性能瓶颈与资源控制策略,帮助将并发能力有效转化为稳定、可扩展的系统性能优势。

24

2026.02.27

Golang 高级特性与最佳实践:提升代码艺术
Golang 高级特性与最佳实践:提升代码艺术

本专题深入剖析 Golang 的高级特性与工程级最佳实践,涵盖并发模型、内存管理、接口设计与错误处理策略。通过真实场景与代码对比,引导从“可运行”走向“高质量”,帮助构建高性能、可扩展、易维护的优雅 Go 代码体系。

20

2026.02.27

Golang 测试与调试专题:确保代码可靠性
Golang 测试与调试专题:确保代码可靠性

本专题聚焦 Golang 的测试与调试体系,系统讲解单元测试、表驱动测试、基准测试与覆盖率分析方法,并深入剖析调试工具与常见问题定位思路。通过实践示例,引导建立可验证、可回归的工程习惯,从而持续提升代码可靠性与可维护性。

4

2026.02.27

漫蛙app官网链接入口
漫蛙app官网链接入口

漫蛙App官网提供多条稳定入口,包括 https://manwa.me、https

348

2026.02.27

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Kotlin 教程
Kotlin 教程

共23课时 | 4.1万人学习

C# 教程
C# 教程

共94课时 | 10.6万人学习

Java 教程
Java 教程

共578课时 | 76.5万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号