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

  1. 通過配置文件,我們其實極大地優化了代碼的結構,很多易變的元素都可以通過配置來修訂.
  2. 配置文件是一個文件,那麼使用的時候不可避免的涉及到IO操作.
  3. 在內存不值錢的今天,我們到底是讀內存快還是讀文件快?
  4. 電腦存儲交互的情況下,不是也有緩存的結構嗎?

想解決的問題

  1. 減少對配置文件的訪問
  2. 讀配置的過程一次完成
  3. 讀配置改為讀內存

Prototype Multiton FactoryMethod

  1. 配置中的每個element,其實就是一個節點(XmlNode).如果把每個節點抽象成一個對象,我們其實是如何使用這個對象的?我們當然是只需要使用它的副本就好,這裡使用Prototype來作為節點的拷貝母體.
  2. 我們讀配置文件的時候需要使用一個Name來定位element,那麼我們當然也可以使用一個傳入的Name參數來需求一個工廠(FactoryMethod)幫我們生成prototype的拷貝對象.
  3. 所有節點在結構上是一個平行的關係,我們可以認為都是具有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: 點讚的隨意,點反對的留言

模式的混合-我們真的需要一次一次的讀配置嗎-MultitonPrototypeFactoryMethod的更多相关文章

  1. 依赖注入及AOP简述(八)——混合请求模式 .

    2.3.    混合请求模式 上一节讲到了FQCN(全类名)请求模式会带来依赖定义的柔软性较差的问题,因此字符串和全类名混合的模式又应运而生了.比如刚才的Spring中的API方式声明注入点的例子就可 ...

  2. HybridStart混合应用开发框架

    转自我的博客,原文地址:http://refined-x.com/2017/06/26/%E5%9F%BA%E4%BA%8EAPICloud%E7%9A%84%E6%B7%B7%E5%90%88%E5 ...

  3. 混合开发框架Flutter

    Flutter开发简介与其他的混合开发的对比 为什么要使用Flutter? 跨平台技术简介 Hybrid技术简介 QT简介 Flutter简介 为什么要使用Flutter? Flutter有什么优势? ...

  4. linux虚拟机网络连接模式 bridged, host-only, NAT

    最近安装了fedora9.0,却一直不能连接到外网,我用的是3G无线网卡上网的,起初以为是linux不支持3G无线方式的,可后来装了虚拟机ubuntu却可以上网,在后来用有ADSL网络连接的电脑安装f ...

  5. apache 三种工作模式的讲解

    Apache 2.X  支持插入式并行处理模块,称为多路处理模块(MPM).在编译apache时必须选择也只能选择一个MPM,对类UNIX系统,有几个不同的MPM可供选择,它们会影响到apache的速 ...

  6. java设计模式--行为型模式--迭代模式

    迭代器模式 概述 给定一个语言,定义它的文法的一种表示,并定义一个解释器,这个解释器使用该表示来解释语言中的句子. 适用性 .访问一个聚合对象的内容而无需暴露它的内部表示. .支持对聚合对象的多种遍历 ...

  7. 经典CSS颜色混合模式

    转自:http://www.webhek.com/css-blend-mode/ 注意:只有使用最新版的谷歌浏览器.火狐浏览器,才能正确的显示本文中的演示. Photoshop里最没有用处的一种功能— ...

  8. XCode工程中ARC模式与非ARC模式共用(转)

    Xcode 项目中经常会融合一些老的代码,它们可能采用非ARC的模式.混合编译时,就会碰到编译出错的情况. 如何共用ARC模式和非ARC模式呢? XCode除了提供整个项目是否使用ARC模式的选择外, ...

  9. 浅析Unity中的Enlighten与混合光照

    0x00 前言 在Unity的5.6版本之前的5.x中,主要使用了Geomerics公司的Enlighten[1]来提供实时全局照明以及烘焙全局照明,在5.6之后Unity引入了新的Lightmapp ...

随机推荐

  1. Eloquent ORM笔记

    基本操作 新增 $user = new User; $user->name = 'John'; $user->save(); $insertedId = $user->id;//从对 ...

  2. php-fpm进程数优化

    php-fpm未优化网友反映的问题 1.最近将Wordpress迁移至阿里云.由于自己的服务器是云服务器,硬盘和内存都比较小,所以内存经常不够使,通过ps ax命令查看后,发现启动php-fpm进程数 ...

  3. [常见问题]解决创建servlet 找不到webservlet包.

    今天在创建一个springmvc项目的时候发现 使用的HttpServletRequest不起作用, 提示需要映入 jar文件, 于是便有了今天的这个问题: 百度了下才发现 项目需要导入Runtime ...

  4. C#并行编程-线程同步原语

    菜鸟学习并行编程,参考<C#并行编程高级教程.PDF>,如有错误,欢迎指正. 目录 C#并行编程-相关概念 C#并行编程-Parallel C#并行编程-Task C#并行编程-并发集合 ...

  5. fir.im weekly - 「 持续集成 」实践教程合集

    我们常看到许多团队和开发者分享他们的持续集成实践经验,本期 fir.im Weekly 收集了 iOS,Android,PHP ,NodeJS 等项目搭建持续集成的实践,以及一些国内外公司的内部持续集 ...

  6. session 学习

    session机制是一种服务器端的机制,服务器使用一种类似于散列表的结构(也可能就是使用散列表)来保存信息. 当程式需要为某个客户端的请求创建一个session的时候,服务器首先检查这个客户端的请求里 ...

  7. draggable属性设置元素是否可拖动。

    设置标签属性draggable="true"将一个标签内的元素拖动到另外一个标签进行显示: <!DOCTYPE HTML> <html> <head& ...

  8. Git使用相关

    Git使用相关 使用git这么久还是时不时碰到小问题,根本原因在于没有仔细研究和做笔记 Git修改remote地址 之前一直使用的ssh的地址,估计是没配置好,每次都需要输密码烦死了,今天看到个用ht ...

  9. 支持自动切换的tab标签代码札记

    html代码如下: <!-- tab标签代码begin --> <div class="tab1" id="tab1"> <div ...

  10. 选择排序java代码

    /** * 选择排序 * * 原理:将最小值与数组第1个即array[0]交换,第二次则忽略array[0],直接从array[1]至array[array.length-1]中 * 选择出最小值与a ...