设计模式 - 建造者模式
定义
Separate the construction of a complex object from its representation so that the same construction process can create different representations.
UML
实例
StringBuilder,JSon数据交换
- 减少 重叠构造函数(telescopic constructor) 的出现。
- 构造组合树或其他复杂对象。
比较
比较 | 建造者模式 | 备注 |
---|---|---|
抽象工厂 | 重点关注如何分步生成复杂对象,在获取产品前可以执行一些额外构造步骤 | 抽象工厂专门用于生产一系列相关对象,可以马上返回产品 |
组合模式 | 建造者可以递归创建复杂组合模式树 | |
桥接模式 | 各种不同的建造者负责实现工作 | 主管类负责抽象工作 |
扩展
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;
}
}
}
}