当幸福来敲门

技术改变人生
posts - 24, comments - 4, trackbacks - 0, articles - 0
  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理

2011年8月5日

老赵博客文章地址:http://www.cnblogs.com/JeffreyZhao/archive/2009/11/26/string-concat-perf-1-benchmark.html

很久以前就知道string 和 stringBuilder 的区别。但是一直没有深入理解。看了老赵的文章。记录个人理解如下:

string:

    string对象是不可变的,使用了string.Concat方法,每次都会生成新的字符串。

    string.Concat方法有多个重载方法,可以接受字符串数组。

    如果在已经知道字符串个数的情况下,可以将开辟新空间的代价减到最小,直接填充数据即可。因此在这种情况下,性能非常高。

stringBuilder:

    stringBuilder对象是可变的。

    但是当修改stringBuilder对象时,分为两种情况:

       1、如果提供了足够的容量,那么则不会重新分配空间,调用AppendInPlace方法复制一个新的字符串到原字符串后面。

       2、但在容量不充足的情况下,则会调用GetNewString方法,自动分析新的空间,且容量翻倍。

   如果我们一下子提供足够的容量,因此在NewStringBuilder方法中一次“扩容”都不需要,因此也就不会调用GetNewString方法了。此时AppendInPlace方法占用的比例增加了。与此对应的是StringBuilder的构造函数开销也增大了——因为需要一下子开辟较多的空间。由于总时间消耗地少,因此采样总数也比之前有所减少

