对于想了解在PHP5中创建Singleton设计模式的读者,本文将是一篇不可错过的文章,我们将详细介绍php设计模式如何实现,并且为您提供关于1.4、设计模式[创建型]-单例模式(SingletonP
对于想了解在PHP5中创建Singleton设计模式的读者,本文将是一篇不可错过的文章,我们将详细介绍php设计模式如何实现,并且为您提供关于1.4、设计模式 [创建型]-单例模式(Singleton Pattern)、android – 使用Singleton设计模式正确打开/关闭数据库、C ++ Singleton设计模式、C#设计模式之Singleton模式的有价值信息。
本文目录一览:- 在PHP5中创建Singleton设计模式(php设计模式如何实现)
- 1.4、设计模式 [创建型]-单例模式(Singleton Pattern)
- android – 使用Singleton设计模式正确打开/关闭数据库
- C ++ Singleton设计模式
- C#设计模式之Singleton模式
在PHP5中创建Singleton设计模式(php设计模式如何实现)
一个人如何使用PHP5类创建Singleton类?
答案1
小编典典/** * Singleton class * */final class UserFactory{ /** * Call this method to get singleton * * @return UserFactory */ public static function Instance() { static $inst = null; if ($inst === null) { $inst = new UserFactory(); } return $inst; } /** * Private ctor so nobody else can instantiate it * */ private function __construct() { }}
使用方法:
$fact = UserFactory::Instance();$fact2 = UserFactory::Instance();
$fact == $fact2;
但:
$fact = new UserFactory()
引发错误。
请参阅http://php.net/manual/zh-
CN/language.variables.scope.php#language.variables.scope.static了解静态变量范围以及为什么设置static $inst = null;
有效。
1.4、设计模式 [创建型]-单例模式(Singleton Pattern)
单例模式
单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。
这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。
注意:
- 1、单例类只能有一个实例。
- 2、单例类必须自己创建自己的唯一实例。
- 3、单例类必须给所有其他对象提供这一实例。
介绍
**意图:**保证一个类仅有一个实例,并提供一个访问它的全局访问点。
**主要解决:**一个全局使用的类频繁地创建与销毁。
**何时使用:**当您想控制实例数目,节省系统资源的时候。
**关键代码:**构造函数是私有的。
优点:
- 1、在内存里只有一个实例,减少了内存的开销,尤其是频繁的创建和销毁实例(比如管理学院首页页面缓存)。
- 2、避免对资源的多重占用(比如写文件操作)。
**缺点:**没有接口,不能继承,与单一职责原则冲突,一个类应该只关心内部逻辑,而不关心外面怎么样来实例化。
使用场景:
- 1、要求生产唯一序列号。
- 2、创建的一个对象需要消耗的资源过多,比如 I/O 与数据库的连接等。
**注意事项:**getInstance() 方法中需要使用同步锁 synchronized (Singleton.class) 防止多线程同时进入造成 instance 被多次实例化。
实现
懒汉式
public class Singleton {
private static Singleton instance;
private Singleton (){}
public static synchronized Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
饿汉式
public class Singleton {
private static Singleton instance = new Singleton();
private Singleton (){}
public static Singleton getInstance() {
return instance;
}
}
双检锁
public class Singleton {
private volatile static Singleton singleton;
private Singleton (){}
public static Singleton getSingleton() {
if (singleton == null) {
synchronized (Singleton.class) {
if (singleton == null) {
singleton = new Singleton();
}
}
}
return singleton;
}
}
android – 使用Singleton设计模式正确打开/关闭数据库
为了避免在每个请求中打开/关闭操作,我创建了一个使用Singleton设计模式扩展sqliteOpenHelper的类.这样,我确定只有一个sqliteOpenHelper实例,并且在所有应用程序生命周期(而不仅仅是活动生命周期)中只有一个到数据库的连接.
我也读了一些关于ContentProvider的文章,但我不知道这是一个更好的方法.
所以,这是我的Singleton类的主要逻辑(onCreate和onUpgrade删除):
public final class Basesqlite extends sqliteOpenHelper { private static Basesqlite mInstance = null; private sqliteDatabase db = null; public static Basesqlite getInstance(Context context) { if (mInstance == null) { mInstance = new Basesqlite(context.getApplicationContext(),dbnAME,DBVERSION); } return mInstance; } private Basesqlite(final Context context,final String name,final int version) { super(context,name,null,version); db = getWritableDatabase(); } @Override public synchronized void close() { if (mInstance != null) db.close(); } public Cursor getAllData() { String buildsql = "SELECT * FROM myTable"; return db.rawQuery(buildsql,null); } }
所以,要访问我的数据库,我做了:
Basesqlite basesqlite = Basesqlite.getInstance(context); basesqlite.getAllData();
它现在工作完美.但我的问题是关于close()方法.我真的不知道什么时候打电话.实际上,我的数据库实例对于我的应用程序的每个Activies都是一样的,所以我认为在onPause()方法中调用close()是一个坏主意,因为实例将会在( onStart()方法的下一个Activity.此外,我无法检测到我的应用程序的结束,即当屏幕上没有任何活动可见时.
有人可以给我一些关于这个问题的帮助吗?当数据库与ONE活动相关联时,我发现了一些答案,但对我的情况没有提供任何真正的提示.
解决方法
阅读是不同的.当您在手机上创建sqlite数据库时,数据是持久的.数据库存在,您创建的处理程序提供了访问该信息的便捷方式.读取数据库通常通过获取数据库的可读实例并使用Cursor来提取值来进行.在这种情况下,您完成后关闭光标,而不是数据库本身.
你是对的,你不应该在单独的活动的生命周期方法中关闭数据库连接.相反,如上所述,在执行该事务完成后,关闭在处理程序的方法中写入数据库的数据库连接.
C ++ Singleton设计模式
最近,我碰到了C ++的Singleton设计模式的实现/实现。它看起来像这样(我从现实生活的示例中采用了它):
// a lot of methods are omitted here
class Singleton
{
public:
static Singleton* getInstance( );
~Singleton( );
private:
Singleton( );
static Singleton* instance;
};
从该声明中,我可以推断出实例字段是在堆上初始化的。这意味着存在内存分配。对我来说,完全不清楚的是何时确切地将要释放内存?还是有错误和内存泄漏?似乎实现中存在问题。
我的主要问题是,如何以正确的方式实施它?
C#设计模式之Singleton模式
前言
Singleton是二十三个设计模式中比较重要也比较经常使用的模式。但是这个模式虽然简单,实现起来也会有一些小坑,让我们一起来看看吧!
实现思路
首先我们看看这个设计模式的UML类图。
很清晰的可以看到,有三点是需要我们在实现这个模式的时候注意的地方。
- 私有化的构造器
- 全局唯一的静态实例
- 能够返回全局唯一静态实例的静态方法
其中,私有化构造器是防止外部用户创建新的实例而静态方法用于返回全局唯一的静态实例供用户使用。原理清楚了,接下来我们看看一些典型的实现方式和其中的暗坑。
实现方法
最简单的实现方法
最简单的实现方法自然就是按照UML类图直接写一个类,我们看看代码。
class Program { static void Main(string[] args) { var single1 = Singleton.Instance; var single2 = Singleton.Instance; Console.WriteLine(object.ReferenceEquals(single1, single2)); Console.ReadLine(); } } class Singleton { private static Singleton _Instance = null; private Singleton() { Console.WriteLine("Created"); } public static Singleton Instance { get { if (_Instance == null) { _Instance = new Singleton(); } return _Instance; } } public void DumbMethod() { } }
这段代码忠实的实现了UML类图里面的一切,查看输出结果,
证实了Singleton确实起了作用,多次调用仅仅产生了一个实例,似乎这么写就可以实现这个模式了。但是,真的会那么简单吗?
如果多线程乱入?
现在我们给刚刚的例子加点调料,假设多个对实例的调用,并不是简单的,彬彬有礼的顺序关系,二是以多线程的方式调用,那么刚刚那种实现方法,还能从容应对吗?让我们试试。把Main函数里面的调用改成这样。
static void Main(string[] args) { int TOTAL = 10000; Task[] tasks = new Task[TOTAL]; for (int i = 0; i < TOTAL; i++) { tasks[i] = Task.Factory.StartNew(() => { Singleton.Instance.DumbMethod(); }); } Task.WaitAll(tasks); Console.ReadLine(); }
通过Factory创造出1万个Task,几乎同时去请求这个单例,看看输出。
咦,我们刚刚写的Singleton模式失效了,这个类被创造了5次(这段代码运行多次,这个数字不一定相同),一定是多线程搞的鬼,我们刚刚写的代码没有办法应对多线程,换句话说,是非线程安全的(thread-safe),那有没有办法来攻克这个难关呢?
线程安全的单例模式
Lock版本
提到线程安全,很多同学第一反应就是用lock,不错,lock是个可行的办法,让我们试试。添加一个引用类型的对象作为lock对象,修改代码如下(什么?你问我为什必须是引用类型的对象而不能是值类型的对象?因为lock的时候,如果对象是值类型,那么lock仅仅锁住了它的一个副本,另外一个线程可以畅通无阻的再次lock,这样lock就失去了阻塞线程的意义)
private static object _SyncObj = new object(); public static Singleton Instance { get { lock (_SyncObj) { if (_Instance == null) { _Instance = new Singleton(); } return _Instance; } } }
运行一下,输出
只有一个实例创建,证明Lock起作用了,这个模式可行!不过有些不喜欢用Lock的同学可能要问,还有没有其他办法呢?答案是有的。
静态构造器版本
回想一下,C#中的类静态构造器,只会在这个类第一次被使用的时候调用一次,天然的线程安全,那我们试试不用Lock使用类静态构造器?修改Singleton类如下:
class Singleton { private static Singleton _Instance = null; private Singleton() { Console.WriteLine("Created"); } static Singleton() { _Instance = new Singleton(); } //private static object _SyncObj = new object(); public static Singleton Instance { get { return _Instance; } } public void DumbMethod() { } }
去掉了Lock,添加了一个类静态构造器,试一试。
完美!对于不喜欢用Lock(在这个例子中,实例只会创建一次但是之后的所有线程都要先排队Lock再进入Critical code进行检查,效率比较低下)的同学,类静态构造器提供了一种很好的选择。
不过俗话说,人心苦不足 , 我们总是追求卓越。这个版本比Lock版本似乎更好一点,那还有没有更好的版本呢?有的。
Lazy版本
从net 4.0开始,C#开始支持延迟初始化,通过Lazy关键字,我们可以声明某个对象为仅仅当第一次使用的时候,再初始化,如果一直没有调用,那就不初始化,省去了一部分不必要的开销,提升了效率。如果你不熟悉Lazy或者想更多了解它,请参考。我们今天关注的重点在于,Lazy也是天生线程安全的,所以我们尝试用它来实现Singleton模式?修改代码如下:
class Singleton { private static Lazy<Singleton> _Instance = new Lazy<Singleton>(() => new Singleton()); private Singleton() { Console.WriteLine("Created"); } public static Singleton Instance { get { return _Instance.Value; } } public void DumbMethod() { } }
输出结果中可以看到,我们达到了想要的效果:
在上面的代码中,私有变量_Instance现在是被声明为延迟初始化,这样不但天然实现了线程安全,同时在没有调用Instance静态方法的时候(也即没有调用_Instance.Value),初始化不会发生,这样就提高了效率。
总结
Singleton模式很常见,实现起来也很简单,只是要小心线程安全。以上三种方法都可以实现线程安全的Singleton模式。如果net 版本在4.0之上,建议使用Lazy版本,毕竟对比Lock版本,Lazy版本可以免去实现手动Lock之苦,对比Static版本,又有延迟初始化的性能优势,何乐而不为呢?
以上就是C#设计模式之Singleton模式的详细内容,更多关于C#中的Singleton模式的资料请关注其它相关文章!
- 快速学习C# 设计模式之职责链模式
- 深入了解c# 设计模式之简单工厂模式
- c#设计模式之单例模式的实现方式
- C#设计模式之Facade外观模式解决天河城购物问题示例
- C#设计模式之Builder生成器模式解决带老婆配置电脑问题实例
- 深入了解C#设计模式之订阅发布模式
关于在PHP5中创建Singleton设计模式和php设计模式如何实现的介绍已经告一段落,感谢您的耐心阅读,如果想了解更多关于1.4、设计模式 [创建型]-单例模式(Singleton Pattern)、android – 使用Singleton设计模式正确打开/关闭数据库、C ++ Singleton设计模式、C#设计模式之Singleton模式的相关信息,请在本站寻找。
本文标签: