samedi 1 août 2020

Use factory and builder pattern to create some class the best way approach

I have the factory class and use builder to create the class for factory class method.

Before create builder to class there are some behavior is same. I don't want to write duplicate code so I create base factory class to encapsulate method and derivative method or delegate to builder.
So child class can override method to hook builder and operate builder.

Full Code.

public abstract class FactoryBase
{
    protected delegate void HookSomeStringHandler(StringBuilder builder);

    protected HookSomeStringHandler OnHookSomeStringHandler;

    /// <summary>
    /// You can override <see cref="InnerHookSomeString"/> to hook builder.
    /// </summary>
    public string GetSomeStringA()
    {
        var sb = new StringBuilder();
        sb.Append(GetType().Name); // need all child class name              
        InnerHookSomeString(sb);   // hook StringBuilder to append some string
        return sb.ToString();
    }

    /// <summary>
    /// Child class can override this to hook StringBuilder <see cref="GetSomeStringA"/>
    /// </summary>
    protected virtual void InnerHookSomeString(StringBuilder builder)
    {
    }

    /// <summary>
    /// You can override method to hook stringBuilder or using delegate action to hook stringBuilder. 
    /// </summary>
    public virtual string GetSomeStringB(Action<StringBuilder> outerHook)
    {
        var sb = new StringBuilder();
        sb.Append(GetType().Name);  // need all child class name              
        outerHook?.Invoke(sb);      // hook StringBuilder to append some string
        return sb.ToString();
    }

    /// <summary>
    /// Use register delegate to hook stringBuilder. <see cref="OnHookSomeStringHandler"/>
    /// </summary>
    public string GetSomeStringC()
    {
        var sb = new StringBuilder();
        sb.Append(GetType().Name);                // need all child class name              
        OnHookSomeStringHandler?.Invoke(sb);      // hook StringBuilder to append some string
        return sb.ToString();
    }
}

public class ChildA : FactoryBase
{
    public ChildA()
    {
        OnHookSomeStringHandler += (sb) =>
        {
            // TODO do something by GetSomeStringC
        };
    }

    protected override void InnerHookSomeString(StringBuilder builder)
    {
        // TODO do something by GetSomeStringA
    }

    public override string GetSomeStringB(Action<StringBuilder> outerHook)
    {
        return base.GetSomeStringB((sb) =>
        {
            // TODO do something by GetSomeStringB
        });
    }
}

Note: The Builder in GetSomeString does not need to add a string or doing something every time so I don't use the abstract method to enforce child class that must be to override.

I have three ideal to this situation.

  1. GetSomeStringA use InnerHookSomeString to hook StringBuilder and child class can operate builder but this way of writing maybe user don't know this approach so need to use tag <see cref>.

  2. GetSomeStringB use override to hook StringBuilder and can hook builder in the outer but this way of writing looks ugly.

  3. GetSomeStringC similar to GetSomeStringA, it is done by registering a delegate and need to use tag too to prompt user.

Which one of the above three methods is better to maintain or readable?
Does anyone have a better idea or suggestion?

Aucun commentaire:

Enregistrer un commentaire