组合模式可以将一系列有相同接口的对象组合成一个对象对外提供服务,组合后的对象对外提供的服务与组合之前单个对象对外提供的服务接口保持一致,
这使得访问这一系列的对象有了统一的访问门面,这种变化对客户端透明,降低了客户端的访问复杂性,同时这种将多个类似对象组合起来使用的设计模式也使得服务端层次结构更加清晰,易于维护。
组合模式可以轻松地将对一个对象的调用传递到多个对象中执行,具有牵一动百之功效,这种特性使得组合模式多用于树形结构、监听器、过滤器、链式处理等场景。
场景:使用监听器监听事件变化,要求可以灵活地添加多个监听器,而不需要修改事件源的逻辑(开闭原则)。
设计:
示例代码:
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();//触发事件
}
}