java设计模式之观察者模式

观察者模式定义

定义:Observer模式定义对象间的一对多的依赖关系,当一个对象(被观察者)的状态发生改变时, 所有依赖于它的对象(观察者)都得到通知并被自动更新,有时候观察者模式也被称为发布/订阅模式。

观察者模式主要包涵两个部分:
- observer 观察者,为所有的具体观察者定义一个接口,在得到主题通知时更新自己
- Observable 被观察者, 观察者随着被观察者的变化更新自己。

为什么要用观察者模式

  • 被观察者只需要知道观察者是谁,不需要知道两者之间具体的内容
  • 被观察者如果发生变化,就会立即通知观察者更新,只有通知和响应的处理
  • 一个观察者可以观察多个主题(多个被观察者),一个被观察者也可能有多个观察者,可以自由选择
  • 观察者可以通过被观察的变化随时做出响应

观察者模式特点

观察者模式所做的工作其实就是在接触耦合,让耦合的双方都依赖于抽象,而不是依赖于具体,从而使得各自的变化都不会影响另一边的变化。

实例

  • 首先是简单的观察者模式使用
    这里我们先设计场景,人和天气吧,根据天气的变化通知主人的出行工具
    这里我们模仿一个点击事件获取edittext的内容,如果是大雪就选择地铁出门

    一个观察者的抽象接口,含有更新数据的方法

/**
 * Created by melo on 2017/2/21.
 */
public interface People {

     void  upData(String string);
}

具体的人,这里给一个实体类小明,通过update方法得到结果

/**
 * Created by melo on 2017/2/21.
 */
public class XiaoMing  implements People {

    @Override
    public void upData(String string) {
        if ("大雪".equals(string)){
            Log.i("tag","今天大雪,建议地铁出行");
        }else if ("多云".equals(string)){
            Log.i("tag","今天多云,建议步行出门");
        }else if ("小雨".equals(string)){
            Log.i("tag","今天小雨,建议公交出门");
        }
    }
}

下面就是模拟被观察者,也就是天气

/**
 * Created by melo on 2017/2/21.
 */
public class Weather {
    private String weatherDetails;
    private People mPeople;

    public Weather(People people) {
        this.mPeople = people;

    }

    public String getWeatherDetails() {
        return weatherDetails;
    }

    public void setWeatherDetails(String weatherDetails) {
        this.weatherDetails = weatherDetails;
        //通知观察者数据改变
        this.notifyObserver(weatherDetails);

    }


    public void notifyObserver(String string) {
        mPeople.upData(string);
    }
}

放上mainactivity,也很简单

/**
 * 简单观察者模式实例
 */
public class MainActivity extends AppCompatActivity{
    EditText mEditText;
    Button mButton;
    TextView mTextView;
    Weather weather;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mEditText = (EditText) findViewById(R.id.et_input);
        mButton = (Button) findViewById(R.id.btn_chang);
        mTextView = (TextView) findViewById(R.id.tv_newweather);

        XiaoMing xiaoMing=new XiaoMing();
        weather = new Weather(xiaoMing);


        mButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String newWeather = mEditText.getText().toString();
                Log.i("tag", "newWeather:" + newWeather);
                weather.setWeatherDetails(newWeather);
            }
        });
    }

}

接下来就不妨来测试一下输出的结果吧。
这里写图片描述


通过上面的例子可以了解到观察者模式其实也不是很难吧,下面就用更深入的实例来学习观察者模式。

首先我们分析总共需要几部分组成:
1.我们需要一个subject类,可翻译为主题或抽象通知者

/**
 * Created by melo on 2017/2/21.
 * subject类,可翻译为主题或抽象通知者,一般用一个抽象类或者一个接口实现,
 * 它把所以对观察者对象的引用保存在一个聚焦里,每个主题都可以有任何数量的观察者。
 * 抽象主题提供一个接口,可以增加和删除观察者对象
 */
abstract class Subject {
    private List<Observer> mObservers = new LinkedList<>();

    //添加观察者
    public void addObserver(Observer observer) {
        mObservers.add(observer);
    }

    //删除观察者
    public void deleteObserver(Observer observer) {
        mObservers.remove(observer);
    }


    public void notifyObservers() {
        for (Observer observer : mObservers) {
            observer.upDate();
        }
    }
}

2.有了subject抽象通知类,我们就需要为所有观察者定义一个接口类,用来更新自己

/**
 * Created by melo on 2017/2/21.
 * 抽象观察者,为所有具体观察者定义一个接口,得到主题的通知时更新自己。这个接口叫做更新接口
 *
 */
public interface Observer {

    void upDate();
}

3.创建一个ConcreteSubject存入观察者对象的状态

/**
 * Created by melo on 2017/2/21.
 * 叫做具体主题或具体通知者,将有关状态存入具体观察者对象
 */
public class ConcreteSubject extends Subject {

    //具体被观察者的状态
    private String subjectState;

    public String getSubjectState() {
        return subjectState;
    }

    public void setSubjectState(String subjectState) {
        this.subjectState = subjectState;
    }
}

4.到这里我们就可以创建具体的观察者

/**
 * Created by melo on 2017/2/21.
 * 具体观察者,实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态一致。
 */
public class ConcreteObserver implements Observer {

    private String name;
    private String observerState;
    private ConcreteSubject subject;

    public ConcreteObserver(String name, ConcreteSubject subject) {
        this.name = name;
        this.subject = subject;
    }


    @Override
    public void upDate() {
        observerState = subject.getSubjectState();
        Log.i("tag", "name:" + name + ",observerState:" + observerState);


    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public ConcreteSubject getSubject() {
        return subject;
    }

    public void setSubject(ConcreteSubject subject) {
        this.subject = subject;
    }
}

5.现在在mainactivity中运行,并看一看输出的结果

//观察者模式
public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        ConcreteSubject concreteSubject=new ConcreteSubject();
        ConcreteObserver observer=new ConcreteObserver("观察者1",concreteSubject);
        concreteSubject.addObserver(observer);

        ConcreteObserver observer2=new ConcreteObserver("观察者2",concreteSubject);
        concreteSubject.addObserver(observer2);

        concreteSubject.setSubjectState("心情很好");
        concreteSubject.notifyObservers();

    }
}

这里写图片描述


参考来源

  • 大话设计模式
  • Android开发艺术探索
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值