设计模式 观察者模式
观察者模式也仍然是一种组件协作模式。
使用动机

可以具体一点,比如银行账户发生变化时,会自动发短信通知。steam玩游戏达到某一个条件时弹成就。
这种有一个“观察者”去时时刻刻的观察某一个东西的变化就可以使用观察者模式。
简单例子
假设银行账户金额发生变化,此时需要短信和邮箱通知
客户类
public class CustomerBank1 {
private String email;
private String phone;
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public void notifyEmail(double amt){
System.out.println("账号金额变动 发送邮件到"+email+"当前金额为"+amt);
}
public void notifyPhone(double amt){
System.out.println("账号金额变动 发送短信到"+phone+"当前金额为"+amt);
}
}
银行类:
public class BankAcount {
private String name;
private double amt;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getAmt() {
return amt;
}
public void setAmt(double amt) {
this.amt = amt;
CustomerBank1 customerBank1=new CustomerBank1();
customerBank1.setEmail("***@***.com");
customerBank1.notifyEmail(amt);
customerBank1.setPhone("123456789");
customerBank1.notifyPhone(amt);
}
}
客户端:
public class Client {
public static void main(String[] args) {
BankAcount bankAcount=new BankAcount();
bankAcount.setAmt(1000);
}
}

不难看出我们的程序有一个问题,如果后续要新添加其他的通讯方式。那么客户类和银行类都必须去修改。
这里不同的观察方式就是观察者(根据数据变化产生某一种行为),银行账户就是被观察类。
采用观察者模式优化
定义一个银行账户观察者接口
public interface BankObserver {
public void update(double amt);
}
实现邮箱方式
public class CustomerBank1_Ob implements BankObserver {
private String email;
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@Override
public void update(double amt) {
System.out.println("账号金额变动 发送邮件到"+email+"当前金额为"+amt);
}
}
实现手机方式
public class CustomerBank2_OB implements BankObserver {
private String phone;
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
@Override
public void update(double amt) {
System.out.println("账号金额变动 发送短信到"+phone+"当前金额为"+amt);
}
}
银行账户类(被观察者)
import java.util.ArrayList;
import java.util.List;
public class BankAcount_OB {
private String name;
private double amt;
List<BankObserver> list=new ArrayList<>();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getAmt() {
return amt;
}
//添加观察者
public void add(BankObserver bankObserver){
list.add(bankObserver);
}
private void remove(BankObserver bankObserver){
list.remove(bankObserver);
}
public void notifyAmt(){
for(int i=0;i<list.size();i++){
BankObserver bankObserver=(BankObserver)list.get(i);
bankObserver.update(amt);
}
}
public void setAmt(double amt) {
this.amt = amt;
notifyAmt();
}
}
客户端代码
public class Client_OB {
public static void main(String[] args) {
BankAcount_OB bankAcount_ob=new BankAcount_OB();
CustomerBank1_Ob customerBank1_ob=new CustomerBank1_Ob();
customerBank1_ob.setEmail("***@***.com");
CustomerBank2_OB customerBank2_ob=new CustomerBank2_OB();
customerBank2_ob.setPhone("123456789");
bankAcount_ob.add(customerBank1_ob);
bankAcount_ob.add(customerBank2_ob);
//将1 2添加到观察者名单
bankAcount_ob.setAmt(1000);
//触发更新时所有观察者名单的update都被执行
}
}
假设我们后续要添加QQ通知功能,就很方便了。只需要定义一个类去实现接口,之前写的代码无需修改
总结



浙公网安备 33010602011771号