首页 > 解决方案 > 使用 Builder 模式和受保护的访问修饰符

问题描述

我正在读一本设计模式的书,下面是作者使用的一些代码示例。作者尝试将 html 构建器构建为:

public class HtmlElement
{
    public string Name, Text;
    public List<HtmlElement> Elements = new List<HtmlElement>();

    public HtmlElement() { }
    public HtmlElement(string name, string text)
    {
        Name = name;
        Text = text;
    }
    // factory method
    public static HtmlBuilder Create(string name)
    {
       return new HtmlBuilder(name);
    } 
}

//builder class
public class HtmlBuilder
{
    protected readonly string rootName;
    protected HtmlElement root = new HtmlElement();
    public HtmlBuilder(string rootName)
    {
        this.rootName = rootName;
        root.Name = rootName;
    }
    public HtmlBuilder AddChild(string childName, string childText)
    {
        var e = new HtmlElement(childName, childText);
        root.Elements.Add(e);
        return this;            //fluent api
    }

     // to return a HtmlElement object
    public static implicit operator HtmlElement(HtmlBuilder builder)
    {
        return builder.root;
    }
    public override string ToString() => root.ToString();
}

然后作者说:

“为了简单地强制用户在构造HtmlElement对象时使用 Builder,我们将HtmlElement类的所有构造函数隐藏为”:

public class HtmlElement
{
   ...
   protected HtmlElement() { }
   protected HtmlElement(string name, string text)
   {
      Name = name;
      Text = text;
   }
   ...
}

所以用户可以去喜欢

HtmlElement root = HtmlElement.Create("ul").AddChildFluent("li", "hello").AddChildFluent("li", "world");

Console.WriteLine(root);

这里是我不明白的,作者将HtmlElement's 构造函数的访问修饰符更改为protected,这意味着HtmlBuilder该类无法访问受保护的构造函数,例如

protected HtmlElement root = new HtmlElement();    // not allowed

那么这是否意味着我们需要让HtmlBuilder继承自HtmlElement?但是它们根本不是继承上下文,那么我该如何修改呢?

标签: c#design-patternsbuilder

解决方案


那个代码是错误的。构建器类无法访问。作者可能打算使用工厂方法。

我完全不同意作者的观点。

永远不要试图强迫用户以某种方式使用类来适应某种模式。构建器模式的重点是在构建对象时降低复杂性,而不是让它变得更难。

当构建对象链而不是像 HTML 元素这样的简单对象时,最常使用构建器模式。例如,您可以拥有一个 CarBuilder 来构建具有引擎、变速箱和所有其他获得功能性汽车所需的对象的汽车。

您可能有一个SafeCarBuilder使用更强大的底盘但相同的引擎和一个FastCarBuilder使用默认底盘但向引擎添加涡轮增压器的车型。


推荐阅读