<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>设计模式笔记开篇 on 冯威的博客</title><link>https://fwhyy.com/wiki/designpattern/</link><description>Recent content in 设计模式笔记开篇 on 冯威的博客</description><generator>Hugo</generator><language>zh-CN</language><atom:link href="https://fwhyy.com/wiki/designpattern/atom.xml" rel="self" type="application/rss+xml"/><item><title>设计模式笔记(2)---单件模式（创建型）</title><link>https://fwhyy.com/wiki/designpattern/Singleton/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://fwhyy.com/wiki/designpattern/Singleton/</guid><description>&lt;h2 id="gof-定义"&gt;Gof 定义&lt;/h2&gt;
&lt;p&gt;保证一个类仅有一个实例，并提供一个该实例的全局访问点&lt;/p&gt;
&lt;h2 id="动机"&gt;动机&lt;/h2&gt;
&lt;p&gt;保证在系统中只存在一个实例，这样才能保证逻辑的正确性和良好的效率&lt;/p&gt;
&lt;h2 id="单件模式单线程环境下实现"&gt;单件模式单线程环境下实现&lt;/h2&gt;
&lt;p&gt;看下面一段代码：&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;div class="chroma"&gt;
&lt;table class="lntable"&gt;&lt;tr&gt;&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code&gt;&lt;span class="lnt"&gt; 1
&lt;/span&gt;&lt;span class="lnt"&gt; 2
&lt;/span&gt;&lt;span class="lnt"&gt; 3
&lt;/span&gt;&lt;span class="lnt"&gt; 4
&lt;/span&gt;&lt;span class="lnt"&gt; 5
&lt;/span&gt;&lt;span class="lnt"&gt; 6
&lt;/span&gt;&lt;span class="lnt"&gt; 7
&lt;/span&gt;&lt;span class="lnt"&gt; 8
&lt;/span&gt;&lt;span class="lnt"&gt; 9
&lt;/span&gt;&lt;span class="lnt"&gt;10
&lt;/span&gt;&lt;span class="lnt"&gt;11
&lt;/span&gt;&lt;span class="lnt"&gt;12
&lt;/span&gt;&lt;span class="lnt"&gt;13
&lt;/span&gt;&lt;span class="lnt"&gt;14
&lt;/span&gt;&lt;span class="lnt"&gt;15
&lt;/span&gt;&lt;span class="lnt"&gt;16
&lt;/span&gt;&lt;span class="lnt"&gt;17
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;
&lt;td class="lntd"&gt;
&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-c#" data-lang="c#"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Singleton&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="n"&gt;Singleton&lt;/span&gt; &lt;span class="n"&gt;_instance&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;//定义为私有，让类的使用者不能直接new一个该类的实例&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="n"&gt;Singleton&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="n"&gt;Singleton&lt;/span&gt; &lt;span class="n"&gt;Instance&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;get&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_instance&lt;/span&gt; &lt;span class="p"&gt;==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;_instance&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Singleton&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;_instance&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;
&lt;/div&gt;
&lt;/div&gt;&lt;p&gt;上面的代码中将Singleton类的构造函数设置为私有，如果试图去用new去创建一个Singleton的实例，会出现编译错误&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;public class Test
{
 public static void Main()
 {
 //Singleton不可访问，因为他受保护级别限制
 Singleton t = new Singleton();
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;要创建Singleton的实例我们可以像下面这样做&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;public class Test
{
 public static void Main()
 {
 Singleton t = Singleton.Instance;
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;上面的代码完成了一个最简单的单例模式的实现，保证了实例的唯一性，如下的测试代码是可以顺利通过的&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[TestMethod()]
public void Test()
{
 Singleton t1 = Singleton.Instance;
 Singleton t2 = Singleton.Instance;

 Assert.AreEqual(true, t1.Equals(t2));
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Singleton模式的几个要点：&lt;/p&gt;
&lt;p&gt;Singleton模式中的实例构造器可以设置为protected以允许子类派生。
Singleton模式一般不要支持ICloneable接口，因为可能会导致多个对象实例。
Singleton模式一般不要支持序列化，因为也可能导致多个实例。
Singleton模式只考虑到对象创建的管理，没有考虑到对象销毁的管理，对支持垃圾回收的平台来讲，没有必要对销毁进行特殊的管理。&lt;/p&gt;
&lt;h2 id="单件模式多线程环境下实现"&gt;单件模式多线程环境下实现&lt;/h2&gt;
&lt;p&gt;在多线程环境下上面代码仍然有可能得到Singleton类的多个对象实例，为什么在多线程环境下会可能创建出多个实例呢？看下面代码：&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;public class Singleton
{
 private static Singleton _instance;
 //定义为私有，让类的使用者不能直接new一个该类的实例
 private Singleton() { }
 public static Singleton Instance
 {
 get
 {
 //线程A执行到此进行if判断，会进入到if语句里面
 //在线程A执行_instance = new Singleton(); 前，线程B也到了if判断处，
 //此时_instance还没有被创建出来仍然为null，线程B也会进入到if语句中
 //这样线程A和线程B会各自构建一个Singleton的实例
 if (_instance == null)
 {
 _instance = new Singleton();
 }
 return _instance;
 }
 }
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;所以上面的代码示例只能应用在单线程的环境下，如果需要实现在多线程环境下的单件模式就需要对上面的&lt;/p&gt;</description></item></channel></rss>