在Java应用开发中,对象不是孤立存在的,不同对象之间需要通过协作完成业务功能。不合理的协作方式会让对象之间产生强依赖,导致系统复杂度急剧上升,而科学的协作模式设计能够有效降低这种复杂度,提升系统的可维护性。

常见的Java对象协作模式
1. 观察者模式
观察者模式通过定义一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。当主题对象状态发生变化时,会自动通知所有观察者对象,使它们能够自动更新。这种模式将主题和观察者的职责拆分,两者不需要直接持有对方的强引用,通过抽象接口交互,降低了耦合度。
下面是一个简单的观察者模式实现示例:
import java.util.ArrayList;
import java.util.List;
// 观察者接口
interface Observer {
void update(String message);
}
// 具体观察者
class ConcreteObserver implements Observer {
private String name;
public ConcreteObserver(String name) {
this.name = name;
}
@Override
public void update(String message) {
System.out.println(name + " 收到通知:" + message);
}
}
// 主题接口
interface Subject {
void addObserver(Observer observer);
void removeObserver(Observer observer);
void notifyObservers();
}
// 具体主题
class ConcreteSubject implements Subject {
private List<Observer> observers = new ArrayList<>();
private String state;
public void setState(String state) {
this.state = state;
notifyObservers();
}
@Override
public void addObserver(Observer observer) {
observers.add(observer);
}
@Override
public void removeObserver(Observer observer) {
observers.remove(observer);
}
@Override
public void notifyObservers() {
for (Observer observer : observers) {
observer.update(state);
}
}
}
public class ObserverDemo {
public static void main(String[] args) {
ConcreteSubject subject = new ConcreteSubject();
Observer observer1 = new ConcreteObserver("观察者1");
Observer observer2 = new ConcreteObserver("观察者2");
subject.addObserver(observer1);
subject.addObserver(observer2);
subject.setState("状态更新为A");
}
}
2. 中介者模式
中介者模式用一个中介对象来封装一系列的对象交互,使各对象不需要显式地相互引用,从而使其耦合松散。多个对象之间的复杂交互逻辑被转移到中介者中,每个对象只需要和中介者交互,不需要关心其他对象的存在,大幅减少了对象之间的直接依赖。
以下是中介者模式的简单实现:
import java.util.HashMap;
import java.util.Map;
// 中介者接口
interface Mediator {
void register(String colleagueName, Colleague colleague);
void sendMessage(String colleagueName, String message);
}
// 具体中介者
class ConcreteMediator implements Mediator {
private Map<String, Colleague> colleagueMap = new HashMap<>();
@Override
public void register(String colleagueName, Colleague colleague) {
colleagueMap.put(colleagueName, colleague);
colleague.setMediator(this);
}
@Override
public void sendMessage(String colleagueName, String message) {
Colleague colleague = colleagueMap.get(colleagueName);
if (colleague != null) {
colleague.receiveMessage(message);
}
}
}
// 同事类抽象
abstract class Colleague {
protected Mediator mediator;
public void setMediator(Mediator mediator) {
this.mediator = mediator;
}
public abstract void sendMessage(String to, String message);
public abstract void receiveMessage(String message);
}
// 具体同事类
class ConcreteColleague extends Colleague {
private String name;
public ConcreteColleague(String name) {
this.name = name;
}
@Override
public void sendMessage(String to, String message) {
System.out.println(name + " 发送消息给 " + to + ":" + message);
mediator.sendMessage(to, message);
}
@Override
public void receiveMessage(String message) {
System.out.println(name + " 收到消息:" + message);
}
}
public class MediatorDemo {
public static void main(String[] args) {
Mediator mediator = new ConcreteMediator();
Colleague colleague1 = new ConcreteColleague("同事1");
Colleague colleague2 = new ConcreteColleague("同事2");
mediator.register("同事1", colleague1);
mediator.register("同事2", colleague2);
colleague1.sendMessage("同事2", "你好,我是同事1");
}
}
协作模式对系统复杂性的优化作用
降低模块间的耦合度
传统的对象协作往往是直接引用其他对象的具体实现类,一旦被引用对象的实现发生变化,所有引用它的对象都需要修改。而通过接口定义协作边界,或者引入中介者、观察者等模式,对象之间只需要依赖抽象接口或者中介者,不需要关心对方的具体实现,模块间的耦合度大幅降低,修改一个模块对其他模块的影响被控制在最小范围。
减少冗余逻辑
在没有合理协作模式的情况下,多个对象可能需要重复编写相同的交互逻辑,比如多个对象都需要通知其他对象状态变化,就需要在每个对象中都编写通知逻辑。而通过统一的协作模式,这些公共的交互逻辑可以被抽取到抽象层或者中介者中,避免逻辑重复,减少代码量,也降低了逻辑出错的概率。
提升系统的可扩展性
当业务需求变化时,合理的协作模式让新增功能变得更加简单。比如使用观察者模式时,如果需要新增一个监听主题状态的对象,只需要新增一个实现观察者接口的类,注册到主题中即可,不需要修改主题和其他现有观察者的代码。这种扩展方式符合开闭原则,系统的扩展性得到明显提升,不会因为需求迭代导致系统复杂度持续上升。
设计协作模式的注意事项
在设计对象协作模式时,不能盲目套用设计模式。首先要明确对象之间的交互边界,避免过度设计。如果对象之间的交互非常简单,直接引用反而比引入复杂模式更清晰。其次要保证协作模式中每个对象的职责单一,不要让一个对象承担过多的交互逻辑,否则中介者或者主题对象会变得过于臃肿,反而提升系统复杂度。最后要注意协作模式的性能影响,比如观察者模式中如果观察者数量过多,通知所有观察者的操作可能会带来性能开销,需要根据实际场景做优化。