设计模式 - 建造者模式

定义

Separate the construction of a complex object from its representation so that the same construction process can create different representations.

UML

实例

StringBuilder,JSon数据交换

  1. 减少 重叠构造函数(telescopic constructor) 的出现。
  2. 构造组合树或其他复杂对象。

比较

比较 建造者模式 备注
抽象工厂 重点关注如何分步生成复杂对象,在获取产品前可以执行一些额外构造步骤 抽象工厂专门用于生产一系列相关对象,可以马上返回产品
组合模式 建造者可以递归创建复杂组合模式树
桥接模式 各种不同的建造者负责实现工作 主管类负责抽象工作

扩展

TreeList根据不同类型,绑定不同数据,并跳转不同页面。同时,根据状态显示不同图标。

IBuilder

interface IBuilder
{
    List<TreeNodeDto> Result { get; }
    void Reset();
    void BuildBase();
    void BuildPass(string name);

    /// <summary>
    /// 刷新子节点状态
    /// </summary>
    /// <param name="tree"></param>
    /// <param name="recipe"></param>
    void RefreshSubNodeStatus(TreeList tree, Demo demo);
}

Director

class Director
{
    private readonly IBuilder _builder;

    public Director(IBuilder builder)
    {
        _builder = builder;
    }
    public void ChangeBuilder(IBuilder builder)
    {
    }
    public void Make(List<string> passes)
    {
        _builder.BuildBase();
        foreach (var name in passes)
        {
            _builder.BuildPass(name);
        }
    }
    public void RefreshSubNodeStatus(TreeList tree, Demo demo)
    {
        _builder.RefreshSubNodeStatus(tree, recipe);
    }
}
class DirectorFactory
{
    public static IBuilder GenerateDirector(DemoTypeEnum type)
    {
        IBuilder builder = null;
        switch (type)
        {
            case DemoTypeEnum.Type1:
                builder = new Concrete1Builder();
                break;
            case DemoTypeEnum.Type12:
                builder = new Concrete2Builder();
                break;
            default:
                break;
        }
        return builder;
    }
}

ConcreteBuilder


class Concrete1Builder : BuilderBase
{
    public Concrete1Builder() : base()
    {
    }
    public override void BuildBase()
    {
        Result.Add(new TreeNodeDto(1, 0, TreeNodeEnum.TreeNode, typeof(UserControl1)));
        Result.Add(new TreeNodeDto(2, 0, TreeNodeEnum.TreeNode2, typeof(UserControl2)));
        Result.Add(new TreeNodeDto(3, 0, TreeNodeEnum.TreeNode3, typeof(UserControl3)));
        _passId = _passParentId = Result.Count;
    }
    public override void BuildPass(string name)
    {
        _passId += 1;
        Result.Add(new TreeNodeDto(_passId, _passParentId, name, typeof(Nullable)));
        var id = _passId + 1;
        Result.Add(new TreeNodeDto(id++, _passId, TreeNodeEnum.ChildNode, typeof(UserControl4)));
        Result.Add(new TreeNodeDto(id++, _passId, TreeNodeEnum.ChildNode2, typeof(UserControl5)));
        Result.Add(new TreeNodeDto(id++, _passId, TreeNodeEnum.ChildNode3, typeof(UserControl6)));

        _passId = id;
    }
}

class BuilderBase : IBuilder
{
    protected int _passParentId;
    protected int _passId;

    public List<TreeNodeDto> Result { get; }

