您的位置:首页 > 其它

模式的混合-我們真的需要一次一次的讀配置嗎-MultitonPrototypeFactoryMethod

2016-05-25 10:49 197 查看

我們真的需要一次一次的讀配置嗎

通過配置文件,我們其實極大地優化了代碼的結構,很多易變的元素都可以通過配置來修訂.

配置文件是一個文件,那麼使用的時候不可避免的涉及到IO操作.

在內存不值錢的今天,我們到底是讀內存快還是讀文件快?

電腦存儲交互的情況下,不是也有緩存的結構嗎?

想解決的問題

減少對配置文件的訪問

讀配置的過程一次完成

讀配置改為讀內存

Prototype Multiton FactoryMethod

配置中的每個element,其實就是一個節點(XmlNode).如果把每個節點抽象成一個對象,我們其實是如何使用這個對象的?我們當然是只需要使用它的副本就好,這裡使用Prototype來作為節點的拷貝母體.

我們讀配置文件的時候需要使用一個Name來定位element,那麼我們當然也可以使用一個傳入的Name參數來需求一個工廠(FactoryMethod)幫我們生成prototype的拷貝對象.

所有節點在結構上是一個平行的關係,我們可以認為都是具有Name和Value屬性的,並且具有有限的個數,那麼我們當然可以使用多例(Multiton)來負載他.

圖解這個結構



1.我們寫一個配置文件,包含了一個數據庫連接字符串和一個文件的路徑配置

<?xml version="1.0" encoding="utf-8" ?>
<Myconfig>
<targets>
<database>"Data Source=(LocalDb)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\aspnet-WebApplication_Collection-20150925030318.mdf;Initial Catalog=aspnet-WebApplication_Collection-20150925030318;Integrated Security=True"</database>
<fileurl>"http://www.cnblogs.com/news/"</fileurl>
</targets>
</Myconfig>

2.我們為 [database] 和[fileurl]節點創建原型(prototype)

interface IConfigPrototype
{
IConfigPrototype Clone();
string GetName();
string GetValue();
}

class ConfigDatabasePrototype: ConfigPrototype, IConfigPrototype
{
public string Name { private get; set; }
public string ConnectionString { private get; set; }

public ConfigDatabasePrototype()
{

XmlNode _xn = base.ReadConfigFile("database");
Name = _xn.Name;
ConnectionString = _xn.InnerText;
}

public IConfigPrototype Clone()
{
return (IConfigPrototype)this.MemberwiseClone();
}

public string GetName()
{
return Name;
}

public string GetValue()
{
return ConnectionString;
}
}

class ConfigFileurlPrototype: ConfigPrototype, IConfigPrototype
{
public string Name { private get; set; }
public string Address { private get; set; }

public ConfigFileurlPrototype()
{
XmlNode _xn = base.ReadConfigFile("fileurl");
Name = _xn.Name;
Address = _xn.InnerText;
}

public IConfigPrototype Clone()
{
return (IConfigPrototype)this.MemberwiseClone();
}

public string GetName()
{
return Name;
}

public string GetValue()
{
return Address;
}
}

3.在原型(Prototype)中,我們需要處理對xml文件的讀的過程,且這個過程是共同的,所以我們抽象出一個層次來實現這個操作.這樣通過繼承關係可以使ConfigDatabasePrototype(database的原型)和ConfigFileurlPrototype(fileurl的原型)具有了這個實現.

abstract class ConfigPrototype
{
public XmlNode ReadConfigFile(string Cname)
{
//return System.Configuration.ConfigurationManager.AppSettings[Cname];
XmlDocument _doc = new XmlDocument();
_doc.Load("../../MyConfig.xml");
string xPath = "/Myconfig/targets/"+ Cname;
XmlNode _xm = _doc.SelectNodes(xPath).Cast<XmlNode>().SingleOrDefault();
return _xm;
}
}

4.使用一個工廠方法(FactoryMethod)來依據Name參數返回對應的原型對象的拷貝

