Java 多态在融合设计模式中的作用
- 桥接模式:
- 作用:桥接模式将抽象部分与实现部分分离,使它们可以独立变化。Java 多态通过抽象类和接口实现。抽象类定义抽象方法,具体实现由子类完成。在桥接模式中,抽象类(如
Abstraction
)持有一个实现类接口(如 Implementor
)的引用,不同的具体实现类(ConcreteImplementorA
、ConcreteImplementorB
)实现该接口。通过多态,Abstraction
的子类(RefinedAbstraction
)可以在运行时动态绑定到不同的 Implementor
实现,实现抽象与实现的解耦。
- 示例代码:
// 实现类接口
interface Implementor {
void operationImpl();
}
// 具体实现类A
class ConcreteImplementorA implements Implementor {
@Override
public void operationImpl() {
System.out.println("ConcreteImplementorA's operationImpl");
}
}
// 具体实现类B
class ConcreteImplementorB implements Implementor {
@Override
public void operationImpl() {
System.out.println("ConcreteImplementorB's operationImpl");
}
}
// 抽象类
abstract class Abstraction {
protected Implementor implementor;
public Abstraction(Implementor implementor) {
this.implementor = implementor;
}
public abstract void operation();
}
// 具体抽象类
class RefinedAbstraction extends Abstraction {
public RefinedAbstraction(Implementor implementor) {
super(implementor);
}
@Override
public void operation() {
System.out.println("RefinedAbstraction's operation");
implementor.operationImpl();
}
}
- 观察者模式:
- 作用:观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。当主题对象状态发生变化时,会通知所有观察者对象。Java 多态在其中体现为,主题(
Subject
)持有一个观察者(Observer
)接口类型的集合。不同的具体观察者(ConcreteObserverA
、ConcreteObserverB
)实现该接口。当主题状态改变时,通过多态调用不同观察者的 update
方法。
- 示例代码:
// 观察者接口
interface Observer {
void update();
}
// 具体观察者A
class ConcreteObserverA implements Observer {
@Override
public void update() {
System.out.println("ConcreteObserverA updated");
}
}
// 具体观察者B
class ConcreteObserverB implements Observer {
@Override
public void update() {
System.out.println("ConcreteObserverB updated");
}
}
// 主题接口
interface Subject {
void attach(Observer observer);
void detach(Observer observer);
void notifyObservers();
}
// 具体主题
class ConcreteSubject implements Subject {
private List<Observer> observers = new ArrayList<>();
@Override
public void attach(Observer observer) {
observers.add(observer);
}
@Override
public void detach(Observer observer) {
observers.remove(observer);
}
@Override
public void notifyObservers() {
for (Observer observer : observers) {
observer.update();
}
}
}
- 代理模式:
- 作用:代理模式为其他对象提供一种代理以控制对这个对象的访问。Java 多态体现在代理类(
Proxy
)和真实主题类(RealSubject
)实现相同的接口(Subject
)。客户端通过代理类访问真实主题,代理类可以在调用真实主题的方法前后添加额外的逻辑。通过多态,客户端可以统一对待代理类和真实主题类,而无需关心具体是哪个类。
- 示例代码:
// 主题接口
interface Subject {
void request();
}
// 真实主题
class RealSubject implements Subject {
@Override
public void request() {
System.out.println("RealSubject's request");
}
}
// 代理类
class Proxy implements Subject {
private RealSubject realSubject;
public Proxy(RealSubject realSubject) {
this.realSubject = realSubject;
}
@Override
public void request() {
System.out.println("Proxy pre - request");
realSubject.request();
System.out.println("Proxy post - request");
}
}
性能考量因素
- 方法调用开销:多态通过虚方法表实现动态绑定,每次方法调用需要在虚方法表中查找具体的实现方法,相比静态绑定有一定的性能开销。在高频率调用的方法中,这种开销可能会累积影响性能。
- 对象创建和内存开销:多态通常伴随着对象的创建,例如在观察者模式中创建多个具体观察者对象,代理模式中创建代理对象等。频繁的对象创建和销毁会增加垃圾回收的压力,影响性能。
- 继承体系复杂度:随着设计模式的融合,继承体系可能变得复杂。复杂的继承体系可能导致方法查找路径变长,影响性能。同时,过多的子类可能增加内存占用。
性能调优
- 减少不必要的动态绑定:对于一些不会发生变化的方法,可以将其定义为
final
方法,避免动态绑定开销。例如,如果 RealSubject
中的某个方法在代理模式中不需要额外逻辑,可定义为 final
。
- 对象复用:在观察者模式和代理模式中,可以复用已有的对象,减少对象创建和销毁的频率。如使用对象池技术管理观察者对象或代理对象。
- 优化继承体系:尽量简化继承体系,避免过深的继承层次和过多的子类。可以通过组合等方式替代部分继承关系,降低方法查找的复杂度。
综合示例代码
// 桥接模式部分
// 实现类接口
interface Implementor {
void operationImpl();
}
// 具体实现类A
class ConcreteImplementorA implements Implementor {
@Override
public void operationImpl() {
System.out.println("ConcreteImplementorA's operationImpl");
}
}
// 具体实现类B
class ConcreteImplementorB implements Implementor {
@Override
public void operationImpl() {
System.out.println("ConcreteImplementorB's operationImpl");
}
}
// 抽象类
abstract class Abstraction {
protected Implementor implementor;
public Abstraction(Implementor implementor) {
this.implementor = implementor;
}
public abstract void operation();
}
// 具体抽象类
class RefinedAbstraction extends Abstraction {
public RefinedAbstraction(Implementor implementor) {
super(implementor);
}
@Override
public void operation() {
System.out.println("RefinedAbstraction's operation");
implementor.operationImpl();
}
}
// 观察者模式部分
// 观察者接口
interface Observer {
void update();
}
// 具体观察者A
class ConcreteObserverA implements Observer {
@Override
public void update() {
System.out.println("ConcreteObserverA updated");
}
}
// 具体观察者B
class ConcreteObserverB implements Observer {
@Override
public void update() {
System.out.println("ConcreteObserverB updated");
}
}
// 主题接口
interface Subject {
void attach(Observer observer);
void detach(Observer observer);
void notifyObservers();
}
// 具体主题
class ConcreteSubject implements Subject {
private List<Observer> observers = new ArrayList<>();
@Override
public void attach(Observer observer) {
observers.add(observer);
}
@Override
public void detach(Observer observer) {
observers.remove(observer);
}
@Override
public void notifyObservers() {
for (Observer observer : observers) {
observer.update();
}
}
}
// 代理模式部分
// 主题接口
interface SubjectForProxy {
void request();
}
// 真实主题
class RealSubjectForProxy implements SubjectForProxy {
@Override
public void request() {
System.out.println("RealSubject's request");
}
}
// 代理类
class ProxyForSubject implements SubjectForProxy {
private RealSubjectForProxy realSubject;
public ProxyForSubject(RealSubjectForProxy realSubject) {
this.realSubject = realSubject;
}
@Override
public void request() {
System.out.println("Proxy pre - request");
realSubject.request();
System.out.println("Proxy post - request");
}
}
// 综合测试
public class ComplexSystemTest {
public static void main(String[] args) {
// 桥接模式测试
Implementor implementorA = new ConcreteImplementorA();
Abstraction abstractionA = new RefinedAbstraction(implementorA);
abstractionA.operation();
// 观察者模式测试
ConcreteSubject subject = new ConcreteSubject();
Observer observerA = new ConcreteObserverA();
Observer observerB = new ConcreteObserverB();
subject.attach(observerA);
subject.attach(observerB);
subject.notifyObservers();
// 代理模式测试
RealSubjectForProxy realSubject = new RealSubjectForProxy();
ProxyForSubject proxy = new ProxyForSubject(realSubject);
proxy.request();
}
}