结论:(老赵)   

  •     StringBuilder:如果能够确定目标字符串的最终长度,则可以使用StringBuilder。如果不能确定的话,也可以在一开始指定更大的容量,减少扩容的次数。
  •     String.Concat:如果不能确定最终长度,但是能够确定字符串的个数(如这个场景),可以将它们放在一个数组中,并调用String.Concat进行连接。
  •     StringListBuilder:折衷方案,与String.Concat相比其优势在于无需确定字符串个数,与StringBuilder相比其优势在于“扩容”操作只需复制一些引用即可。
  •  

    posted @ 2011-08-05 16:32 宝多 阅读(122) 评论(0) 编辑

    2011年8月4日

    前段时间刚学习完 js闭包 到现在又忘了。所以特此纪录下来。

    两个例子都是在网上找到的。在这里只是记录下自己的理解。

    例1:

    HTML代码:

    <form id="form1" runat="server">
        
    <ul id="ul1">
            
    <li>1</li>
            
    <li>2</li>
            
    <li>3</li>
        
    </ul>
    </form>

    JS代码:

    function xc() {
         
    var ul1 = document.getElementById("ul1").getElementsByTagName("li");
         
    for (var i = 0; i < ul1.length; i++) {
             ul1[i].onclick 
    = function() {
                 alert(i);
                 }
             }
         }
    window.onload 
    = xc;

    运行结果:

    ater(i)运行结果一直都是3。

    首先在 function xc()里定义了一个 局部变量i,在该方法内部又定义了另外一个方法 ul1[i].onclick = function(){ alter(i); },此方法使用了xc()定义的变量i。并将该方法返回给了 xc()的外部变量(ul1[i].onclick)。

    此时 function(){ alter(i);} 就会形成一个闭包。

    如果想得到正常的 1,2,3结果的话,需要添加如下代码:

     

    function xc() {
        var ul1 
    = document.getElementById("ul1").getElementsByTagName("li");
            f
    or (var i = 0; i < ul1.length; i++) {
               
    ul1[i].i = i; 
                ul1[i].onclick = function() {
                    alert(
    this.i) ;
                }
            }
        }
    window.onload 
    = xc;

     

    为什么结果一直为3?

    可以理解为:

        解释1:因为 i为局部变量,不能以 window.i或者obj.i的形式在后期引用。所以只能以 指标 或 变量地址 的方式来引用该变量。既然是以地址引用变量,那么就会共用一个变量i。

        解释2:Javascript的垃圾回收机制中,如果一个对象不在被引用的话,这个对象会自动被回收。如果两个对象相互引用,并且不再被第三个对象所引用的话,那么这两个对象也一样会被回收。但因为局部变量i 被xc()外部的对象继续引用,所以每次调用 alter(i)时,都是同一个i累加而成的。

    关于解释2,还有个例子更为明显。

    例2:

    function a(
        
    var i = 0;
        
    function b(){
            alert(
    ++i);
        }
        
    return b;
    )
    var c = a();
    c(); 结果: 1
    c(); 结果: 2

    因为 a 的内部的变量i被内部方法b引用,并且将 b方法返回给 a()外部的对象 c,那么a()方法中的i就不会被回收,所以每次的结果都会加1。(是不是也可以说,因为 变量i同样是以指针或地址的形式保存的?)

    但是如果a方法没有返回b,那么不论执行多少次a(),结果永远为1 

           function a() {
                
    var i = 0;
                
    function b() {                 
                    alert(
    ++i);
                }
                b();
            }
            a(); // 结果 1
            a(); // 结果 1

    这两个例子是网上解释js闭包概念时,用的比较多的。(未完)

     

    posted @ 2011-08-04 14:40 宝多 阅读(93) 评论(0) 编辑

    2011年3月7日

    建造者模式

         以下内容示例部分引用:http://terrylee.cnblogs.com/archive/2005/12/19/299878.html

                    文字部分引用:http://www.cnblogs.com/zhenyulu/articles/37378.html

    概述:

        在软件系统中,有时候面临着“一个复杂对象”的创建工作,其通常由各个部分的子对象用一定的算法构成;由于需求的变化,这个复杂对象的各个部分经常面临着剧烈的变化,但是将它们组合在一起的算法确相对稳定。

    意图:

         将一个复杂的构建与其表示相分离,使得同样的构建过程可以创建不同的表示。

    对象性质的建造:

         有些情况下,一个对象会有一些重要的性质,在它们没有恰当的值之前,对象不能作为一个完整的产品使用。比如,一个电子邮件有发件人地址、收件人地址、主题、内容、附录等部分,而在最起码的收件人地址未被赋值之前,这个电子邮件不能发出。

         有些情况下,一个对象的一些性质必须按照某个顺序赋值才有意义。在某个性质没有赋值之前,另一个性质则无法赋值。    

         这时候,此对象相当于一个有待建造的产品,而对象的这些性质相当于产品的零件,建造产品的过程就是组合零件的过程。由于组合零件的过程很复杂,因此,这些“零件”的组合过程往往被“外部化”到一个称作建造者的对象里,建造者返还给客户端的就是一个全部零件都建造完毕的产品对象。

     

    /// <summary>
    /// Food类,即产品类
    /// </summary>
        public class Food
        {
            Hashtable food 
    = new Hashtable();

            
    /// <summary>
            
    /// 添加食品
            
    /// </summary>
            
    /// <param name="strName">食品名称</param>
            
    /// <param name="Price">价格</param>
            public void Add(string strName, string Price)
            {
                food.Add(strName, Price);
            }

            
    public void Show()
            {
                IDictionaryEnumerator myEnumerator 
    = food.GetEnumerator();
                Console.WriteLine(
    "Food List:");

                Console.WriteLine(
    "-------------------------");
                
    string strfoodlist = "";
                
    while (myEnumerator.MoveNext())
                {
                    strfoodlist 
    = strfoodlist + "\n\n" + myEnumerator.Key.ToString();
                    strfoodlist 
    = strfoodlist + ":t" + myEnumerator.Value.ToString();
                }

                Console.WriteLine(strfoodlist);
                Console.WriteLine(
    "\n-----------------------");
            }
        }

     

       /// <summary>
        
    /// Builder类,即抽象建造者类,构造套餐
        
    /// </summary>
        public abstract class Builder
        {
            
    /// <summary>
            
    /// 添加汉堡
            
    /// </summary>
            public abstract void BuildHamb();

            
    /// <summary>
            
    /// 添加可乐
            
    /// </summary>
            public abstract void BuildCoke();
            
            
    /// <summary>
            
    /// 添加薯条
            
    /// </summary>
            public abstract void BuildChip();

            
    /// <summary>
            
    /// 返回结果
            
    /// </summary>
            
    /// <returns></returns>
            public abstract Food GetFood();
        }

      

        /// <summary>
        
    /// FoodManager类,即指导者
        
    /// </summary>
        public class FoodManager
        {
            
    public void Construct(Builder builder)
            {
                builder.BuildHamb();

                builder.BuildCoke();

                builder.BuildChip();
            }
        }

     

     

      /// <summary>
        
    /// 添加NormalBuilder类,具体构造者,普通套餐
        
    /// </summary>
        public class NormalBuilder : Builder
        {
            
    private Food NormalFood = new Food();

            
    public override void BuildHamb()
            {
                NormalFood.Add(
    "NormalHamb""¥10.50");
                
    //throw new NotImplementedException();
            }

            
    public override void BuildCoke()
            {
                NormalFood.Add(
    "CokeCole""¥4.50");
                
    //throw new NotImplementedException();
            }

            
    public override void BuildChip()
            {
                NormalFood.Add(
    "FireChips""¥2.00");
                
    //throw new NotImplementedException();
            }

            
    public override Food GetFood()
            {
                
    return NormalFood;
                
    //throw new NotImplementedException();
            }
        }

        
    /// <summary>
        
    /// 添加GooldBuilder类,具体构造者,黄金套餐
        
    /// </summary>
        public class GoldBuilder : Builder
        {
            
    private Food GoldFood = new Food();

            
    public override void BuildHamb()
            {
                GoldFood.Add(
    "GoldHamb""¥13.50");
                
    //throw new NotImplementedException();
            }

            
    public override void BuildCoke()
            {
                GoldFood.Add(
    "CokeCole""¥4.50");
                
    //throw new NotImplementedException();
            }

            
    public override void BuildChip()
            {
                GoldFood.Add(
    "FireChips""¥3.50");
                
    //throw new NotImplementedException();
            }

            
    public override Food GetFood()
            {
                
    return GoldFood;
                
    //throw new NotImplementedException();
            }
        }

     

    建造者:(Builder)角色

         给出一个抽象接口,以规范产品对象的各个组成成分的建造。一般而言,此接口独立于应用程序的商业逻辑。模式中直接创建产品对象的是具体建造者(ConcreteBuilder)角色。具体建造者类必须实现这个接口所要求的方法:一个是建造方法,另一个是结果返还方法。

    具体建造者(GoldBuilder、NormalBuilder )角色

       担任这个角色的是于应用程序紧密相关的类,它们在应用程序调用下创建产品实例。这个角色主要完成的任务包括:  

    • 实现Builder角色提供的接口,一步一步完成创建产品实例的过程。
    • 在建造过程完成后,提供产品的实例。

     

    指导者(FoodManager)角色:

        担任这个角色的类调用具体建造者角色以创建产品对象。导演者并没有产品类的具体知识,真正拥有产品类的具体知识的是具体建造者对象。

    产品(Food)角色:

        产品便是建造中的复杂对象。

     

    在什么情况下使用建造者模式

       1、需要生成的产品对象有复杂的内部结构。

       2、需要生成的产品对象的属性相互依赖,建造者模式可以强迫生成顺序。
       3、在对象创建过程中会使用到系统中的一些其它对象,这些对象在产品对象的创建过程中不易得到。

    posted @ 2011-03-07 15:44 宝多 阅读(73) 评论(0) 编辑

    2011年3月4日

    抽象工厂模式

            这里的示例出自:http://blog.csdn.net/MONKEY_D_MENG/archive/2010/07/01/5707076.aspx。引用的是《大话设计模式》这本书的例子。

            并且工厂模式与抽象工厂模式之间的区别也是通过其它文章了解的。只不过是把自己所理解的东西写出来而己。如果看到这些文章的朋友,发现了错误,希望您能告诉我一下。但希望不要

    意图   

             提供一个创建一系列相关或相互依赖对象的接口,而无需指定他们具体的类。

    //用户实体类
    public class User
    {
        
    private int id;
        
    private String name;
        
        
    public int getId()
        {
           
    return id;
        }

        
    public void setId(int id)
        {
           
    this.id = id;
        }

        
    public String getName()
        {
           
    return name;
        }
     
        
    public void setName(String name)
        {
           
    this.name = name;
        }
    }

    //Department实体类。
    public class Department
    {
        
    private int id;
        
    private String name;
        
        
    public int getId()
        {
            
    return id;
        }

        
    public void setId(int id)
        {
            
    this.id = id;
        }

        
    public String getName()
        {
            
    return name;
        }
      
        
    public void setName(String name)
        { 
            
    this.name = name;
        }
    }

     

     

    //抽象产品类
    //这里抽象产品类包括两个,一个是对User的操作,另一个是对IDepartment的操作。
    public interface IUser
    {
        
    void insert(User user);
        User getUser(
    int id);
    }

    public interface IDepartment
    {
        
    void insert(Department department);    
        Department getDepartment(
    int id);
    }

     

     

    //SQL ServerUser操作类.
    //实现IUser接口
    public class SqlServerUser : IUser
    {
        
    public void insert(User user)
        {
           Console.Write(
    "在SQL Server中给User表增加一条记录");
        }

        
    public User getUser(int id)
        {
           Console.Write(
    "在SQL Server中根据ID得到User表一条记录");
           
    return null;
        }
    }
    //Access操作类
    //实现IUser接口
    public class AccessUser : IUser
    {
        
    public void insert(User user)
        {
           Console.Write(
    "在Access中给User表增加一条记录");
        }

        
    public User getUser(int id)
        {
           Console.Write(
    "在Access中根据ID得到User表一条记录");
           
    return null;
        }
    }

     

     

    //SqlServer操作类
    //实现IDepartment接口
    public class SqlServerDepartment : IDepartment
    {
        
    public void insert(Department department)
        {
            Console.Write(
    "在SQL Server中给Department表增加一条记录");
        }

        Department getDepartment(
    int id)
        {
            Console.Write(
    "在SQL Server中根据ID得到Department表一条记录");
        }
    }
    //Access操作类
    //实现Idepartment接口
    public class AccessDepartment : IDepartment
    {
        
    public void insert(Department department)
        {
            Console.Write(
    "在Access中给Department表增加一条记录");
        }

        
    public Department getDepartment(int id)
        {
            Console.Write(
    "在Access中根据ID得到Department表一条记录");
        }
    }

     

     

     

    //抽象工厂类,主要负责分别生成sqlserver和access操作对象。
    public class DataAccess
    {
        
    private static final String db = "Sqlserver";
       
        
    public static IUser createUser()
        {
            Iuser result 
    = null;
            
            
    if ("Sqlserver".equals(db))
            {
                result 
    = new SqlServerUser();
            } 
    else if ("Access".equals(db))
            {
                result 
    = new AccessUser();
            }
            
    return result;
        }

        
    public static IDepartment createDepartment()
        {
            IDepartment result 
    = null;

            
    if ("Sqlserver".equals(db))
            {
                result 
    = new SqlServerDepartment();
            } 
    else if ("Access".equals(db))
            {
                result 
    = new AccessDepartment();
            }
            
    return result;
        }
    }

     

     

     

    //客户端代码
    public class Main
    {
        
    public static void main(String[] args)
        {
            User user 
    = new User();
            Department department 
    = new Department();
            
    //直接调用抽象工厂类,创建多个具体产品类的实例。(IUser和IDepartment)
            IUser iu = DataAccess.createUser();
            iu.insert(user);
            iu.getUser(
    1);

            IDepartment id 
    = DataAccess.createDepartment();
            id.insert(department);
            id.getDepartment(
    1);
        }
    }

     

     抽象工厂模式与工厂模式的区别。

        工厂设计模式:

              一个抽象产品类,可以派生出多个具体产品

                    (如IUser这个抽象产品,可以派生出Accesss及SQLServer两种,即一个抽象产品可以派生出多个具体产品)

              每个具体工厂类只能创建一个具体产品类的实例

                    (本例如果使用工厂模式,需要定义SqlFactory以及AccessFactory两个工厂以及一个抽象工厂Factory,如果只有IUser表时,只能通过SqlFactory创建一个iuser对象,这种方法即为工厂模式。

                    但现在这里边存在两个对象Iuser以及IDepartment(一系列对象),并且SQL和Access又可以看成是两大不同的分类,所以使用抽象工厂模式)

       抽工厂模式

            多个抽象产品类,可以派生出多个具体产品

            每个具体工厂类可以创建多个具体产品类的实例

    可以想像另一种举例

            现在比如说有一个生产鼠标以及健盘的厂家,如果想生成不同的产品,即是生成鼠标还是只生成健盘,可以使用工厂模式,这里只有具体对象的区别,而没有厂家的区别。

                  (这里的思想是,在客户端指定是生成鼠标还是生成健盘,鼠标与健盘继承同一个接口)             

            如果想在不同厂家之间进行切换,如生成联想的健盘鼠标套装,或者是生成其它厂家的健盘鼠标套装,就应该使用抽象工厂模式。

                 (而这里应该分别定义鼠标与键盘生产的接口,在根据抽象工厂生成具体是联想品牌还是其它厂家的品牌对象)

    对于抽象工厂模式以及工厂模式之间的区别,自己不是很清楚。现在只是通过看其它人的文章得到的学习结果。以后如果发现不对的地方,会慢慢改进的。

    在学习的过程中出现错误不怕,但一定要及时发现并改正,才是最终的学习目标.

     

    posted @ 2011-03-04 15:57 宝多 阅读(125) 评论(1) 编辑

    2011年3月3日

    文章内容出自:http://www.cnblogs.com/Terrylee/archive/2006/07/17/334911.html

    这里只是整理一下自己对于学所知识的理解,让自己在以后的日子中更能方便的回想起以前所学过的东西.并没有创新.

     

    1、工厂模式(Factory Mothod) 

    意图:

    定义一个用户创建对象的接口,让子类决定实例化哪一个类。 

    实现代码:

    ///<summary>
    ///Log类
    ///说明:定义具体类的抽象方法.
    ///<summary>
    public abstract class Log
    {
        
    public abstract void Write();
    }

    /// <summary>
    /// EventLog类
    /// 说明:子类具体实现抽象类方法
    /// </summary>
    public class EventLog:Log
    {
        
    public override void Write()
        {
            Console.WriteLine(
    "EventLog Write Success!");
        }
    }
    /// <summary>
    /// FileLog类
    /// 说明:子类具体实现抽象类方法
    /// </summary>
    public class FileLog:Log
    {
        
    public override void Write()
        {
            Console.WriteLine(
    "FileLog Write Success!");
        }


    /// <summary>
    /// LogFactory类
    /// 说明:定义抽象类,Create()方法用于由子类创建具体的对象.
    /// </summary>
    public abstract class LogFactory
    {
        
    public abstract Log Create();
    }

     

    /// <summary>
    /// EventFactory类
    /// 说明:返回具体的子类对象
    /// </summary>
    public class EventFactory:LogFactory
    {
       
    public override EventLog Create()
       {
            
    return new EventLog();
       }
    }
    /// <summary>
    /// FileFactory类
    /// 说明:返回具体的子类对象
    /// </summary>
    public class FileFactory:LogFactory
    {
        
    public override FileLog Create()
        {
            
    return new FileLog();
        }

    }  

     

    /// <summary> 
    /// 客户端实现
    /// 说明: 1、创建子类工厂对象。
    ///       2、创建具体子类实现对象。
    ///       3、调用子类方法。 
    ///       4、这样在Event和File两个子类之间进行切换的时候,直接修改new EventFactory() 为new EventFactory()即可
    ///</summary>
    public class App 
    {
        
    public static void Main(string[] args)
        {
            
    //使用new 创建实际的子类工厂,用来创建子类对象.
            LogFactory factory =new EventFactory();
            
    //调用工厂类里的方法,返回具体的子在对象。        
            Log log = factory.Create();
            
    //调用子类方法。
            log.Write(); 
        } 


    项目经验:

    在项目中需要读取外部文件:分别为Excel文件、.xxx文件两种。在项目发布时,只能存在一种文件的调用方式。那么此时使用工厂模式,根本具体的需求,通过修改new后边的子类工厂,进行不同对象之间的切换。


    posted @ 2011-03-03 14:52 宝多 阅读(100) 评论(0) 编辑

    2011年2月22日

    摘要: 1:DIV+CSS 标准模板 : http://www.aa25.cn/layout/index.shtml2:在Firefox下,外部DIV作为一个容器,并且内部DIV设置了float,此时外部DIV不能被自动撑开。而IE不会出现此问题。例: <div style = " height : auto; background-color : Yellow; border : 1px solid red; width :300px;"> <div style = "height : 100px; width :100px; background-color : Red; flo阅读全文

    posted @ 2011-02-22 09:37 宝多 阅读(99) 评论(0) 编辑

    2010年2月21日

    摘要: 果然很犀利。。。。CSDN论坛的回复。。。。--搜索指定数据在那个对象中存在.txtCREATE PROC sp_ValueSearch@value sql_variant, --要搜索的数据@precision bit=1 --1=仅根据sql_variant中的数据类型查找对应类型的数据列.<>1,查询兼容的所有列,字符数据使用like匹配ASSET NOCOUNT ONIF @v...阅读全文

    posted @ 2010-02-21 12:40 宝多 阅读(66) 评论(0) 编辑

    2010年2月10日

    摘要: 一:Properties->TextEditStyle属性:1、Standard:正常显示2、HideTextEditor:隐藏文本,文本在下拉列表中显示3、DisableTextEditor:选择整行,文本不能编辑阅读全文

    posted @ 2010-02-10 13:17 宝多 阅读(219) 评论(0) 编辑

    摘要: GridControl :去掉Drag a column header here to group by that column设置->Views->OptionsView->ShowGroupPanel->False阅读全文

    posted @ 2010-02-10 13:08 宝多 阅读(240) 评论(0) 编辑

    2010年1月20日

    摘要: 摘自MSDN的解释:this 关键字引用类的当前实例。[代码]输出:Name: John M. TrainerAlias: jtrainerTaxes: $2.40可以更好的理解,printEmployee中的this表示为类的当前对象,也就是E1对象。阅读全文

    posted @ 2010-01-20 15:26 宝多 阅读(557) 评论(2) 编辑

    无标题页