行为模式一、策略模式、观察者模式

文章目录

  • 策略模式
    • 策略模式的结构
    • 策略模式的角色和职责
    • 代码
    • 策略模式的优点
    • 策略模式缺点
  • 观察者模式
    • 观察者模式的结构
    • 气象站的例子
    • Java内置的观察者模式如何运作
      • 如何把对象变成观察者
      • 如何给观察者送出通知
      • 观察者如何接收通知
      • 利用内置的支持重做气象站

策略模式

策略模式是行为模式的一种,他对一系列的算法加以封装,为所有算法定义一个抽象的算法接口,并通过继承该算法接口对所有的算法加以封装和实现,具体的算法选择交给客户端决定(策略)。

定义一系列的算法,把它们一个个封装起来, 并且使它们可相互替换。

策略模式的结构

行为模式一、策略模式、观察者模式_第1张图片

策略模式的角色和职责

行为模式一、策略模式、观察者模式_第2张图片

代码

public interface Strategy
{
    //加密
    public void encrypt();
}
class MDSStrategy implements Strategy {
    @Override
    public void encrypt() {
        System.out.println("执行MDS加密");
    }
}
class MD5Strategy implements Strategy {
    @Override
    public void encrypt()
    {
        System.out.println("执行MD5加密");
    }

}

class Context
{
    private Strategy strategy;
    public Context(Strategy strategy)
    {
        this.strategy = strategy;
    }

    public void operation()
    {
        strategy.encrypt();
    }
}

public class MainClass
{
    public static void main(String[] args) {
//        Strategy stra = new MD5Strategy();
//        stra.encrypt();
        Context context = new Context(new MD5Strategy());
        context.operation();
    }
}

策略模式的优点

行为模式一、策略模式、观察者模式_第3张图片

策略模式缺点

行为模式一、策略模式、观察者模式_第4张图片

观察者模式

Observer模式是行为模式的一种,它的作用是当一个对象的状态发生变化的时候,能够自动通知其他关联对象,自动刷新对象状态。

Observer模式提供给关联对象一种同步通信的手段,使得某个对象与依赖它的其他对象之间保持状态同步。

观察者模式的结构

行为模式一、策略模式、观察者模式_第5张图片行为模式一、策略模式、观察者模式_第6张图片

气象站的例子

观察者里面有主题对象,创建的时候传入主题对象,注册到主题。
主题中有观察者的列表,当有数据修改的时候,会遍历列表,通知所有的观察者。

行为模式一、策略模式、观察者模式_第7张图片

package Observer;
import java.util.ArrayList;
interface Subject  //出版者即主题,主题需要实现的接口
{
    public void registerObserver(Object o);  //观察者注册
    public void removeObserver(Object o);   //观察者撤销注册
    public void notifyObservers();   //通知观察者
}
interface Observer
{
    public void update(float temp,float humidity,float pressure);
}

interface DisplayElement
{
    public void display();
}

class CurrentConditionsDisplay implements Observer, DisplayElement  //观察者实现
{
    private float tempature;
    private float humidity;
    private Subject weatherData;

    public CurrentConditionsDisplay(Subject weatherData)   //观察者在创建的时候就会注册到主题中
    {
        this.weatherData = weatherData;
        weatherData.registerObserver(this);
    }

    @Override
    public void update(float temp, float humidity, float pressure) 
    {
        this.tempature = temp;
        this.humidity = humidity;
        display();
    }

    @Override
    public void display()
    {
        System.out.println("Current conditions:"+tempature+"F degrees and"+humidity+"% humidity");

    }
}

class WeatherData implements Subject
{
    private ArrayList observers;
    private float temperature;
    private float humidity;
    private float pressure;

    public WeatherData()
    {
        observers = new ArrayList();
    }

    @Override
    public void registerObserver(Object o)
    {
        observers.add(o);
    }

    @Override
    public void removeObserver(Object o)
    {
        int i = observers.indexOf(o);
        if(i>=0)
        {
            observers.remove(i);
        }
    }


