【发布时间】:2020-11-22 01:23:14
【问题描述】:
我有工厂类并使用生成器为工厂类方法创建类。在下面的示例中,我将自定义构建器替换为 StringBuilder 以简化示例。
在为类创建构建器之前,有些行为是相同的。我不想编写重复的代码,所以我创建了基工厂类来封装方法和派生方法或委托给构建器。
所以子类可以重写方法来钩住builder和操作builder。
完整代码。
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
});
}
}
注意:GetSomeString 中的 Builder 不需要每次都添加字符串或做某事,所以我不使用抽象方法来强制必须覆盖的子类。
我对这种情况有三个理想。
-
GetSomeStringA使用InnerHookSomeString钩住StringBuilder,子类可以操作builder,但是这种写法可能用户不知道这种方法,所以需要使用标签<see cref>。 -
GetSomeStringB使用 override 来挂钩StringBuilder并且可以在外部挂钩 builder 但这种写法看起来很难看。 -
GetSomeStringC和GetSomeStringA类似,都是通过注册一个delegate来实现的,也需要使用tag来提示用户。
以上三种方法中哪一种更好维护或可读性更好?
有没有人有更好的想法或建议?
【问题讨论】:
标签: c# oop inheritance design-patterns hook