设计模式之行为型模式

Posted 编程爱好者ing

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了设计模式之行为型模式相关的知识,希望对你有一定的参考价值。

行为型模式包含有:模板方法模式,命令模式,访问者模式,迭代器模式,观察者模式,中介者模式,备忘录模式,解释器模式,状态模式,策略模式,职责链模式(责任链模式)

以下主要讲述:观察者模式,策略模式,职责链模式,模板方法模式

一、观察者模式

  1.     观察者模式原理

    观察者模式有两大角色:观察者与被观察者

    Subject(被观察者):(一方)提供数据并更改数据的

    Observer(观察者):(多的一方):接收数据的

对象之间多对一依赖的一种设计方案,被观察的对象Subject,观察者Observer,Subject通知Observer变化。如果这里的Subject是一个气象站的话,Observer就是接入气象站的各个第三方接口,当天气数据出现变化的时候,气象站更新天气数据,第三方接口显示的天气也会同步更新。

    2.实例 观察者模式解决天气预报需求

 3.UML类图

设计模式之行为型模式(三)

/** * 被观察者接口 * @author admin */public interface Subject { //注册 public void registerObserver(Observer o); //移除 public void removeObserver(Observer o); //提醒 public void notifyObservers();}//被观察者实现类
public class WeatherData implements Subject { private float temperatrue;//温度 private float pressure;//气压 private float humidity;//湿度
// 观察者集合(第三方接口集合) private ArrayList<Observer> observers;
// 加入新的第三方 public WeatherData() { observers = new ArrayList<Observer>(); }
// 注册一个观察者 @Override public void registerObserver(Observer o) { observers.add(o); }
// 移除一个观察者 @Override public void removeObserver(Observer o) { if (observers.contains(o)) { observers.remove(o); } }
// 当数据有更新时,就调用 setData public void setData(float temperature, float pressure, float humidity) {    this.temperatrue = temperature;    this.pressure = pressure;    this.humidity = humidity; // 调用dataChange, 将最新的信息 推送给 观察者 dataChange();  } // 更改第三方观察者 public void dataChange() { // 调用 接入方的 update notifyObservers(); }
// 遍历所有的观察者,并通知 @Override public void notifyObservers() { for (int i = 0; i < observers.size(); i++) { observers.get(i).update(this.temperatrue, this.pressure, this.humidity); } }
public float getTemperature() { return temperatrue;  } public float getPressure() { return pressure;  } public float getHumidity() { return humidity;  }}
/** * 观察者接口 * @author admin */public interface Observer { //更新数据 public void update(float temperature, float pressure, float humidity);}//观察者接口实现类/**观察者(第三方接口) * @author admin */public class Sina implements Observer { private float temperature;// 温度 private float pressure;// 气压 private float humidity;// 湿度
// 更新 天气情况,是由 WeatherData 来调用,使用推送模式 public void update(float temperature, float pressure, float humidity) { this.temperature = temperature; this.pressure = pressure; this.humidity = humidity; display();  } // 天气数据显示 public void display() { System.out.println("***Sina mTemperature: " + temperature + "***"); System.out.println("***Sina mPressure: " + pressure + "***"); System.out.println("***Sina mHumidity: " + humidity + "***");  }}//观察者实现类2/**观察者(第三方接口) * @author admin */public class BaiduSite implements Observer { private float temperature;// 温度 private float pressure;// 气压 private float humidity;// 湿度
// 更新 天气情况,是由 WeatherData 来调用,我使用推送模式 public void update(float temperature, float pressure, float humidity) { this.temperature = temperature; this.pressure = pressure; this.humidity = humidity; display(); }
// 天气数据显示 public void display() { System.out.println("***Baidu mTemperature: " + temperature + "***"); System.out.println("***Baidu mPressure: " + pressure + "***"); System.out.println("***Baidu mHumidity: " + humidity + "***"); }}//测试类public class ClientTest { public static void main(String[] args) { // 创建被观察者对象 WeatherData weatherData = new WeatherData(); // 创建观察者对象 BaiduSite baiduSite = new BaiduSite(); Sina sina=new Sina();
// 将观察者注册到被观察者集合中 weatherData.registerObserver(baiduSite); weatherData.registerObserver(sina); // 测试 System.out.println("通知各个注册的观察者, 看看信息"); //更新数据    weatherData.setData(10f, 100f, 30.3f); //移除观察者 weatherData.removeObserver(sina); // 测试 System.out.println(); System.out.println("通知各个注册的观察者, 看看信息"); weatherData.setData(20f, 200f, 30.3f);  }}当其他第三方接口接入时,被观察者不用改动,只需再写一个类实现观察者接口即可代码大致与BaiduSite,sina类中的代码类似。

二、策略模式

  1. 策略模式简介

    1)策略模式中定义了算法簇,分别封装起来,让他们之间相互替换,此模式让算法的变化独立于使用算法的客户。

    2)这种算法体现了几个设计原则:第一:把变化的代码从不变的代码中分离出来。第二:针对接口编程,不是具体类(定义了策略接口)。第3)多用组合/聚合,少用继承(客户通过组合方式使用策略)

  2. 策略模式解决鸭子问题:需求如下

    设计模式之行为型模式(三)

    不论是野鸭,北京鸭还是水鸭也好,都有相同的特点,会有飞,叫等属性,策略模式就是将鸭子的属性定义成一个个的接口,用类去实现。即使各种鸭子飞行技术好坏或者叫声的声音不同也好,使用多个实现类去实现即可。

    当在某个鸭子的时候,直接在构造方法中,直接使用接口定义子类对象即可把其属性添加进来。

  3. UML类图