    protected Demo _demo;
    public BuilderBase()
    {
        Result = new List<TreeNodeDto>();
    }
    public virtual void Reset()
    {
        Result.Clear();
    }
    public virtual void BuildBase()
    {
    }
    public virtual void BuildPass(string name)
    {
    }
    public void RefreshSubNodeStatus(TreeList tree, Demo demo)
    {
        if (demo == null)
        {
            return;
        }
        _demo = demo;
        foreach (TreeListNode node in tree.Nodes)
        {
            var txt = node.GetDisplayText(0);
            var data = tree.GetDataRecordByNode(node) as TreeNodeDto;
            if (data == null)
            {
                continue;
            }
            bool isCompleted = false;
            bool isEnabled = false;
            var @enum = GlobalCommFunc.EnumHelper.GetValueByDescription<TreeNodeEnum>(data.DisplayText);
            switch (@enum)
            {
                case TreeNodeEnum.TreeNode:
                    {
                        isCompleted = IsTreeNodeValidable();
                        isEnabled = IsTreeNodeEditable();
                    }
                    break;
                case TreeNodeEnum.TreeNode2:
                    {
                        isCompleted = IsTreeNode2Validable();
                        isEnabled = IsTreeNode2Editable();
                    }
                    break;
                case RecipeNodeEnum.TreeNode3:
                    {
                        bool treeNodeCompleted = true;
                        foreach (TreeListNode passNode in node.Nodes)
                        {
                            bool passNodeCompleted = true;
                            var passData = tree.GetDataRecordByNode(passNode) as TreeNodeDto;
                            if (passData == null)
                            {
                                continue;
                            }
                            foreach (TreeListNode childNode in passNode.Nodes)
                            {
                                bool childNodeIscompleted = false;
                                var childData = tree.GetDataRecordByNode(childNode) as TreeNodeDto;
                                if (childData == null)
                                {
                                    continue;
                                }
                                @enum = GlobalCommFunc.EnumHelper.GetValueByDescription<TreeNodeEnum>(data.DisplayText);
                                switch (@enum)
                                {
                                    case RecipeNodeEnum.ChildNode:
                                        {
                                            childNodeIscompleted = IsChildNodeValidable();
                                            isEnabled = IsChildNodeEditable();
                                        }
                                        break;
                                    case RecipeNodeEnum.ChildNode2:
                                        {
                                            childNodeIscompleted = IsChildNode2Validable();
                                            isEnabled = IsChildNode2Editable();
                                        }
                                        break;
                                    case RecipeNodeEnum.ChildNode3:
                                        {
                                            childNodeIscompleted = IsChildNode3Validable();
                                            isEnabled = IsChildNode3Editable();
                                        }
                                        break;
                                    default:
                                        //其他不存在的节点,默认为Complete,否则会影响最终颜色显示
                                        childNodeIscompleted = true;
                                        break;
                                }
                                childNode.Tag = isEnabled;
                                //更新节点状态
                                if (childNodeIscompleted)
                                {
                                    childData.ImageIndex = 0;
                                }
                                else if (isEnabled)
                                {
                                    childData.ImageIndex = 1;
                                }
                                else
                                {
                                    childData.ImageIndex = 2;
                                }
                                passNodeCompleted &= childNodeIscompleted;
                            }
                            if (passNodeCompleted)
                            {
                                isCompleted = true;
                                isEnabled = true;
                            }
                            else
                            {
                                isCompleted = false;
                            }
                            passNode.Tag = isEnabled;
                            if (!recipe.CurrentPass.Active)
                            {
                                passData.ImageIndex = 3;
                            }
                            else if (isCompleted)
                            {
                                passData.ImageIndex = 0;
                            }
                            else if (isEnabled)
                            {
                                passData.ImageIndex = 1;
                            }
                            else
                            {
                                passData.ImageIndex = 2;
                            }
                            treeNodeCompleted &= passNodeCompleted;
                        }
                        if (treeNodeCompleted)
                        {
                            isCompleted = true;
                            isEnabled = true;
                        }
                        else
                        {
                            isCompleted = false;
                        }
                    }
                    break;
                default:
                    break;
            }
            node.Tag = isEnabled;
            if (isCompleted)
            {
                data.ImageIndex = 0;
            }
            else if (isEnabled)
            {
                data.ImageIndex = 1;
            }
            else
            {
                data.ImageIndex = 2;
            }
        }
    }
}

posted @ 2022-04-21 23:41  wesson2019  阅读(15)  评论(0编辑  收藏  举报