我并不想创建一个关于单比静态比全球要好,等我看了几十个关于SO类似问题的问题,但我不能想出一个回答这个具体问题更好的讨论,所以我希望有人可以用一个(或多个)真实的简单例子来回答这个问题,而不仅仅是理论上的讨论.
在我的应用程序中,我有一个典型的DB类来抽象数据库层并在数据库上执行任务而无需在代码中随处写入mysql_connect / mysql_select_db / mysql...
我可以把这个类写成静态类:
class DB
{
private static $connection = FALSE; //connection to be opened
//DB connection values
private static $server = NULL; private static $usr = NULL; private static $psw = NULL; private static $name = NULL;
public static function init($db_server, $db_usr, $db_psw, $db_name)
{
//simply stores connections values, without opening connection
}
public static function query($query_string)
{
//performs query over alerady opened connection, if not open, it opens connection …Run Code Online (Sandbox Code Playgroud) 好的,我阅读了一些文章/示例如何在单例中编写实体管理器工厂.
其中一个对我来说最容易理解:
http://javanotepad.blogspot.com/2007/05/jpa-entitymanagerfactory-in-web.html
我了解到EntityManagerFactory(EMF)应该只在应用程序范围内创建一次.
并确保在使用后关闭EMF(?)
所以我编写了EMF helper类来使用的业务方法:
public class EmProvider {
private static final String DB_PU = "KogaAlphaPU";
public static final boolean DEBUG = true;
private static final EmProvider singleton = new EmProvider();
private EntityManagerFactory emf;
private EmProvider() {}
public static EmProvider getInstance() {
return singleton;
}
public EntityManagerFactory getEntityManagerFactory() {
if(emf == null) {
emf = Persistence.createEntityManagerFactory(DB_PU);
}
if(DEBUG) {
System.out.println("factory created on: " + new Date());
}
return emf;
}
public void closeEmf() {
if(emf.isOpen() || emf …Run Code Online (Sandbox Code Playgroud) 编辑:对不起,我的问题不明确,为什么书籍/文章更喜欢实施#1而不是实施#2?
使用指针实现Singleton类与使用静态对象的实际优势是什么?为什么大多数书都喜欢这个
class Singleton
{
private:
static Singleton *p_inst;
Singleton();
public:
static Singleton * instance()
{
if (!p_inst)
{
p_inst = new Singleton();
}
return p_inst;
}
};
Run Code Online (Sandbox Code Playgroud)
在此
class Singleton
{
public:
static Singleton& Instance()
{
static Singleton inst;
return inst;
}
protected:
Singleton(); // Prevent construction
Singleton(const Singleton&); // Prevent construction by copying
Singleton& operator=(const Singleton&); // Prevent assignment
~Singleton(); // Prevent unwanted destruction
};
Run Code Online (Sandbox Code Playgroud) 我正在做一些关于单身人士的研究,特别是关于单身人士的懒惰与急切初始化.
急切初始化的一个例子:
public class Singleton
{
//initialzed during class loading
private static final Singleton INSTANCE = new Singleton();
//to prevent creating another instance of Singleton
private Singleton(){}
public static Singleton getSingleton(){
return INSTANCE;
}
}
Run Code Online (Sandbox Code Playgroud)
但如上所示,它是急切的初始化和线程安全留给jvm但现在,我希望有相同的模式,但延迟初始化.
所以我想出了这个方法:
public final class Foo {
private static class FooLoader {
private static final Foo INSTANCE = new Foo();
}
private Foo() {
if (FooLoader.INSTANCE != null) {
throw new IllegalStateException("Already instantiated");
}
}
public static Foo getInstance() {
return FooLoader.INSTANCE;
}
}
Run Code Online (Sandbox Code Playgroud)
如上图所示 …
这是一个非常广泛的枚举单例代码:
public enum enumClazz{
INSTANCE
enumClazz(){
//do something
}
}
Run Code Online (Sandbox Code Playgroud)
和一堆地方说这是一个懒惰的初始化.但在阅读" Java虚拟机内部"第7章- 类型的生命周期后,我感到困惑:
Java虚拟机规范为类和接口加载和链接的时序提供了实现的灵活性,但严格定义了初始化的时间.所有实现必须在其第一次活动使用时初始化每个类或接口.以下六种情况符合有效用途:
- 创建一个类的新实例(在字节码中,执行新指令.或者,通过隐式创建,反射,克隆或反序列化.)
- 调用由类声明的静态方法(在字节码中,执行invokestatic指令)
- 使用或赋值由类或接口声明的静态字段,除了最终的静态字段并由编译时常量表达式初始化(在字节码中,执行getstatic或putstatic指令)
- 在Java API中调用某些反射方法,例如Class类中的方法或java.lang.reflect包中的类
- 初始化类的子类(类的初始化需要事先初始化其超类.)
- 在Java虚拟机启动时将类指定为初始类(使用main()<方法)
粗体风格的第三点澄清了如果字段是static final,则字段的初始化发生在编译时.同样,INSTANCEin enumClazz隐含地等于public static final并符合第三点.
如果我的理解错了,有人可以纠正我吗?
今天在我的采访中,一位采访者让我写了一个Singleton课程.我给出了答案
public class Singleton {
private static Singleton ref;
private Singleton() {
}
public static Singleton getInstance() {
if (ref == null) {
ref = new Singleton();
}
return ref;
}
}
Run Code Online (Sandbox Code Playgroud)
突然他告诉我这是写作课的老方法.任何人都可以帮助我,为什么他这样说.
我有一个像这样的单身人士.
public class BookingFactory {
private final static BookingFactory instance;
static {
instance = new BookingFactory();
}
public static BookingFactory getInstance() {
return instance;
}
private BookingFactory() {
System.out.println("Object is created.");
}
}
public class Test {
BookingFactory instance = BookingFactory.getInstance();
instance = BookingFactory.getInstance();
Class<?> clazz = Class.forName("com.test.BookingFactory");
Constructor pvtConstructor = clazz.getDeclaredConstructors()[0];
// Set its access control
pvtConstructor.setAccessible(true);
// Invoke Private Constructor
BookingFactory notSingleton = (BookingFactory) pvtConstructor.newInstance(null);
}
Run Code Online (Sandbox Code Playgroud)
当我运行它时,我看到了多条打印输出消息.有没有办法阻止这个单例从这个反射中被多次实例化?
谢谢.
可能重复:
谁需要单身人士?
我总是写最佳实践,但我也想了解为什么给定的东西是最佳实践.
我读过一篇文章(遗憾的是我不记得),单例类更喜欢被实例化,而不是用静态函数创建并使用范围解析运算符(::)进行访问.因此,如果我有一个包含所有要验证的工具的类,简而言之:
class validate {
private function __construct(){}
public static function email($input){
return true;
}
}
Run Code Online (Sandbox Code Playgroud)
我被告知这被认为是不好的做法(或者至少被警告过),因为有垃圾收集器和维护这样的东西.所以对"单体类作为静态方法"的批评是什么,我实例化一个类我100%肯定我只会实例化一次.对我来说,它似乎在做"双重工作",因为它已经准备好了.我错过了什么?
对此事有何看法?当然,这不是生死攸关的问题,但如果有选择的话,人们也可以做正确的事情:)
在我的项目中,每个用户交互事件都进行网络调用(即TCP,而不是HTTP).我需要活动指示灯是全球性的,以表明从随机UIViewController和 隐藏的NetworkActivityManager类(自定义的类来处理网络活动,这是没有的UIViewController或UIView的子类).
在搜索网络后,我发现MBProgressHUD用于同一目的,但我无法找到一个关于如何在全球范围内使用它的示例.(通过说全局我的意思是MBProgressHUD的单个对象和类方法来显示和隐藏它.)
以下是我的尝试,但是,失败了:在AppDelegate.h中:
@property (nonatomic, retain) MBProgressHUD *hud;
在AppDelegate.m中:
@synthesize hud;
在一些随机的UIViewController对象中:
appDelegate.hud = [MBProgressHUD showHUDAddedTo:appDelegate.navigationController.topViewController.view animated:YES];
appDelegate.hud.labelText = @"This will take some time.";
Run Code Online (Sandbox Code Playgroud)
在隐藏它的同时,从NetworkActivityManagerClass:
[MBProgressHUD hideHUDForView:appDelegate.navigationController.topViewController.view animated:YES];
Run Code Online (Sandbox Code Playgroud)
这使得项目在一段时间后崩溃(由于内存问题.)我在我的项目中使用ARC,而且,我正在使用ARC版本的MBProgressHUD.
我错过了什么吗?
重要问题:
我可以让MBProgressHUD像UIAlertView 一样工作吗?(说我的意思是独立于UIView 的MBProgressHUD的实现- 它用于showHUDAddedTo:呈现自己)?
请注意:在上面隐藏MBProgressHUD的代码中,View可能会改变显示MBProgressHUD时的状态.
任何帮助非常感谢.