当前位置:主页   - 电脑 - 网站开发 - ASP.Net
DotNet源代码中的模式Builder生成器模式
来源:网络   作者:   更新时间:2012-03-13
收藏此页】    【字号    】    【打印】    【关闭

  将一个复杂对象的构件与它的表示分离,使得同样的构建过程可以创建不同的表述。

DotNet源代码中的模式Builder生成器模式 

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

  具体建造者(Concrete Builder)角色:担任这个角色的是于应用程序紧密相关的类,它们在应用程序调用下创建产品实例。这个角色主要完成的任务包括:实现Builder角色提供的接口,一步一步完成创建产品实例的过程;在建造过程完成后,提供产品的实例。

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

  产品(Product)角色:产品便是建造中的复杂对象。

  以以.NET Framework 2.0 System.Text. StringBuilder为例

  System.Text. StringBuilder

Code
public sealed class StringBuilder : ISerializable
{
    //
    internal IntPtr m_currentThread = Thread.InternalGetCurrentThread();
    internal int m_MaxCapacity = 0;
    internal volatile String m_StringValue = null;
    //
    public StringBuilder() : this(DefaultCapacity)
    {

    }
    //
    public StringBuilder Append(String value)
    {
        //If the value being added is null, eat the null
        //and return.
        if (value == null)
        {
            return this;
        }

        IntPtr tid;
        // hand inlining of GetThreadSafeString
        String currentString = m_StringValue;
        tid = Thread.InternalGetCurrentThread();
        if (m_currentThread != tid)
            currentString = String.GetStringForStringBuilder(currentString, currentString.Capacity);

        int currentLength = currentString.Length;

        int requiredLength = currentLength + value.Length;

        if (NeedsAllocation(currentString, requiredLength))
        {
            String newString = GetNewString(currentString, requiredLength);
            newString.AppendInPlace(value, currentLength);
            ReplaceString(tid, newString);
        }
        else
        {
            currentString.AppendInPlace(value, currentLength);
            ReplaceString(tid, currentString);
        }

        return this;
    }
    //
    public StringBuilder Append(int value)
    {
        return Append(value.ToString(CultureInfo.CurrentCulture));
    }
    //
    public override String ToString()
    {
        //
        // We assume that their read of m_currentThread will always occur after read of m_StringValue.
        // If these reads get re-ordered then it is possible to get a currentString owned by some other
        // (mutating) thread and yet think, according to currentThread, that such was not the case.
        // This is acheived by marking m_StringValue as volatile.
        //
        String currentString = m_StringValue;
        IntPtr currentThread = m_currentThread;

        //
        // Note calling ToString the second time or from a different thread will cause allocation of a new string.
        // If we do not make a copy if currentThread is IntPtr.Zero, we will have following race:
        //
        // (1) Thread T1 completes a mutation of the string and will become the owner.
        // T1 then starts another mutation operation and
        // A thread interleaving happens at this point.
        // (2) Thread T2 starts a ToString operation.  T2 reads m_StringValue into its local currentString variable.
        // A thread interleaving happens at this point.
        // (3) Thread T3 finshes a mutation of the string in the StringBuilder , performing the ReplaceString call.
        // Thread T3 then starts a ToString operation.  Assuming the string is not wasting excessive space,
        // T3 will proceeds to call ClearPostNullChar, registers NOBODY as the owner, and returns the string.
        // A thread interleaving happens at this point.
        // (4) Thread T2 resumes execution.  T2 reads m_currentThread and sees that NOBODY is the registered owner
        //  Assuming its currentString is not wasting excessive space, T2 will return the same string that thread T1 is
        //  in the middle of mutating.
        //
        if (currentThread != Thread.InternalGetCurrentThread())
        {
            return String.InternalCopy(currentString);
        }

        if ((2 * currentString.Length) < currentString.ArrayLength)
        {
            return String.InternalCopy(currentString);
        }

        currentString.ClearPostNullChar();
        m_currentThread = IntPtr.Zero;
        return currentString;
    }
}

 

System.String

Code
public sealed class String : IComparable, ICloneable, IConvertible, IEnumerable
{
    //
    // Creates a new string with the characters copied in from ptr. If
    // ptr is null, a string initialized to ";<;No Object>;"; (i.e.,
    // String.NullString) is created.
    //
    [CLSCompliant(false), MethodImplAttribute(MethodImplOptions.InternalCall)]
    unsafe public extern String(char* value);
    [CLSCompliant(false), MethodImplAttribute(MethodImplOptions.InternalCall)]
    unsafe public extern String(char* value, int startIndex, int length);

    [CLSCompliant(false), MethodImplAttribute(MethodImplOptions.InternalCall)]
    unsafe public extern String(sbyte* value);
    [CLSCompliant(false), MethodImplAttribute(MethodImplOptions.InternalCall)]
    unsafe public extern String(sbyte* value, int startIndex, int length);

    [CLSCompliant(false), MethodImplAttribute(MethodImplOptions.InternalCall)]
    unsafe public extern String(sbyte* value, int startIndex, int length, Encoding enc);
    //
    // Creates a new string from the characters in a subarray.  The new string will
    // be created from the characters in value between startIndex and
    // startIndex + length - 1.
    //
    [MethodImplAttribute(MethodImplOptions.InternalCall)]
    public extern String(char[] value, int startIndex, int length);

    // Creates a new string from the characters in a subarray.  The new string will be
    // created from the characters in value.
    //

    [MethodImplAttribute(MethodImplOptions.InternalCall)]
    public extern String(char[] value);
    //

    internal unsafe void AppendInPlace(String value, int currentLength)
    {
  f     int count = value.Length;
        int newLength = currentLength + count;

        //

        fixed (char* dest = &this.m_firstChar)
        {
            fixed (char* src = &value.m_firstChar)
            {
                wstrcpy(dest + currentLength, src, count);
            }
            dest[newLength] = '';
        }
        this.m_stringLength = newLength;
    }

    //

}

其它资源
来源声明

版权与免责声明
1、本站所发布的文章仅供技术交流参考,本站不主张将其做为决策的依据,浏览者可自愿选择采信与否,本站不对因采信这些信息所产生的任何问题负责。
2、本站部分文章来源于网络,其版权为原权利人所有。由于来源之故,有的文章未能获得作者姓名,署“未知”或“佚名”。对于这些文章,有知悉作者姓名的请告知本站,以便及时署名。如果作者要求删除,我们将予以删除。除此之外本站不再承担其它责任。
3、本站部分文章来源于本站原创,本站拥有所有权利。
4、如对本站发布的信息有异议,请联系我们,经本站确认后,将在三个工作日内做出修改或删除处理。
请参阅权责声明