    @Override
    public void notifyObservers()
    {
        for (int i=0;i<observers.size();i++)
        {
            Observer observer = (Observer)observers.get(i);
            observer.update(temperature,humidity,pressure);
        }
    }

    public void measurementsChanged()
    {
        notifyObservers();
    }
    public void setMeasurements(float temperature,float humidity,float pressure)
    {
        this.temperature = temperature;
        this.humidity = humidity;
        this.pressure = pressure;
        measurementsChanged();
    }
}
public class WeatherStation
{
    public static void main(String[] args)
    {
        WeatherData weatherData = new WeatherData();
        CurrentConditionsDisplay currentConditionsDisplay = new CurrentConditionsDisplay(weatherData);  //观察者注册到主题
        weatherData.setMeasurements(80,65,30.4f); //主题改变会触发所有的观察者的update方法。
        weatherData.setMeasurements(82,70,30.4f);
    }
}

Java内置的观察者模式如何运作

Java内置的观察者模式运作方式,和我们在气象站中的实现类似,但是有一些差异,最明显的差异是WeatherData(也就是我们的主题)现在可以扩展自Observable类,并继承到一些增加、删除、通知观察者的方法(以及其他的方法)。

如何把对象变成观察者

如同以前一样,实现观察者接口(java.util.Observer),然后调用任何Observable对象的addObserver()方法。不想再当观察者,调用deleteObserver()
方法就可以了。

如何给观察者送出通知

首先,你要利用扩展java.util.Observable接口产生"可观察者"类,然后,需要两个步骤:

  • 1、先调用setChanged()方法,标记状态已经改变的事实。
  • 2、然后调用两种notifyObserver()方法中的一个。
    notifyObservers()或者notifyObservers(Object arg)

观察者如何接收通知

同以前一样,观察者实现了更新的方法,但是签名不太一样:
update(Observable o,Object arg)
如果你想推数据给观察者,你可以把数据当作数据对象送给notifyObservers(arg)方法,否则,观察者就必须从观察者对象中拉数据。如何拉数据?我
们再做一遍气象站,你就会知道了。

利用内置的支持重做气象站

import java.util.Observable;
import java.util.Observer;

interface DisplayElement
{
    public void display();
}
class WeatherData extends Observable    //主题
{
    private float temperature;
    private float humidity;
    private float pressure;

    public WeatherData() 
    {
    }
    public void measuremnetsChanged()
    {
        setChanged();
        notifyObservers();
    }
    public void setMeasurements(float temperature,float humidity,float pressure)   //元素变化就会通知观察者
    {
        this.temperature = temperature;
        this.humidity = humidity;
        this.pressure = pressure;
        measuremnetsChanged();
    }
    
    public float getTemperature() 
    {
        return temperature;
    }

    public float getHumidity() {
        return humidity;
    }

    public float getPressure() {
        return pressure;
    }
}

class CurrentConditionDisplay implements Observer,DisplayElement
{

    Observable observable;
    private float temperature;
    private float humidity;

    public CurrentConditionDisplay(Observable observable) {
        this.observable = observable;
        observable.addObserver(this);   //将观察者注册到主题
    }

    @Override
    public void display()
    {
        System.out.println("Current conditions:"+temperature+"F degrees and"+humidity+"% humidity");
    }

    @Override
    public void update(Observable obs, Object arg)
    {
        if(obs instanceof WeatherData)
        {
            WeatherData weatherData = (WeatherData) obs;
            this.temperature = weatherData.getTemperature();
            this.humidity = weatherData.getHumidity();
            display();
        }
    }
}
public class WeatherStation
{
    public static void main(String[] args)
    {
        WeatherData weatherData = new WeatherData();
        CurrentConditionDisplay currentConditionsDisplay = new CurrentConditionDisplay(weatherData);  //观察者注册到主题
        weatherData.setMeasurements(80,65,30.4f); //主题改变会触发所有的观察者的update方法。
        weatherData.setMeasurements(82,70,30.4f);
    }
}

你可能感兴趣的:(设计模式)