java 观察者模式类图_Java 设计模式之观察者模式

本文详细介绍了Java设计模式中的观察者模式,又称发布订阅模式,及其在GUI系统和订阅发布系统中的常见应用。文章通过一个Android界面实例展示了如何使用观察者模式,使UI层与业务逻辑解耦。内容包括被观察者(Subject)、具体被观察者(ConcreteSubject)、观察者(Observer)和具体观察者(ConcreteObserver)的角色定义,以及模式在实际代码中的实现。
摘要由CSDN通过智能技术生成

摘要:

本篇主要讲Java设计模式之观察者模式。

[TOC]

​ 当心浮气躁时,告诫自己要静下心来,一步一步来,不要急不要燥。

​ 观察者模式也叫做发布订阅模式,是一种行为型设计模式。观察者模式最常用的地方是GUI系统、订阅---------发布系统。尤其是GUI系统,使用观察者模式可以使UI层与业务逻辑解耦。

​ 定义对象间一种一对多的依赖关系,使得每当一个对象改变状态。则所有依赖于它的对象都会得到通知并被自动更新。

关联行为场景

需要注意的是,关联行为是可以拆分的,并不是“组合”关系。

事件多级触发场景。

跨系统的消息交换场景,如消息队列、事件总线的处理机制。

d1d27d9dfb9edda8da2729cb95353298.png

说明:

Subject

被观察者,一般是抽象类或者是实现类,主要功能是管理观察者(动态的增加、取消观察者)并且通知观察者。

ConCreteSubject

具体的被观察者,定义被观察者自己的业务逻辑,同时定义对哪些事件进行通知。

Observer

观察者,一般是抽象类或者是实现类,对接收到的信息进行处理。

ConcreteObserver

具体的观察者,通过接收的信息,实现各个观察者自己的业务逻辑。

​ 现在有这样一个功能需求:在Android的一个界面上,有三个控件,分别为Edittext,TextView,ImageView,当EditText按下键盘的回车键(或者确认键)时,TextView显示EditText输入的文字,ImageView根据输入的文字显示相应的图片。如果运用观察者模式去做的话,EditText是被观察者,TextView和ImageView是观察者,当EditText输入的时候按下回车键,ImageView和TextView通过接受的信息根据自己的业务逻辑进行相应的处理。下面就让我们来实现一下。

重写EditText,使其成为被观察者

package com.yf.designpatternandroid;

import android.content.Context;

import android.util.AttributeSet;

import android.view.KeyEvent;

import android.view.inputmethod.EditorInfo;

import android.widget.EditText;

import android.widget.TextView;

import java.util.Observable;

import java.util.Observer;

/**

* Created by iuni.life on 16/9/7.

* yangfei's computer.

*/

public class MyEditText extends EditText {

//使用内部类的方式实现被观察者

private Content content;

public MyEditText(Context context) {

super(context);

}

public MyEditText(final Context context, AttributeSet attrs) {

super(context, attrs);

content = new Content();

//对输入的内容进行监听

setOnEditorActionListener(new OnEditorActionListener() {

@Override

public boolean onEditorAction(TextView textView, int i, KeyEvent keyEvent) {

if (i == EditorInfo.IME_ACTION_SEARCH || i == EditorInfo.IME_ACTION_DONE ||

keyEvent.getAction() == KeyEvent.ACTION_DOWN &&

keyEvent.getAction() == KeyEvent.KEYCODE_ENTER) {

//触发各个Observer

content.setEditTextContent(getText().toString());

}

return false;

}

});

}

public MyEditText(Context context, AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

}

/**

* 添加观察者

*

* @param observer

*/

public void addObserver(Observer observer) {

content.addObserver(observer);

}

//被观察者需要继承Observable

private class Content extends Observable {

private String editTextContent;

public void setEditTextContent(String editTextContent) {

this.editTextContent = editTextContent;

//标识状态或者内容发生改变

setChanged();

//通知所有的观察者

notifyObservers(editTextContent);

}

}

}

复制代码

重写TextView,使其成为观察者

package com.yf.designpatternandroid;

import android.content.Context;

import android.util.AttributeSet;

import android.util.Log;

import android.widget.TextView;

import java.util.Observable;

import java.util.Observer;

/**

* Created by iuni.life on 16/9/7.

* yangfei's computer.

* 观察者需要实现接口Observer,并在update方法中实现业务逻辑

*/

public class MyTextView extends TextView implements Observer {

public MyTextView(Context context) {

super(context);

}

public MyTextView(Context context, AttributeSet attrs) {

super(context, attrs);

}

public MyTextView(Context context, AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

}

@Override

public void update(Observable observable, Object o) {

Log.d("MyTextView", "Observer:MyTextView收到通知:" + o);

setText(o.toString());

}

}

复制代码

重写ImageView,使其成为观察者

package com.yf.designpatternandroid;

import android.content.Context;

import android.media.Image;

import android.util.AttributeSet;

import android.util.Log;

import android.widget.ImageView;

import java.util.Observable;

import java.util.Observer;

/**

* Created by iuni.life on 16/9/7.

* yangfei's computer.

* 观察者需要实现接口Observer,并在update方法中实现业务逻辑

*/

public class MyImageView extends ImageView implements Observer {

public MyImageView(Context context) {

super(context);

}

public MyImageView(Context context, AttributeSet attrs) {

super(context, attrs);

}

public MyImageView(Context context, AttributeSet attrs, int defStyleAttr) {

super(context, attrs, defStyleAttr);

}

@Override

public void update(Observable observable, Object o) {

Log.d("MyImageView", "Observer:MyImageView收到通知:" + o);

String content = o.toString();

if (o.equals("iuni")) {

setImageResource(R.mipmap.ic_launcher);

} else {

setImageResource(R.mipmap.test);

}

}

}

复制代码

在布局文件中引用重写的三个控件

复制代码

测试代码

package com.yf.designpatternandroid;

import android.support.v7.app.AppCompatActivity;

import android.os.Bundle;

import android.view.View;

import android.widget.AutoCompleteTextView;

import android.widget.ImageView;

import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

private MyEditText myEditText;

private MyTextView myTextView;

private MyImageView myImageView;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

myEditText = (MyEditText) findViewById(R.id.id_et);

myImageView = (MyImageView) findViewById(R.id.id_iv);

myTextView = (MyTextView) findViewById(R.id.id_tv);

myEditText.addObserver(myImageView);

myEditText.addObserver(myTextView);

}

}

复制代码

效果展示

ecd14161239154069a1a917b38360ecc.gif

观察者和被观察者之间是抽象耦合。

可以建立一套触发机制。

增强系统的灵活性,可拓展性。

一个被观察者,多个观察者,开发效率和运行效率需要考虑。

一个被观察者,多个观察者,调试比较复杂。

Java中的消息通知默认是顺序执行,一个观察者卡壳,会影响整体的执行效率。(这种情况一般会采取异步的方式处理)

​ 文章不足之处,望大家多多指点,共同学习,共同进步。

<> 秦小波 著

若想获得更好阅读体验,请访问个人博客网站:iuni.life

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值