一、開篇
其實我本來不是打算把系統(tǒng)架構(gòu)中的一些設(shè)計模式單獨抽出來講解的,因為很多的好朋友也比較關(guān)注這方面的內(nèi)容,所以我想通過我理解及平時項目中應(yīng)用到的一
些常見的設(shè)計模式,拿出來給大家做個簡單講解,我這里只是拋磚引玉,如果某個地方講解的不正確或者不詳細(xì),請大家批評指出。園子里面的很多的大牛寫的設(shè)計模式
都非常的經(jīng)典,我這里寫可能有點班門弄斧的感覺,不過我還是決定把它寫出來,希望能對初學(xué)者有一定的幫助和指導(dǎo)的作用。當(dāng)然我這里如果說某個地方解釋的有問
題或者說是某個地方寫的不符合邏輯之處,還請大家多多指出,提出寶貴意見。
軟件工程中其實有很多總結(jié)性的話語,比如說軟件=算法+數(shù)據(jù)結(jié)構(gòu)等等這樣的描述,當(dāng)然我們這里可能算法就是泛指一些軟件中的編程方法了,設(shè)計模式怎么去
理解呢?為什么要有設(shè)計模式?它能帶來什么?等等這些都是我們需要討論的問題。首先我們需要知道設(shè)計模式能帶來什么??赡苓@才是我們學(xué)習(xí)它的主要原因,如果
說不能為我們在書寫軟件的過程中帶來更方面的好處,那我們也不會使用和學(xué)習(xí)它。
設(shè)計模式是什么?
設(shè)計模式可以簡單的理解為解決某一系列問題的完美的解決方案。我們在軟件開發(fā)的過程中經(jīng)常遇到設(shè)計功能實現(xiàn)的問題,而設(shè)計模式正是為了解決軟件設(shè)計功能
實現(xiàn)時遇到的某一類問題的解決方案。因為一般情況下來說,我們在某個軟件功能的開發(fā)過程中遇到的功能設(shè)計問題,可能是前人很早就遇到過的問題,所以通過這種
設(shè)計模式的方式來解決,能讓我們在軟件實現(xiàn)的過程中少走彎路,或者說是給我們的軟件設(shè)計帶來很好的靈活性和適應(yīng)性。
設(shè)計模式帶來了什么?
設(shè)計模式是源于實踐,并且每種設(shè)計模式都包含了一個問題描述,問題涉及到的參與者并且提供了一個實際的解決方案。設(shè)計模式的好處我們可以通過下圖來簡單
說明:
當(dāng)然我這里可能總結(jié)還不完全,還請大家補充,我會更新這里面的內(nèi)容。當(dāng)然設(shè)
計模式帶來了這么多的好處,所以我們學(xué)習(xí)設(shè)計模式就顯得比較必要了,也是從事軟件開發(fā)及設(shè)計必須掌握的基本技能之一。
設(shè)計模式的簡單分類:
當(dāng)然這里可以簡單的分為這3大類,下面我們在講述的過程中將會分別講解,當(dāng)然我這里是以創(chuàng)建型模
式開始講解,我想創(chuàng)建型模式也是大家項目中必備的吧?下面我就從創(chuàng)建型模式先來講解。
二、摘要
本文將主要講解創(chuàng)建型模式中的單例模式先來講解,因為單例模式是最簡單也是最容易理解的設(shè)計模式,上手快,易使用的設(shè)計模式。本文將從下面的流程來講解
單例模式,后面講述的設(shè)計模式也將使用這樣的方式。
1、什么是單例模式?
2、單例模式的應(yīng)用場景。
3、舉例說明單例模式的使用。
4、總結(jié)單例模式的用法。
三、本文大綱
a、開篇。
b、摘要。
c、本文大綱。
d、單例模式的簡介。
e、相關(guān)應(yīng)用場景分析。
f、本文總結(jié)。
g、系列進(jìn)度。
h、下篇預(yù)告。
四、單例模式的簡介
本章我們將來講述下單例模式的使用,首先我們來看看單例模式的定義:
單例模式:是一種軟件設(shè)計中常用的設(shè)計模式,主要是用來控制某個類必須在某個應(yīng)用程序中只能有一個實例存在。
有時候我們需要確保整個系統(tǒng)中只有某個類的一個實例存在,這樣有利于我們協(xié)調(diào)控制系統(tǒng)的行為。例如:我們在某個系統(tǒng)中使用了發(fā)送短信的這樣的服務(wù),那么
我們可能希望通過單一的短信服務(wù)類的實例,而不是多個對象實例完成短信的發(fā)送服務(wù)。這時我們可以通過單例模式來完成。
上圖簡單描述了單例模式應(yīng)用的位置。
我們看看單例模式的幾種實現(xiàn)方式:
下面我們來舉例說明下這2種方式的實現(xiàn)。
1、外部控制的方式
public class Instance
{
private List<SendMessage> lists = new List<SendMessage>();
private SendMessage sendInstance;
public SendMessage SInstance
{
get
{
return sendInstance;
}
}
public void InstanceMethod()
{
if (lists.Count == 0)
{
sendInstance = new SendMessage();
lists.Add(sendInstance);
}
else
{
sendInstance = lists[0];
}
}
}
2、內(nèi)部控制方式
public class Instance1
{
private static SendMessage sendInstance;
private static object _lock = new object();
protected Instance1()
{
}
public static SendMessage SInstance
{
get
{
lock (_lock)
{
if (sendInstance == null)
sendInstance = new SendMessage();
return sendInstance;
}
}
}
}
這里有幾點需要注意的地方,對于第二種方式有幾個地方需要說明下,首先是要控制全局只有一個實例的類,請定義成靜態(tài)實例,這樣可以確保只有一個實例對
象,其次,這個對象的構(gòu)造函數(shù)請聲明成保護類型的成員,這樣可以屏蔽通過直接實例化的形式來訪問。通過這樣的形式,客戶可以不需要知道某個單例實例對象的內(nèi)
部實現(xiàn)細(xì)節(jié)。一般情況下滿足上面的2點需求就可以完成全局唯一訪問入口的控制。當(dāng)然可能在多線程的情況下采用這樣的形式還會有一定的弊端,當(dāng)然我們這里也簡單
的講解下相應(yīng)的控制方案。方案如下:
public class CoolInstance
{
private CoolInstance()
{
}
public static readonly CoolInstance Instance = new CoolInstance();
}
看吧很簡單吧,當(dāng)然我們這里來簡單解釋下原理:
1、我們先把構(gòu)造函數(shù)聲明為私有的構(gòu)造函數(shù),這樣我們能夠屏蔽外部通過實例化的形式訪問內(nèi)部的成員函數(shù)。所有的成員函數(shù)的訪問必須通過靜態(tài)成員Instance
來完成訪問。
2、這段代碼通過定義公共、靜態(tài)、只讀的成員相當(dāng)于在類被第一次使用時執(zhí)行構(gòu)造,由于是只讀的,所以一旦構(gòu)造后不允許修改,就不用擔(dān)心不安全的問題。
相信對上面的介紹大家應(yīng)該基本上知道單例模式的應(yīng)用了,那么下面我們來看看項目中的實際應(yīng)用場景及用法。
五、相關(guān)應(yīng)用場景講解
1、場景短信及郵件發(fā)送服務(wù)
那么我們將采用上面介紹的最“COOL”的方式來進(jìn)行控制,提供發(fā)送短信及發(fā)送郵件的服務(wù)。
public class CoolInstance
{
private CoolInstance()
{
}
public static readonly CoolInstance Instance = new CoolInstance();
/// <summary>
/// 發(fā)送手機短信
/// </summary>
public bool SendMessage(string telNumber,string content)
{
return true;
}
/// <summary>
/// 發(fā)送郵件
/// </summary>
/// <param name="content"></param>
/// <param name="toMail"></param>
public bool SendMail(string content,string toMail)
{
return true;
}
}
我們再來看看調(diào)用類中如何書寫完成調(diào)用。例如我們有個訂單類,當(dāng)有人新下訂單時,將給賣家發(fā)送短信提醒功能。
/// <summary>
/// 訂單業(yè)務(wù)
/// </summary>
public class Order
{
public int Save()
{
//先是將訂單的相關(guān)信息生成,
this.InitOrderInfo();
//執(zhí)行訂單的持久化方法
int count= this.Add();
//發(fā)送短信
CoolInstance.Instance.SendMessage(string.Empty, string.Empty);
//發(fā)送郵件
CoolInstance.Instance.SendMail(string.Empty, string.Empty);
return count;
}
/// <summary>
/// 初始化訂單信息
/// </summary>
private void InitOrderInfo()
{
}
/// <summary>
/// 新增訂單信息
/// </summary>
/// <returns></returns>
private int Add()
{
return 0;
}
}
這樣我們就完成了短信發(fā)送服務(wù)及郵件發(fā)送服務(wù)的控制。主要還是根據(jù)自己的業(yè)務(wù)需要。
2、例如我們現(xiàn)在提供一個系統(tǒng)日志服務(wù)或者打印或者掃描的服務(wù),我們希望全局只有一個訪問入口,那么我們就可以通過這樣的單例模式來實現(xiàn)這樣的需求。
public class PrintHelper
{
#region 構(gòu)造函數(shù)
private PrintHelper()
{
}
public static readonly PrintHelper Instance = new PrintHelper();
#endregion
#region 打印服務(wù)
/// <summary>
/// 直接打印服務(wù)
/// </summary>
/// <returns></returns>
public bool Print()
{
return true;
}
/// <summary>
/// 打印預(yù)覽
/// </summary>
/// <returns></returns>
public bool PrintPreview()
{
return true;
}
#endregion
}
具體的調(diào)用類我就不寫相應(yīng)的代碼,都和上面的形式類同,下面我們講解下可能更特殊的需求,有時候我們可能需要更新我們創(chuàng)建的唯一實例,這時我們?nèi)绾慰?/p>
制單例實例對象的更新呢,有時候可能我們有這樣的需求。下面我們來看看如何實現(xiàn)這樣的需求。
3、可更新單例對象的場景
首先我們先說下什么情況下會遇到這樣的更新方式呢?例如我們想在單例模式的類的構(gòu)造函數(shù)是帶有一定參數(shù)的情形時:
public class UpdateHelper
{
private string type = string.Empty;
private static object _lock = new object();
private static UpdateHelper instance;
private UpdateHelper(string valueType)
{
type = valueType;
}
public static UpdateHelper Instance
{
get
{
lock (_lock)
{
if (instance == null)
{
//如果這里有多個條件需求的話,可能寫起來會比較復(fù)雜,那么有更好的方式來處理嗎?
instance = new UpdateHelper("test!");
}
return instance;
}
}
}
}
那么我們來分析幾種辦法,有沒有更好的辦法來處理呢?
1、首先我們不能手動實例化,所以我們沒有辦法動態(tài)傳入構(gòu)造函數(shù)參數(shù),只能在類的內(nèi)部指定這個參數(shù),但是有時候我們需要動態(tài)的更新這個參數(shù),那么這樣的
形式顯然就沒有辦法實現(xiàn)。
2、通過屬性的方式,來動態(tài)的設(shè)置屬性的內(nèi)容來完成輸出參數(shù)的改變,但是這樣的方式可能太過自由,無法滿足單例模式的初衷。
3、接口方式,因為接口必須要靠類來實現(xiàn),所以更不靠譜,可以不考慮這樣的方式。
4、通過Attribute的方式來將信息動態(tài)的注入到構(gòu)造函數(shù)中,但是怎么說這樣的方式是不是太興師動眾了呢?畢竟單例模式本來就是很簡單的。
5、通過配置文件,通過config文件配置節(jié)點的形式來動態(tài)的配置相關(guān)信息,實現(xiàn)更新實例對象內(nèi)容的情況。
通過上面的5種情況的分析,那么通過2、4、5可以實現(xiàn)這個要求,但是對比相應(yīng)的代價來說,5的方式是最靈活也是最符合單例模式本來的規(guī)范要求,相對來說
成本和代價也可以接收。
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<system.Web>
<add key="ssss" >value</add>
</system.Web>
</configuration>
那么我們上面的單力模型中的代碼只需要稍微的變化下即可,請看如下代碼:
public class UpdateHelper
{
private string type = string.Empty;
private static object _lock = new object();
private static UpdateHelper instance;
private UpdateHelper(string valueType)
{
type = valueType;
}
public static UpdateHelper Instance
{
get
{
lock (_lock)
{
if (instance == null)
{
//如果這里有多個條件需求的話,可能寫起來會比較復(fù)雜,那么有更好的方式來處理嗎?
instance = new UpdateHelper(System.Configuration.ConfigurationManager.AppSettings["ssss"].ToString());
}
return instance;
}
}
}
}
我想到這里大家都對單例模式有個簡單的認(rèn)識了,本文的內(nèi)容就講到這里。我們來回顧下我們講述的內(nèi)容:
六、本文總結(jié)
本文主要講述了創(chuàng)建型模式中的單例模式,單例模式主要是用來控制系統(tǒng)中的某個類的實例的數(shù)量及全局的訪問入口點。我們主要講述了實現(xiàn)單例模式的方式,
分為外部方式及內(nèi)部方式,當(dāng)然我們現(xiàn)在采用的方式都是內(nèi)部方式,還講述了線程安全的單例模式及帶有參數(shù)的構(gòu)造函數(shù)的情況,根據(jù)配置文件來實現(xiàn)參數(shù)值的動態(tài)配
置的情況。希望本文的講解能對不熟悉設(shè)計模式的同仁能夠了解知道單例模式的應(yīng)用,而對已熟知單例模式的同仁可以溫故而知新,我會努力寫好這個系列,當(dāng)然我這
里可能在大牛的面前可能是班門弄斧吧,不過我會繼續(xù)努力,爭取寫出讓大家一看就明白的設(shè)計模式系列。本文錯誤之處再所難免,還請大家批評之處,我會繼續(xù)改
進(jìn)。
七、系列進(jìn)度
創(chuàng)建型
1、系統(tǒng)架構(gòu)技能之設(shè)計模式-單件模式
2、系統(tǒng)架構(gòu)技能之設(shè)計模式-工廠模式
3、系統(tǒng)架構(gòu)技能之設(shè)計模式-抽象工廠模式
4、系統(tǒng)架構(gòu)技能之設(shè)計模式-創(chuàng)建者模式
5、系統(tǒng)架構(gòu)技能之設(shè)計模式-原型模式
結(jié)構(gòu)型
1、系統(tǒng)架構(gòu)技能之設(shè)計模式-組合模式
2、系統(tǒng)架構(gòu)技能之設(shè)計模式-外觀模式
3、系統(tǒng)架構(gòu)技能之設(shè)計模式-適配器模式
4、系統(tǒng)架構(gòu)技能之設(shè)計模式-橋模式
5、系統(tǒng)架構(gòu)技能之設(shè)計模式-裝飾模式
6、系統(tǒng)架構(gòu)技能之設(shè)計模式-享元模式
7、系統(tǒng)架構(gòu)技能之設(shè)計模式-代理模式
行為型
1、系統(tǒng)架構(gòu)技能之設(shè)計模式-命令模式
2、系統(tǒng)架構(gòu)技能之設(shè)計模式-觀察者模式
3、系統(tǒng)架構(gòu)技能之設(shè)計模式-策略模式
4、系統(tǒng)架構(gòu)技能之設(shè)計模式-職責(zé)模式
5、系統(tǒng)架構(gòu)技能之設(shè)計模式-模板模式
6、系統(tǒng)架構(gòu)技能之設(shè)計模式-中介者模式
7、系統(tǒng)架構(gòu)技能之設(shè)計模式-解釋器模式
八、下篇預(yù)告
下篇我們將會介紹我們大家最熟知的工程模式,當(dāng)然我會更多的結(jié)合實例來講解每個設(shè)計模式的應(yīng)用場景及具體的實例,來更清晰的描述什么情況下用什么模
式,及每個模式之間的區(qū)別。大家的支持就是我書寫的動力,希望大家多多支持我吧!文章來源:http://www.zghlxwxcb.cn/news/detail-687542.html
轉(zhuǎn)自:https://www.cnblogs.com/hegezhou_hot/archive/2010/10/02/1841390.html文章來源地址http://www.zghlxwxcb.cn/news/detail-687542.html
到了這里,關(guān)于系統(tǒng)架構(gòu)技能之設(shè)計模式-單件模式的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!