设计模式全文
迭代器模型
- 案例,学校、学院、系;不同学院用不同的方式管理,计算机用数组,信息工程用集合
- Iterator Pattern,行为型模式,当集合用不同的方式实现,当客户端要遍历这些集合,就需要多种遍历方式,暴露元素的内部结构
提供一种遍历集合元素的统一接口,用
一致的方法遍历集合元素
- 案例类图
- 抽象集合
public interface College {
String getName();
void addDepartment(String name, String des);
Iterator createIterator();
}
- 实际的集合,以数组的方式存放元素
public class ComputeCollege implements College{
Department[] departments;
//保存当前数组的对象个数
int numOfDepartment = 0;
public ComputeCollege() {
departments = new Department[5];
addDepartment("java","java");
addDepartment("go","go");
addDepartment("oc","oc");
addDepartment("python","python");
addDepartment("swift","swift");
}
@Override
public String getName() {
return "Computer";
}
@Override
public void addDepartment(String name, String des) {
Department department = new Department(name, des);
departments[numOfDepartment++] = department;
}
@Override
public Iterator createIterator() {
return new ComputerCollegeIterator(departments);
}
}
- ComputerCollegeIterator,针对于数组方式的迭代器
public class ComputerCollegeIterator implements Iterator {
//需要知道Department的存放方式
Department[] departments;
//起始位置
int position = 0;
public ComputerCollegeIterator(Department[] departments) {
this.departments = departments;
}
@Override
public boolean hasNext() {
return !(position >= departments.length || departments[position] == null);
}
@Override
public Object next() {
return departments[position++];
}
@Override
public void remove() {
}
}
- 实际元素
public class Department {
private String name;
private String des;
public Department(String name, String des) {
this.name = name;
this.des = des;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getDes() {
return des;
}
public void setDes(String des) {
this.des = des;
}
}
- 输出类
public class OutputImpl {
//学院集合
List<College> colleges;
public OutputImpl(List<College> colleges) {
this.colleges = colleges;
}
//输出学院
public void outputCollege() {
Iterator<College> iterator = colleges.iterator();
while (iterator.hasNext()) {
College college = iterator.next();
System.out.println(college.getName());
outputDepatrment(college.createIterator());
}
}
//学院输出系
public void outputDepatrment(Iterator iterator) {
while (iterator.hasNext()) {
Department d = (Department) iterator.next();
System.out.println(d.getName() + " - " + d.getDes());
}
}
}
ArrayList源码
- 实现了
list接口,有Iterator<E> iterator();得到迭代器的抽象方法 ArrayList的实现
public Iterator<E> iterator() {
return new Itr();
}
ArrayList的内部类ItrArrayList以数组形式存放,transient不会被序列化- 直接使用
ArrayList元素
小结
- 把管理对象集合和遍历对象集合则责任分开,符合单一责任原则,集合改变只影响聚合对象,遍历方式改变,只影响迭代器
- 将迭代器隐含于集合的内部,一种方法遍历所有集合,具体实现根据存储的方式不同进行改变
- 每个聚合对象都需要一个具体的迭代器,需要管理多个类
观察者模型
- 案例,气象站,每天测量到温度、湿度等信息,设计API,更新时将信息发布
- 传统方案,如果增加一个显示渠道,修改的地方较多
- Observer,需要端注册通知,推送端发送通知,遵守OCP原则
- Observer,观察者
public interface Observer {
void update(float temperature, float pressure, float humidity);
}
- Subject,管理者,管理观察者,负责监控信息变化
public interface Subject {
void registerObserver(Observer o);
void notifyObserver();
void removeObserver(Observer o);
}
- CurrentConditions,观察者的实现类
//显示网站
public class CurrentConditions implements Observer {
// 温度气压
private float temperature;
private float pressure;
private float humidity;
//更新,被推送
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("***Today mTemperature: " + temperature + "***");
System.out.println("***Today mPressure: " + pressure + "***");
System.out.println("***Today mHumidity: " + humidity + "***");
}
}
- WeatherData,消息源
public class WeatherData implements Subject{
private float temperatrue;
private float pressure;
private float humidity;
private List<Observer> observerList = new ArrayList<>();
public void dataChange() {
notifyObserver();
}
@Override
public void registerObserver(Observer o) {
observerList.add(o);
}
@Override
public void notifyObserver() {
for (Observer observer : observerList) {
observer.update(temperatrue, pressure, humidity);
}
}
@Override
public void removeObserver(Observer o) {
if (observerList.contains(o)) observerList.remove(o);
}
public void setData(float temperature, float pressure, float humidity) {
this.temperatrue = temperature;
this.pressure = pressure;
this.humidity = humidity;
dataChange();
}
}
Observable源码
- 管理观察者类,直接将接口实现,管理观察者
- 观察者
public interface Observer {
void update(Observable o, Object arg);
}
change为false时,标明这个数据源已将最新的更改通知给所有通知者,此时调用notify无效
那么在使用时,数据更新时要先将change设置为true