每次我遇到单例模式或任何静态类(即具有(几乎)只有静态成员的类)的实现时,我想知道这是否实际上不是一个 hack,因此严重滥用类和实例的原则只是为了设计单个对象,而不是设计类和创建单个实例。对我来说,看起来类的静态成员通常会尝试向类添加一些他们实际上不应该拥有的特性,而是让它们自己反对。
但是这样实现单个对象真的很可取吗?还是您对事物的看法完全不同,并且认为此类静态类或单例与实际对象没有任何共同之处?
每次我遇到单例模式或任何静态类(即具有(几乎)只有静态成员的类)的实现时,我想知道这是否实际上不是一个 hack,因此严重滥用类和实例的原则只是为了设计单个对象,而不是设计类和创建单个实例。对我来说,看起来类的静态成员通常会尝试向类添加一些他们实际上不应该拥有的特性,而是让它们自己反对。
但是这样实现单个对象真的很可取吗?还是您对事物的看法完全不同,并且认为此类静态类或单例与实际对象没有任何共同之处?
静态成员实际上只是全局变量的命名空间,是的。没有错; 命名空间很好,全局变量是完成某些任务的最干净的方式。
单例可能更有趣(按需加载...),但它们是类似的构造(是的,您可以将静态成员视为由编译器管理的匿名单例)。
像大多数事情一样,这些工具也有自己的位置,只有理论家担心它们是否“适合”特定的意识形态。
根据您的语言,类是对象。在 ruby 和 java 中,它们属于 Class;在python中,我不记得(类型的子类?)。
在java中,你不能避免把东西放在类上。这意味着您有时必须像使用命名空间和模块一样使用类。Math 上的许多静态方法就是一个很好的例子。我会说让这些方法是静态的可以充分利用糟糕的情况。
我认为拥有静态属性是否“肮脏”在很大程度上取决于上下文。您真正应该寻找的是适当的封装:如果您可以在代码的概念空间中绘制一条曲线并说“这一侧的一切都不需要知道关于那一侧的任何事情,除了跨越的接口曲线。
您可以从性能和内存的角度来查看它。例如,在以下代码中:
public class StringUtils
{
public static boolean isEmpty(String value)
{
// some code
}
public static String reverseString(String value)
{
// some code
}
}
你真的想在所有地方实例化 StringUtils 对象只是为了调用一个不存储任何成员变量的方法吗?在一个简单的程序中,这并不重要。但是一旦你的程序开始达到一定的大小并且你调用这些方法数千次,那么让我们只是实例化可以加起来。为什么?做一个纯粹主义者?这不值得。只需使用相同的实例。
假设我有一个具有单个配置文件的应用程序。如果我的语言不支持类之外的全局函数(如 Java 或 C#),我将如何创建函数以在不使用“单例”的情况下对该文件进行操作?
在我看来,实现这一目标的唯一真正方法是开设一个单例课程。使用单例模式,您也不需要传递指向对象的指针,因为您可以使用静态方法再次获取它。
我看不出这违反了任何面向对象的原则。以不同的方式来做,比如将配置函数放在另一个不处理配置的类(如“实用程序”类)中,这更像是违反 OO 原则。
假设您有一个需要中央数据存储库的多线程应用程序。消费者和生产者使用或放入存储库中的数据,包括通过接口访问存储库的外部应用程序对象。
如果您将此存储库设为普通类对象,您将遇到初始化它并获取指向每个需要它的对象的指针的问题。不是最棘手的问题,但它可能会与许多线程和对象混淆。
另一方面,如果你这样做:
public enum Data implements MyInterface{
INSTANCE;
private final Whatevertype secretstuff = new Whatevertype();
...etc...
public void PutThing( Sometype indata){ ... };
public Sometype GetThing( int somecode ){ ...};
...etc...
}
您(a)不必实例化任何东西,并且(b)可以从任何地方访问
Data.INSTANCE.GetThing(42);
等等,就像汉兰达一样......只能有一个