組合模式可以将一系列有相同接口的對象組合成一個對象對外提供服務,組合後的對象對外提供的服務與組合之前單個對象對外提供的服務接口保持一緻,
這使得通路這一系列的對象有了統一的通路門面,這種變化對用戶端透明,降低了用戶端的通路複雜性,同時這種将多個類似對象組合起來使用的設計模式也使得服務端層次結構更加清晰,易于維護。
組合模式可以輕松地将對一個對象的調用傳遞到多個對象中執行,具有牽一動百之功效,這種特性使得組合模式多用于樹形結構、監聽器、過濾器、鍊式處理等場景。
場景:使用監聽器監聽事件變化,要求可以靈活地添加多個監聽器,而不需要修改事件源的邏輯(開閉原則)。
設計:
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIiclRnblN0LclHdpZXYyd2LcBzNvwVZ2x2bzNXak9CX90TQNNkRrFlQKBTSvwFbslmZvwFMwQzLcVmepNHdu9mZvwFVywUNMZTY18CX052bm9CX9UFVNNTQqNGbWh1Y1ljMZZXUYpVd1kmYr50MZV3YyI2cKJDT29GRjBjUIF2LcRHelR3LcJzLctmch1mclRXY39jMxgzNwQzMwEjNyEDM1EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
示例代碼:
import java.util.ArrayList;
import java.util.List;
interface EventListener {
void doEvent();
}
class EventSource {
private EventListener eventListener;
public EventSource(EventListener eventListener) {
this.eventListener = eventListener;
}
public void fireEvent() {
eventListener.doEvent();
}
}
class ClickEventListener implements EventListener {
@Override
public void doEvent() {
System.out.println("處理點選事件 ...");
}
}
class ChangeEventListener implements EventListener {
@Override
public void doEvent() {
System.out.println("處理改變事件 ...");
}
}
class CompositeListener implements EventListener {//對外表現就是一個普通的EventListener
private List<EventListener> eventListeners = new ArrayList<>();
@Override
public void doEvent() {//這裡實作了EventListener接口,表現就像是一個普通的EventListener
for (EventListener eventListener: eventListeners) {//一起工作
eventListener.doEvent();
}
}
// 可以友善地添加協同工作者,以組合成強大的工作陣容
public void addEventListener(EventListener eventListener) {
eventListeners.add(eventListener);
}
}
public class Test {
public static void main(String[] args) {
ClickEventListener clickEventListener = new ClickEventListener();
ChangeEventListener changeEventListener = new ChangeEventListener();
CompositeListener compositeListener = new CompositeListener();
compositeListener.addEventListener(clickEventListener);//添加協作者
compositeListener.addEventListener(changeEventListener);//添加協作者
//EventSource隻允許傳入一個 監聽器,使用組合模式,便可讓多個監聽器一起工作
EventSource eventSource = new EventSource(compositeListener);
eventSource.fireEvent();//觸發事件
System.out.println("=================================");
// 組合一個組合對象
CompositeListener others = new CompositeListener();
others.addEventListener(new EventListener() {
@Override
public void doEvent() {
System.out.println("處理選擇事件 ...");
}
});
others.addEventListener(new EventListener() {
@Override
public void doEvent() {
System.out.println("處理其它事件 ...");
}
});
// 組合一個組合對象
compositeListener.addEventListener(others);
eventSource.fireEvent();//觸發事件
}
}