在Java中创建和管理可由不同用户访问的类的唯一实例

在Java中创建和管理可由不同用户访问的类的唯一实例,java,oop,design-patterns,static-factory,Java,Oop,Design Patterns,Static Factory,我有一个编程问题,我想知道它是否可以用Java设计技术解决。我有班级服务和班级客户。客户机请求服务,如果该服务尚未存在,则将创建该服务,即新的服务对象。如果服务是由不同的客户机甚至同一客户机创建的,那么服务类将不会创建新对象。相反,如果尚未添加客户端,则可以将其添加到服务中。服务类的其他字段和方法将应用于同一服务的客户端 public class Service { private String service; private ArrayList<Integer> cli

我有一个编程问题,我想知道它是否可以用Java设计技术解决。我有班级服务和班级客户。客户机请求服务,如果该服务尚未存在,则将创建该服务,即新的服务对象。如果服务是由不同的客户机甚至同一客户机创建的,那么服务类将不会创建新对象。相反,如果尚未添加客户端,则可以将其添加到服务中。服务类的其他字段和方法将应用于同一服务的客户端

public class Service {

  private String service;
  private ArrayList<Integer> clients;
  //.... other field    

  public Service (String s){
    this.service = s;
    clients = new ArrayList<>;  
  } 

  public void addClient(int c){
    clients.add(c);
  }



  //..other methods

}

public class Client {

  private int clientID;
  private ArrayList<String> services;

  public Client(int id){
    clientID = id;
    services = new ArrayList<>;
  }

  public void addService(String s){
    services.add(s);
  }

  public void requestService() {
    for(int i=0; i<services.size();i++)
        Service s = new Service(services.get(i));
  } 

}

上述代码将阻止创建新的对象实例。但是,如果服务已经存在,因此返回null,那么新客户端就不能加入或使用该特定服务。

我认为您正在寻找的是典型的懒惰单例模式。我认为这是最好的方法,因为它是100%线程安全的

public class Service {

  // Private constructor. Prevents instantiation from other classes.
  private Service() {
  }

  // Initializes Service singleton.
  private static class SingletonHolder {

    private static final Service INSTANCE = new Service();
  }

  // gets the one and only instance of Service
  public static Service getInstance() {
    return SingletonHolder.INSTANCE;
  }
}
编辑:

查看静态工厂代码,看起来您实际上在寻找一个服务容器,该容器为特定的密钥服务名称提供一个且仅提供一个服务实例,或者为您传递的更好的类型安全性提供服务类。下面您将发现一个非常基本的非线程安全实现,它使用类作为键。如果你在谷歌上搜索线程安全的多音或类似内容,还有很多其他更好的线程安全实现。然而,如果你现在是一个新手,我强烈建议你使用a,它已经为你完成了全部工作,除了带来许多其他好处之外。我特别喜欢谷歌的Guice,但使用什么在很大程度上取决于你的项目。如果您需要帮助,我建议发布一个新的线程,其中包含您的项目的详细信息以及您需要此服务容器的目的

public class ServiceContainer {

  private final Map<Class<?>, Service> map = new HashMap<>();

  // Private constructor. Prevents instantiation from other classes.
  private ServiceContainer() {
  }

  // ServiceContainer singleton.
  private static class SingletonHolder {

    private static final ServiceContainer INSTANCE = new ServiceContainer();
  }

  // gets the one and only instance for a particular Service class
  @SuppressWarnings("unchecked")
  public static <T extends Service> T getInstance(final Class<T> serviceClass) {
    // init service if not initialized yet
    if (!SingletonHolder.INSTANCE.map.containsKey(serviceClass)) {
      SingletonHolder.INSTANCE.map.put(serviceClass, createService(serviceClass));
    }
    return (T)SingletonHolder.INSTANCE.map.get(serviceClass);
  }

  private static <T extends Service> T createService(final Class<T> serviceClass) {
    try {
      return serviceClass.newInstance();
    } catch (InstantiationException | IllegalAccessException e) {
      // please handle this exception properly
      throw new RuntimeException(e);
    }
  }
}

我认为你需要阅读关于工厂方法的任何文献中的下一段或两段。如果您的客户机可以同时发出请求,那么您将需要阅读多线程编程和线程安全代码。
public class ServiceContainer {

  private final Map<Class<?>, Service> map = new HashMap<>();

  // Private constructor. Prevents instantiation from other classes.
  private ServiceContainer() {
  }

  // ServiceContainer singleton.
  private static class SingletonHolder {

    private static final ServiceContainer INSTANCE = new ServiceContainer();
  }

  // gets the one and only instance for a particular Service class
  @SuppressWarnings("unchecked")
  public static <T extends Service> T getInstance(final Class<T> serviceClass) {
    // init service if not initialized yet
    if (!SingletonHolder.INSTANCE.map.containsKey(serviceClass)) {
      SingletonHolder.INSTANCE.map.put(serviceClass, createService(serviceClass));
    }
    return (T)SingletonHolder.INSTANCE.map.get(serviceClass);
  }

  private static <T extends Service> T createService(final Class<T> serviceClass) {
    try {
      return serviceClass.newInstance();
    } catch (InstantiationException | IllegalAccessException e) {
      // please handle this exception properly
      throw new RuntimeException(e);
    }
  }
}