23种设计模式之内置观察者模式

一般听到观察者模式的时候,许多人都比较懵逼,我在这里给大家详细讲解一下什么叫观察者模式并附带源码。

观察者模式定义了对象之间的一对多依赖,这样一来,当一个对象改变状态时,它的所有依赖者都会受到通知并自动跟新。意思就是,当我的一个主题状态发生改变时,就会自动跟新或者通知观察者,根据通知的风格,观察者可能因此新值发生改变。

观察者模式一般至少会有两个接口,一个是主题接口,主题接口是用来通知所有观察者并且跟新信息,另一个接口是观察者接口,这个接口负责更新数据。举个例子来说,当你饿了的时候,你的胃就会发出一个信号传送到你的大脑里面,告诉你这个信息,你饿了,该吃饭了,这个时候你的胃就是主题,你的大脑就是观察者,你吃东西就是你在改变你的行为。

但是今天我讲解的是观察者模式中的内置观察者模式,内置的好处在于Observable这个类在Java类库中已经定义,不需要自己再去定义,直接继承就可以,比起观察者模式更具灵活和简单。首先我们先看Java内置观察者模式的讲解类图。





在这个类图中,我们就可能有了一个疑问,为什么还是Observable这个类呢,这张图告诉我们Observable类虽然不需要你重新写,但是它本身是存在的,作为一个主题追踪所有的观察者,并通知他们,他作为气象站WeatherDate扩展了Observable主题;而接口Observer作为观察者,负责通知具体的观察者根据update()方法做出相应地改变。但是内置观察者模式与观察者模式区别在于,内置观察者模式新增了gettter()和setter()方法来“拉”和“推”数据,来使得代码灵活性更高。


就举个例子俩说,在一个超市(market)系统里面,我有许多消费者(customer),为了促进消费,我为customer设置了会员(vip)等级,当消费者选好商品(product)来付款时,我的超市(market)能及时通知老板(boss),更新上一个消费者(customer)的消费记录,并进行打折,输出折扣价格,请用内置观察者模式写出来。

下面是我附带的源码,来教大家具体怎么写。

第一步我们是先要设置customer中的五个vip等级,这里需要有一个VIPBehavior接口来实现,这里我只举例VIP1。

package customer;


public interface VIPBehavior {

public float VipBehavior();


}


package customer;


public class Vip1 implements VIPBehavior{
public float VipBehavior(){
return (float) 0.7;
}
}

第二步我们要开始定义Customer抽象类,这里我定义的抽象类,因为Customer中有很多类型的消费者,然后我定义了一个CustomerA来继承抽象类Customer,Customer类中通过buy()方法来输出的折扣后的价格,值得注意的是,这里用的集合来存放的,方便管理和操作,值得注意的是,CustomerA继承Customer方法的super()方法时只能在同一个包中。

package customer;
import market.*;
import product.Product;


import java.util.ArrayList;


public abstract class Customer {

VIPBehavior vipBehavior;

private ArrayList<Product> pro= new ArrayList<Product>();

public Customer(ArrayList<Product> product){
this.pro = product;
//vipBehavior = new Vip1();

}


public float buy(){
float sum=0.0f;

for(int i=0;i<pro.size();i++){
Product productPrice = (Product)pro.get(i);


sum +=productPrice.getPrice()*productPrice.getNumber();

}
sum = sum*vipBehavior.VipBehavior();
return (float)sum;

}


}



package customer;
import java.util.ArrayList;


import product.Product;


public class CustomerA extends Customer {
public CustomerA(ArrayList<Product> list){
super(list);
vipBehavior=new Vip1();

}



}

第三步就要写我们的商品(product)类,这个方法较简单,只需要构造方法和setter、getter方法即可。

package product;


public class Product {

private String name;
private float price;
private int number;

public Product(String name,float price,int number){
this.name = name;
this.price = price;
this.number = number;


public String getName() {
return name;
}


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


public int getNumber() {
return number;
}


public void setNumber(int number) {
this.number = number;
}


public void setPrice(float price) {
this.price = price;
}


public float getPrice(){

return price;
}


}


第四步设置我的超市系统,并继承Observable类,写好setMeasurement()通知观察者。


package market;
import java.util.Observable;


import customer.Customer;


public class SuperMarket extends Observable{

private float sum;
public SuperMarket(){

}

public void measurementsChanged(){
setChanged();
notifyObservers();
}

public float getSum(){
return sum;
}

public void setMeasurements(Customer prices){

            //通过从消费者买的商品中获取折扣价格时通知观察者并发生改变

sum = prices.buy();     
measurementsChanged();
}



}


第五步我们要开始写观察者接口Observer,并且boss类继承Observer这个接口,作为当前观察者,通过update()方法及时跟新数据。

package market;


import java.util.Observable;


public interface Observer {
public void update(Observable o,Object arg);


}


package market;


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


public class Boss implements Observer{

Observable observable;

public Boss(Observable observable){
this.observable = observable;
observable.addObserver(this);

}



public void update(Observable o,Object arg){
if(o instanceof SuperMarket){
SuperMarket sup = (SuperMarket)o;
float sumPrice = sup.getSum();
System.out.println("经过折扣后的价格为:"+sumPrice);

}

}

}


最后一步,当我们把这些都做完的时候,我们这个时候就需要到主函数里面输出了,值得注意的是,主函数中一定要有setMeasurement()这个方法,主题对象发生变化并通知观察者的起点。

package main;
import java.util.ArrayList;


import customer.*;
import market.Boss;
import market.SuperMarket;
import product.Product;


public class MarketStation {
public static void main(String[] args){

ArrayList<Product> product = new ArrayList<Product>();
SuperMarket superMarket = new SuperMarket();
Boss boss =  new Boss(superMarket);
Customer customerA = new CustomerA(product);

product.add(new Product("文化苦旅",69.8f,2));
superMarket.setMeasurements(customerA);

}


}


猜你喜欢

转载自blog.csdn.net/masterpieve/article/details/79716631
今日推荐