public IConfigPrototype ConfigFactoryMethod(string Name)
{
IConfigPrototype _prototype =null;
switch (Name)
{
case "database":
_prototype = _configDatabasePrototype.Clone();
break;
case "fileurl":
_prototype = _configFileurlPrototype.Clone();
break;
default:
break;
}
return _prototype;
}

5.使用一個多例(Multiton)來容納這兩個原型對象(Prototype)

class ConfigMultiton
{
protected static IConfigPrototype _configDatabasePrototype = new ConfigDatabasePrototype();
protected static IConfigPrototype _configFileurlPrototype = new ConfigFileurlPrototype();

private static ConfigMultiton _configMutiton = new ConfigMultiton();

private ConfigMultiton() { }

public static ConfigMultiton GetInstance()
{
return _configMutiton;
}

public IConfigPrototype ConfigFactoryMethod(string Name) { IConfigPrototype _prototype =null; switch (Name) { case "database": _prototype = _configDatabasePrototype.Clone(); break; case "fileurl": _prototype = _configFileurlPrototype.Clone(); break; default: break; } return _prototype; }
}

測試用例

1.初始化完成後,Multiton中的元素準備完畢,如圖



2.通過IConfigPrototype中的約定的方法調用可以獲取Name和Value,如圖



3.測試用例如下,圖中那麼多都是Prototype的副本~



[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
IConfigPrototype _temp = ConfigMultiton.GetInstance().ConfigFactoryMethod("database");
IConfigPrototype _temp1 = ConfigMultiton.GetInstance().ConfigFactoryMethod("database");
IConfigPrototype _temp2 = ConfigMultiton.GetInstance().ConfigFactoryMethod("database");
IConfigPrototype _temp3 = ConfigMultiton.GetInstance().ConfigFactoryMethod("database");
IConfigPrototype _temp4 = ConfigMultiton.GetInstance().ConfigFactoryMethod("database");
IConfigPrototype _temp5 = ConfigMultiton.GetInstance().ConfigFactoryMethod("database");
IConfigPrototype _temp6 = ConfigMultiton.GetInstance().ConfigFactoryMethod("database");

IConfigPrototype _temp7 = ConfigMultiton.GetInstance().ConfigFactoryMethod("fileurl");
IConfigPrototype _temp8 = ConfigMultiton.GetInstance().ConfigFactoryMethod("fileurl");
IConfigPrototype _temp9 = ConfigMultiton.GetInstance().ConfigFactoryMethod("fileurl");
IConfigPrototype _temp10 = ConfigMultiton.GetInstance().ConfigFactoryMethod("fileurl");
IConfigPrototype _temp11 = ConfigMultiton.GetInstance().ConfigFactoryMethod("fileurl");
IConfigPrototype _temp12 = ConfigMultiton.GetInstance().ConfigFactoryMethod("fileurl");
IConfigPrototype _temp13 = ConfigMultiton.GetInstance().ConfigFactoryMethod("fileurl");

IConfigPrototype _temp14 = ConfigMultiton.GetInstance().ConfigFactoryMethod("database");
IConfigPrototype _temp15 = ConfigMultiton.GetInstance().ConfigFactoryMethod("fileurl");
IConfigPrototype _temp16 = ConfigMultiton.GetInstance().ConfigFactoryMethod("database");
IConfigPrototype _temp17 = ConfigMultiton.GetInstance().ConfigFactoryMethod("fileurl");
IConfigPrototype _temp18 = ConfigMultiton.GetInstance().ConfigFactoryMethod("database");
IConfigPrototype _temp19 = ConfigMultiton.GetInstance().ConfigFactoryMethod("fileurl");
IConfigPrototype _temp20 = ConfigMultiton.GetInstance().ConfigFactoryMethod("database");
}
}

代碼下載

http://files.cnblogs.com/files/aaron-clark-aic/PrototypeFactoryMethodMultiton-Config.zip

Note: 點讚的隨意,點反對的留言
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: