首页 > 解决方案 > 在层次结构中为每个类创建一个对象实例

问题描述

我在一次采访中被问到这个问题。

有 3 个类AB extends A& C extends B。我们必须设计符合这些约束的这些类

我建议了一种使用static Map<Class, Object>. 因此,例如,当有人打电话给它时new B(),它会检查 if map.contains(B.class)。如果是,则抛出异常;如果不是,则将实例保存在地图中并创建对象。

但下一个问题是我将如何对每个班级实施这种方法?根据我的方法,每个构造函数都必须仔细填充地图,否则它将打破约束。

我将如何解决这个问题?

标签: javaoopclass-design

解决方案


但下一个问题是我将如何对每个班级实施这种方法?根据我的方法,每个构造函数都必须仔细填充地图,否则它将打破约束。

只需将该地图及其周围的代码放入某个不同的实用程序类即可。这样您的每个班级都可以执行以下操作:

public WhateverClassConstructor() {
  synchroized(someLock) {
     SingeltonChecker.ensureUnique(this);

 public static void ensureUnique(Object objectToAdd) {
   Class<?> classToAdd = o.getClass();
   ...

鉴于 C 扩展 B 扩展 A 的事实,您可能只需要在类 A 的构造函数中调用。另一方面,假设您的第一次调用new C()导致 C 构造函数异常,但第二次调用不会. 当然,这本身就是一个问题,但问题仍然存在:如何确保在将对象添加到这样的映射之前完全正确地初始化它?!

因此:编写此类实用程序代码时需要考虑很多事情因此,我的回答将集中在给定设计点的不切实际,几乎是愚蠢的,并建议将其扔掉并寻求其他解决方案,例如简单的事情:

public enum SingletonObjectHolder {
  private final Object hold;
  A_INSTANCE(new A()), B_INSTANCE(new B())...

  public Object getSingleton() { return hold; }
  private SingletonObjectHolder(Object o) { hold = o };

不要浪费太多时间试图给人们一个技术性的答案,真正的重点是不要让自己陷入困境。并且不要误会:让基于地图的“单例”方法在各种情况下稳健且正确地工作,真的很难

换句话说:如果我在采访中问你这个问题,我想听到一个挑战那个可怕的设计点的答案。当然,您花了 10% 的时间为给定场景概述解决方案。但是要花 90% 的时间来解释为什么它如此糟糕,以及为什么其他解决方案会更好。


推荐阅读