MST

星途 面试题库

面试题:Java观察者模式与其他设计模式的结合及应用场景分析

在实际项目中,Java观察者模式常常会与其他设计模式结合使用,以满足复杂的业务需求。请举例说明观察者模式可以与哪些设计模式结合,为什么要这样结合,以及结合后在哪些典型的应用场景中能发挥最大优势,同时给出一个简单的代码示例来展示这种结合。
46.6万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

1. 与单例模式结合

  • 结合原因:在很多应用场景中,可能需要一个全局唯一的主题对象,所有观察者都观察这个唯一主题。单例模式确保主题对象的唯一性,避免创建多个主题对象导致的不一致问题,同时也节省系统资源。
  • 应用场景:例如在一个系统的配置管理模块中,配置信息作为主题,当配置发生变化时,所有依赖该配置的模块(观察者)都需要得到通知。由于配置信息全局唯一,使用单例模式创建主题对象非常合适。
  • 代码示例
// 单例主题类
class ConfigSubject {
    private static ConfigSubject instance;
    private String configValue;
    private List<Observer> observers = new ArrayList<>();

    private ConfigSubject() {}

    public static ConfigSubject getInstance() {
        if (instance == null) {
            instance = new ConfigSubject();
        }
        return instance;
    }

    public void attach(Observer observer) {
        observers.add(observer);
    }

    public void detach(Observer observer) {
        observers.remove(observer);
    }

    public void notifyObservers() {
        for (Observer observer : observers) {
            observer.update(configValue);
        }
    }

    public void setConfigValue(String value) {
        this.configValue = value;
        notifyObservers();
    }
}

// 观察者接口
interface Observer {
    void update(String configValue);
}

// 具体观察者类
class ConfigObserver implements Observer {
    @Override
    public void update(String configValue) {
        System.out.println("Config has changed to: " + configValue);
    }
}

2. 与工厂模式结合

  • 结合原因:当系统中有多种类型的主题和观察者,并且需要根据不同条件创建相应的主题和观察者对象时,工厂模式可以封装对象的创建逻辑,使代码更具可维护性和扩展性。
  • 应用场景:在一个消息推送系统中,可能有不同类型的消息主题(如邮件主题、短信主题等)以及对应的观察者(邮件发送者、短信发送者等)。根据用户的配置或业务逻辑,使用工厂模式创建合适的主题和观察者对象。
  • 代码示例
// 主题接口
interface MessageSubject {
    void attach(Observer observer);
    void detach(Observer observer);
    void notifyObservers(String message);
}

// 邮件主题类
class EmailSubject implements MessageSubject {
    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(String message) {
        for (Observer observer : observers) {
            observer.update(message);
        }
    }
}

// 短信主题类
class SmsSubject implements MessageSubject {
    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(String message) {
        for (Observer observer : observers) {
            observer.update(message);
        }
    }
}

// 观察者接口
interface Observer {
    void update(String message);
}

// 邮件发送者观察者类
class EmailSender implements Observer {
    @Override
    public void update(String message) {
        System.out.println("Sending email with message: " + message);
    }
}

// 短信发送者观察者类
class SmsSender implements Observer {
    @Override
    public void update(String message) {
        System.out.println("Sending sms with message: " + message);
    }
}

// 主题工厂类
class SubjectFactory {
    public static MessageSubject createSubject(String type) {
        if ("email".equals(type)) {
            return new EmailSubject();
        } else if ("sms".equals(type)) {
            return new SmsSubject();
        }
        return null;
    }
}

// 观察者工厂类
class ObserverFactory {
    public static Observer createObserver(String type) {
        if ("email".equals(type)) {
            return new EmailSender();
        } else if ("sms".equals(type)) {
            return new SmsSender();
        }
        return null;
    }
}