設計模式-中介者模式(Java實現)
阿新 • • 發佈:2019-01-24
1. 摘要
中介者模式可以把互相關聯的兩者解耦。這裡的互相關聯,就是關係資料庫中的關聯關係。如班級和學生的關係,每個班級有多個學生,但每個學生只屬於一個班級。(關係資料庫中的一對多關係)通過中介者模式,就能很好的實現一對多、多對多關係。本文僅介紹一對多的實現,多對多的實現與之類似,讀者可舉一反三。
2. 中介者模式UML圖
3. 中介者模式實現
Mediator:
Student:public class Mediator<MANY,ONE> { private Map<MANY,ONE> mMany2One = new HashMap<>(); public ONE getOne(MANY many) { return mMany2One.get(many); } public Set<MANY> getMany(ONE one) { Set<MANY> set = new HashSet<>(); Iterator<Map.Entry<MANY,ONE>> i = mMany2One.entrySet().iterator(); while (i.hasNext()) { Map.Entry<MANY,ONE> e = i.next(); if (e.getValue().equals(one)) { set.add(e.getKey()); } } return set; } public void set(MANY many, ONE one) { mMany2One.put(many, one); } }
ClassRoom:public class Student { private String mId; private Mediator<Student, ClassRoom> mMediator; public Student(String id, Mediator<Student, ClassRoom> mediator) { mId = id; mMediator = mediator; } public ClassRoom getClassRoom() { return mMediator.getOne(this); } public void setClassRoom(ClassRoom classRoom) { mMediator.set(this, classRoom); } @Override public String toString() { return "[Student id: " + mId + "]"; } }
public class ClassRoom { private String mId; private Mediator<Student, ClassRoom> mMediator; public ClassRoom(String id, Mediator<Student, ClassRoom> mediator) { mId = id; mMediator = mediator; } public Set<Student> getStudents() { return mMediator.getMany(this); } public void addStudent(Student student) { mMediator.set(student, this); } @Override public String toString() { return "[ClassRoom id: " + mId + "]"; } }
4. 中介者模式實現多對多思路
可以使用List<Pair<F,S>>來代替一對多中Mediator的Map<MANY,ONE>物件。F為First的縮寫,S為Second的縮寫。使用Pair<F,S>來處理多對多關係,與關係資料庫中,處理多對多關係的方式一樣。舉例來說,學生與課程是多對多的關係。假設,學生有三人,學生1、學生2、學生3,課程有兩門,課程1、課程2。學生1選修了課程1,List<Pair<學生,課程>>就需要新增這一項Pair<學生,課程> pair11 = new Pair(學生1,課程1); 學生2選修了課程1和課程2,則List<Pair<學生,課程>>就需要再新增這兩項Pair<學生,課程> pair21 = new Pair(學生2,課程1); 以及Pair<學生,課程> pair22 = new Pair(學生2,課程2); 學生3選修了課程2,則不再累述。
在Android中,Pair<F, S>實現如下:
package android.util;
import java.util.Objects;
/**
* Container to ease passing around a tuple of two objects. This object provides a sensible
* implementation of equals(), returning true if equals() is true on each of the contained
* objects.
*/
public class Pair<F, S> {
public final F first;
public final S second;
/**
* Constructor for a Pair.
*
* @param first the first object in the Pair
* @param second the second object in the pair
*/
public Pair(F first, S second) {
this.first = first;
this.second = second;
}
/**
* Checks the two objects for equality by delegating to their respective
* {@link Object#equals(Object)} methods.
*
* @param o the {@link Pair} to which this one is to be checked for equality
* @return true if the underlying objects of the Pair are both considered
* equal
*/
@Override
public boolean equals(Object o) {
if (!(o instanceof Pair)) {
return false;
}
Pair<?, ?> p = (Pair<?, ?>) o;
return Objects.equals(p.first, first) && Objects.equals(p.second, second);
}
/**
* Compute a hash code using the hash codes of the underlying objects
*
* @return a hashcode of the Pair
*/
@Override
public int hashCode() {
return (first == null ? 0 : first.hashCode()) ^ (second == null ? 0 : second.hashCode());
}
@Override
public String toString() {
return "Pair{" + String.valueOf(first) + " " + String.valueOf(second) + "}";
}
/**
* Convenience method for creating an appropriately typed pair.
* @param a the first object in the Pair
* @param b the second object in the pair
* @return a Pair that is templatized with the types of a and b
*/
public static <A, B> Pair <A, B> create(A a, B b) {
return new Pair<A, B>(a, b);
}
}
5. 引用
[1] 《設計模式Java手冊》