设计模式之行为型模式(三)

4.代码实现

/** * 飞属性接口 * @author admin */public interface FlyBehavior { void fly();}//飞属性接口实现类/**鸭子飞行技术,有飞的技术好的也有飞行技术差的 这里有两个实现飞接口的实现类 * @author admin */public class GoodFlyBehavior implements FlyBehavior { @Override public void fly() { System.out.println("飞行技术很好,厉害厉害~~~~"); }}public class BadFlyBehavior implements FlyBehavior{ @Override public void fly() { System.out.println("飞行技术不行。。。。。。。");  }}//鸭子叫接口public interface QuackBehavior { void quack();}//实现类public class GaGaQuackBehavior implements QuackBehavior { @Override public void quack() { System.out.println("GaGa的叫~~~~~~");  }}
public class GeGeQuackBehavior implements QuackBehavior{ @Override public void quack() { System.out.println("GeGe的叫。。。。。"); }}
/**鸭子抽象类 * @author admin * */public abstract class Duck { //将飞行行为接口作为鸭子的属性 FlyBehavior flyBehavior; QuackBehavior quackBehavior;
/** * 鸭子的飞行技术属性 */ public void fly() { if(flyBehavior!=null) { flyBehavior.fly(); } }
/** * 鸭子叫的行为技术 */ public void call() { if(quackBehavior!=null) { quackBehavior.quack(); }  }}//鸭子的实现类/**北京鸭 * @author admin */public class PekingDuck extends Duck{    //在构造方法中添加其属性 public PekingDuck() { //飞属性 flyBehavior=new BadFlyBehavior();    //叫属性 quackBehavior=new GeGeQuackBehavior(); }}//野鸭实现类public class WildDuck extends Duck{ public WildDuck() { //飞行技术 flyBehavior=new GoodFlyBehavior(); //鸭子叫的行为 quackBehavior=new GaGaQuackBehavior(); }}//测试类代码:public static void main(String[] args) {     //北京鸭 PekingDuck pekingDuck=new PekingDuck(); pekingDuck.fly(); System.out.println(); pekingDuck.call(); System.out.println(); //野鸭 WildDuck wildDuck=new WildDuck(); wildDuck.fly(); System.out.println(); wildDuck.call();  }

设计模式之行为型模式(三)

策略模式遵循OCP原则,但是当策略过多是会导致类数目庞大。

三、职责链模式(责任链模式)

职责链模式简介

1)职责链模式又叫责任链模式,为请求创建一个接收者对象的链。这种模式对请求的发送者和接收者进行解耦。

