首页 > 其他分享 >赶紧收藏!2024 年最常见 20道设计模式面试题(七)

赶紧收藏!2024 年最常见 20道设计模式面试题(七)

时间:2024-06-20 10:28:36浏览次数:14  
标签:享元 状态 面试题 20 对象 观察者 模式 设计模式 客户端

上一篇地址:赶紧收藏!2024 年最常见 20道设计模式面试题(六)-CSDN博客

十三、享元模式如何优化资源使用?

享元模式(Flyweight Pattern)是一种结构型设计模式,用于减少创建对象的数量,以减少内存占用和提高性能。这种模式通过共享多于一个对象共同使用的相同状态,来优化资源使用。

享元模式的组成部分:

  1. 享元对象(Flyweight):享元对象是细粒度的,可以被多个客户端共享。
  2. 非享元对象(UnsharedConcreteFlyweight):如果有些状态不能共享,则需要创建非享元对象。
  3. 享元工厂(FlyweightFactory):负责创建和管理享元对象,确保享元对象可以被多个客户端共享。

享元模式的工作原理:

  1. 享元工厂:客户端通过享元工厂请求享元对象。享元工厂首先检查请求的享元对象是否已经存在,如果存在,则返回现有的对象;如果不存在,则创建一个新的对象。
  2. 享元对象:享元对象存储内部状态,这些状态对于所有共享该对象的客户端都是相同的。
  3. 非享元对象:如果享元对象的状态信息有部分是不可以共享的,则需要创建非享元对象来存储这些状态。

享元模式如何优化资源使用:

  • 共享对象:享元模式通过共享尽可能多的对象来减少内存占用。对于具有相同内部状态的对象,享元模式只创建一个实例,然后被多个客户端共享。
  • 减少对象创建:通过享元工厂来控制对象的创建,避免了不必要的对象实例化,从而减少了资源的浪费。
  • 分离内部状态和外部状态:享元模式将对象的内部状态和外部状态分离。内部状态是共享的,而外部状态是特定于每个客户端的,并且不会影响其他客户端。
  • 按需加载:享元模式可以实现按需加载对象,即只有在需要时才创建对象,这有助于减少启动时的资源消耗。

使用场景:

享元模式特别适用于以下情况:

  • 当一个系统有大量相似对象时,这些对象的创建和维护成本很高。
  • 当对象的大部分状态都可以外部化,并且可以由对象的使用者提供时。
  • 当使用简单的工厂模式创建对象开销较大,或者对象的创建和销毁需要花费较多资源时。

代码示例(伪代码):

// 享元接口
interface Flyweight {
    void operation(String extrinsicState);
}

// 具体享元对象
class ConcreteFlyweight implements Flyweight {
    private intrinsicState; // 内部状态,可以共享

    public ConcreteFlyweight(int intrinsicState) {
        this.intrinsicState = intrinsicState;
    }

    public void operation(String extrinsicState) {
        // 操作内部状态和外部状态
        System.out.println("Operation on intrinsic state: " + intrinsicState + " with extrinsic state: " + extrinsicState);
    }
}

// 享元工厂
class FlyweightFactory {
    private HashMap<String, Flyweight> flyweights = new HashMap<>();

    public Flyweight getFlyweight(String key) {
        if (!flyweights.containsKey(key)) {
            flyweights.put(key, new ConcreteFlyweight(Integer.parseInt(key)));
        }
        return flyweights.get(key);
    }
}

// 客户端代码
FlyweightFactory factory = new FlyweightFactory();
Flyweight flyweightX = factory.getFlyweight("1");
Flyweight flyweightY = factory.getFlyweight("1");

flyweightX.operation("Additional information X");
// 输出: Operation on intrinsic state: 1 with extrinsic state: Additional information X

flyweightY.operation("Additional information Y");
// 输出: Operation on intrinsic state: 1 with extrinsic state: Additional information Y

在这个示例中,ConcreteFlyweight 是具体的享元对象,它有一个内部状态 intrinsicState,这个状态是共享的。FlyweightFactory 是享元工厂,它管理享元对象的创建和存储。客户端通过工厂来获取享元对象,如果对象已经存在,则工厂返回现有的对象,从而避免了重复创建。通过这种方式,享元模式优化了资源使用,减少了内存占用。

十四、请解释行为型模式中的观察者模式和状态模式的区别。

观察者模式(Observer Pattern)和状态模式(State Pattern)都是行为型设计模式,它们各自解决不同的设计问题,具有不同的结构和用途。下面是两种模式的详细解释和它们之间的主要区别:

观察者模式:

观察者模式定义了对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都会得到通知并自动更新。

特点:

  • 主题(Subject)拥有一组观察者(Observer),并在状态改变时通知它们。
  • 观察者模式主要用于实现分布式的事件处理系统。

组成部分:

  • 主题(Subject):维护观察者列表,提供添加、删除和通知观察者的方法。
  • 观察者(Observer):定义了一个更新接口,用于接收主题状态改变的通知。

使用场景:

  • 当一个对象的改变需要同时改变其他对象时,且这些对象可能有很多,而且彼此之间不应该知道对方的存在。

状态模式:

状态模式允许一个对象在其内部状态改变时改变它的行为,看起来好像改变了其类。

特点:

  • 状态模式通过将每个状态封装为一个类,来实现状态的转换逻辑。
  • 状态模式主要用于实现状态机。

组成部分:

  • 状态(State):定义了一个接口,包含一个或多个行为(方法)。
  • 具体状态(Concrete State):实现状态接口,定义具体的状态行为。
  • 上下文(Context):包含一个状态对象引用,负责与状态相关的行为。

使用场景:

  • 当一个对象的行为取决于其状态,且它的状态值在运行时可以改变时。

观察者模式与状态模式的区别:

  1. 目的不同

    • 观察者模式用于对象间的通信,确保当一个对象状态改变时,所有依赖它的对象都会得到通知。
    • 状态模式用于行为随状态改变而改变的场景,实现状态转换逻辑。
  2. 结构不同

    • 观察者模式包含主题和观察者两个主要角色,主题维护观察者列表并负责通知它们。
    • 状态模式包含上下文、状态以及具体状态三个角色,上下文持有状态对象并根据状态改变行为。
  3. 关注点不同

    • 观察者模式关注的是如何在对象间传递消息或事件。
    • 状态模式关注的是如何根据对象的状态改变其行为。
  4. 使用场景不同

    • 观察者模式适用于事件多播问题,如模型-视图-控制器(MVC)架构中的观察者模式。
    • 状态模式适用于状态机问题,如用户界面的不同状态(如正常、暂停、退出)。
  5. 实现方式不同

    • 观察者模式通常通过注册和注销观察者,以及在主题中维护观察者列表来实现。
    • 状态模式通常通过在上下文中维护对当前状态对象的引用,并在状态对象中实现状态转换逻辑来实现。

总结来说,观察者模式和状态模式虽然都是行为型模式,但它们的设计目的、结构组成、关注点和使用场景都有所不同。观察者模式用于对象间的事件通知,而状态模式用于根据状态改变行为。

标签:享元,状态,面试题,20,对象,观察者,模式,设计模式,客户端
From: https://blog.csdn.net/weixin_42922481/article/details/139824931

相关文章