在Java中创建和管理可由不同用户访问的类的唯一实例
我有一个编程问题,我想知道它是否可以用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
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);
}
}
}