2)职责链模式通常每个接收者都包含对另一个接收者的引用。如果一个对象不能处理该请求,那么它会把相同的请求传给下一个接收者,以此类推。

实例需求:


UML类图


//职责/处理者抽象接口public abstract class Approver { //下一个处理者  Approver approver;  String name;//处理者名字 public Approver(String name) { this.name = name; } //设置下一个处理请求的人 public void setApprover(Approver approver) { this.approver = approver;  } //处理请求方法,需要每一个子类去实现  public abstract void processRequest(PurchaseRequest purchaseRequest);}
//教学主任处理者public class DepartmentApprover extends Approver { public DepartmentApprover(String name) { super(name); }  //PurchaseRequest 请求类 @Override public void processRequest(PurchaseRequest purchaseRequest) { if(purchaseRequest.getPrice() <= 5000) { System.out.println(" 请求编号 id= " + purchaseRequest.getId() + " 被 " + this.name + " 处理"); }else { approver.processRequest(purchaseRequest); }  }}
//院长处理者public class CollegeApprover extends Approver { public CollegeApprover(String name) { super(name);  } //PurchaseRequest 请求类 @Override public void processRequest(PurchaseRequest purchaseRequest) { if(purchaseRequest.getPrice()>5000 && purchaseRequest.getPrice() <= 10000) { System.out.println(" 请求编号 id= " + purchaseRequest.getId() + " 被 " + this.name + " 处理"); }else { approver.processRequest(purchaseRequest); } }}
//副校长处理者public class ViceSchoolMasterApprover extends Approver { public ViceSchoolMasterApprover(String name) { super(name); } //PurchaseRequest 请求类 @Override public void processRequest(PurchaseRequest purchaseRequest) { if(purchaseRequest.getPrice()>10000 && purchaseRequest.getPrice() <= 30000) { System.out.println(" 请求编号 id= " + purchaseRequest.getId() + " 被 " + this.name + " 处理"); }else { approver.processRequest(purchaseRequest); } }}
//校长处理者public class SchoolMasterApprover extends Approver { public SchoolMasterApprover(String name) { super(name); } //PurchaseRequest 请求类 @Override public void processRequest(PurchaseRequest purchaseRequest) { if(purchaseRequest.getPrice() > 30000) { System.out.println(" 请求编号 id= " + purchaseRequest.getId() + " 被 " + this.name + " 处理"); }else { approver.processRequest(purchaseRequest); } }}
//请求类public class PurchaseRequest { private int type = 0; //请求类型 private float price = 0.0f; //请求金额 private int id = 0; public PurchaseRequest(int type, float price, int id) { super(); this.type = type; this.price = price; this.id = id; } public int getType() { return type; } public float getPrice() { return price; } public int getId() { return id;  }}
//测试类public static void main(String[] args) { //创建一个请求    PurchaseRequest purchaseRequest = new PurchaseRequest(180001); //创建相关的审批人 //系主任 DepartmentApprover department = new DepartmentApprover("张主任"); //院长 CollegeApprover college = new CollegeApprover("李院长"); //副校长 ViceSchoolMasterApprover viceSchoolMaster = new ViceSchoolMasterApprover("王副校"); //校长 SchoolMasterApprover schoolMaster = new SchoolMasterApprover("佟校长");
//需要将各个审批级别的下一个处理者设置好 (处理人构成环形: ) department.setApprover(college); college.setApprover(viceSchoolMaster); viceSchoolMaster.setApprover(schoolMaster); schoolMaster.setApprover(department); //任何一个处理者调用请求的方法都可以    viceSchoolMaster.processRequest(purchaseRequest);  }


以上是关于设计模式之行为型模式的主要内容,如果未能解决你的问题,请参考以下文章

设计模式 行为型模式 -- 观察者模式(发布-订阅(Publish/Subscribe)模式)

设计模式之行为型状态模式

GoF23种设计模式之行为型模式之模板方法

设计模式之行为型迭代器模式

设计模式——行为型模式之中介者模式

行为型设计模式之策略模式