单例和静态类案例研究
已经有人询问单例和静态类之间有什么区别。然而,知道了其中的区别,每次需要选择的时候我还是感到困惑。
因此,对于我自己,我定义了两种不同的情况 - 如果该类只有一个实例(这种情况很少),我主要对 POJO 类(在 java 中)使用单例,对所有服务类使用静态类(这种情况经常发生) )。
例如,在我的应用程序中,我需要存储消息(我有一个可序列化的消息类),将它们写入文件,从文件中读取并在运行时访问。我不认为这里有任何理由使用单例,静态类就可以了。唯一的静态类是 MessageStorage,它有 3 个函数 - 读取、写入和 getMessages,以及一个静态私有消息数组列表。
这种做法合理吗?如果不合理,它的问题是什么?
It was already asked what's the difference between singleton and static class. However, knowing the difference, I still feel confused every time I need to chose.
So for myself I defined two different cases - I'm using singletones mainly for POJO classes(in java) if there should be only one instance of this class(which is very rarely) and static classes for all service classes(which occur very often).
For example, in my application I need to store messages(I have a serializable class Message), write them into a file, read from a file and access during the runtime. I don't see any reason to use singleton here, static class is just okay. The only static class is MessageStorage which has 3 functions - read, write and getMessages and also one static private arraylist of messages.
Is this approach reasonable and if not, what's its problem?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
在 Java 中使用“单例”的两个主要原因是:
1)因此某些存储可以与其他“静态”类相关联。
2) 对于给定服务的不同子类(或接口实现),您可能有多个“单例”,并且单例作为识别要使用哪个特定服务的方式进行传递。
当然,您可以使用“静态”类的静态字段来包含数据,而不是#1,但使用主题类的单个实例来包含数据通常更方便(并且在许多情况下更有效)。数据,与作为其他类的实例的多个静态成员。
并且,关于 #2,在 JDK 中有许多情况,单个类以定义“常量”的形式实际上实现了多个“单例”。 (例如,java.awt.font.TextAttribute。)
一般来说,Java 中使用单例的动机比基于 C 的语言要少,因为 Java 确实实现了真正的类关联(和类保护)静态数据,而与C 语言中使用的模糊伪装(如果有的话)全局静态,因此可以在一个类中简单地拥有多个静态字段,而不需要有一个“中心”对象来包含 C 语言中的字段。
The two main reasons for using a "singleton" in Java are:
1) So some storage can be associated with an otherwise "static" class.
2) Where you may have multiple "singletons" for different subclasses (or interface implementations) of a given service, and the singleton is passed as a way of identifying which specific service to employ.
Of course, instead of #1 you can use static fields of a "static" class to contain the data, but it's often more convenient (and, in many cases, more efficient) to have a single instance of the subject class to contain the data, vs multiple static members which are instances of other classes.
And, re #2, there are a number of cases in the JDK of a single class implementing, in effect, multiple "singletons", in the guise of defining "constants". (Eg, java.awt.font.TextAttribute.)
In general, the motivation to have singletons is less in Java than in C-based languages, since Java does implement true class-associated (and class-protected) static data, vs the vaguely disguised (if disguised at all) global statics used in the C languages, and so one can simply have multiple static fields in a class vs the need to have a "central" object to contain the fields in the C languages.
理想的设计 :-)
无论如何,这就是现在很酷的孩子们正在做的事情......依赖注入而不是工厂,但一次一步......
The ideal design :-)
That's what the cool kids are doing now days, anyway... and dependency injection rather than a factory, but one step at a time...
这里真正要理解的是,c#/java 有不同的内存组。
所有类都将被加载到称为类加载器内存的内存部分中。如果您创建静态的东西,它会保留在类加载器内存中。可以从那里使用它,但只能有 1 个实例。类加载器内存没有垃圾收集器,所有内容在应用程序的生命周期中都保留在那里。
创建一个类的实例,无论它是否是单例,都意味着完成了内存复制,从类加载器内存中复制您的类并将其复制到存储实例的区域。实例可以被垃圾收集。
单例和静态类选项之间的实际决策点是:
1)您想要继承,还是您的类的接口(如果是这样,您想要单例)
2)强制您的类具有与应用程序相同的生命周期是否有意义(即您必须手动清除类或编写一个方法来执行此操作,这会不必要地增加代码,从而降低可维护性)。 (如果没有,那么你想要单例)
3) 您的应用程序是否需要可扩展性和更改潜力。如今,单例通常被认为是一种反模式,如果通过静态属性实现的话。原因是您投资于基础设施,例如在类上公开静态实例属性,这可能完全不是您将来想要的,因为您的单窗口应用程序可能会突然变成多窗口,并且您需要重写代码。 (重写代码表明设计不好,尤其是其核心基础设施)。
作为一般经验法则,我建议如下:
The thing to really understand here is that there are different groups of memory for c#/java.
All of your classes will be loaded into a section of memory called class loader memory. If you make something that is static, it remains there in class loader memory. It can be used from there, but only can have the 1 instance. There is no garbage collector for class loader memory, everything stays there for the life of the application.
Creating an instance of a class whether it be singleton or not means that a memory copy is done, copying your class from class loader memory and copying it to the area where instances are stored. Instances can be garbage collected.
The actual decision point between the option of singleton and static class is:
1) Do you want inheritance, or an interface for your class (if so you want singleton)
2) Does it make sense to force your class to have a lifecycle that is the same as your applications (ie you would have to manually clear the class or write a method to do it which unessasarily increases code, hence decreasing maintainability). (if it doesn't then you want singleton)
3) Does your Application require scalability, and potential for change. Singleton is often considered an anti-pattern nowadays, IF implemented via a static property. The reason for this is that you invest in infrastructure like exposing a static instance property on your class which might be entirely not what you want in the future because your single window application could suddenly become multi window and you need to rewrite code. (rewriting code is indicative of bad design, especially if its core infrastructure).
As a general rule of thumb, I would recommend the following: