第 8 章 Abstract Factory 模式 -- 将关联
2018-09-03 本文已影响26人
oO反骨仔Oo
image.png
Abstract Factory 模式
抽象工厂的工作是将“抽象零件”组装为“抽象产品”。
Show me the code
image.pngnamespace AbstractFactoryPattern.Factories
{
/// <summary>
/// 项目
/// </summary>
public abstract class Item
{
/// <summary>
/// 标题
/// </summary>
protected string Caption;
protected Item(string caption)
{
Caption = caption;
}
/// <summary>
/// 制作 HTML
/// </summary>
/// <returns></returns>
public abstract string MakeHtml();
}
}
namespace AbstractFactoryPattern.Factories
{
/// <summary>
/// 超链接
/// </summary>
public abstract class Link : Item
{
/// <summary>
/// 地址
/// </summary>
protected string Url;
protected Link(string caption, string url) : base(caption)
{
Url = url;
}
}
}
using System.Collections.Generic;
namespace AbstractFactoryPattern.Factories
{
/// <summary>
/// 托盘
/// </summary>
public abstract class Tray : Item
{
protected List<Item> Traies = new List<Item>();
protected Tray(string caption) : base(caption)
{
}
/// <summary>
/// 添加
/// </summary>
/// <param name="item"></param>
public void Add(Item item)
{
Traies.Add(item);
}
}
}
using System;
using System.Collections.Generic;
namespace AbstractFactoryPattern.Factories
{
/// <summary>
/// 页面
/// </summary>
public abstract class Page
{
/// <summary>
/// 作者
/// </summary>
protected string Author;
/// <summary>
/// 内容
/// </summary>
protected List<Item> Contents = new List<Item>();
/// <summary>
/// 标题
/// </summary>
protected string Title;
protected Page(string title, string author)
{
Title = title;
Author = author;
}
/// <summary>
/// 添加
/// </summary>
/// <param name="item"></param>
public void Add(Item item)
{
Contents.Add(item);
}
/// <summary>
/// 输出
/// </summary>
public void Output()
{
try
{
Console.WriteLine(MakeHtml());
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
}
/// <summary>
/// 生成 HTML
/// </summary>
/// <returns></returns>
public abstract string MakeHtml();
}
}
using System;
using System.Reflection;
namespace AbstractFactoryPattern.Factories
{
/// <summary>
/// 工厂
/// </summary>
public abstract class Factory
{
/// <summary>
/// 获取工厂
/// </summary>
/// <param name="className"></param>
/// <returns></returns>
public static Factory GetFactory(string className)
{
Factory factory = null;
try
{
var assembly = Assembly.GetExecutingAssembly(); // 获取当前程序集
factory = (Factory) assembly.CreateInstance(className);
}
catch (Exception e)
{
Console.WriteLine(e);
throw;
}
return factory;
}
/// <summary>
/// 创建超链接
/// </summary>
/// <param name="caption"></param>
/// <param name="url"></param>
/// <returns></returns>
public abstract Link CreateLink(string caption, string url);
/// <summary>
/// 创建托盘
/// </summary>
/// <param name="caption"></param>
/// <returns></returns>
public abstract Tray CreateTray(string caption);
/// <summary>
/// 创建页面
/// </summary>
/// <param name="title"></param>
/// <param name="author"></param>
/// <returns></returns>
public abstract Page CreatePage(string title, string author);
}
}
using System;
using AbstractFactoryPattern.Factories;
namespace AbstractFactoryPattern
{
internal class Program
{
private static void Main(string[] args)
{
const string url = "https://360json.cn";
var factory = Factory.GetFactory("AbstractFactoryPattern.ListFactories.ListFactory");
var people = factory.CreateLink("人民日报", url);
var gmw = factory.CreateLink("光明日报", url);
var usYahoo = factory.CreateLink("Yahoo!", url);
var jpYahoo = factory.CreateLink("Yahoo!Japan", url);
var excite = factory.CreateLink("Excite", url);
var google = factory.CreateLink("Google", url);
var traynews = factory.CreateTray("日报");
traynews.Add(people);
traynews.Add(gmw);
var trayyahoo = factory.CreateTray("Yahoo!");
trayyahoo.Add(usYahoo);
trayyahoo.Add(jpYahoo);
var traysearch = factory.CreateTray("检索引擎");
trayyahoo.Add(trayyahoo);
trayyahoo.Add(excite);
trayyahoo.Add(google);
var page = factory.CreatePage("LinkPage", url);
page.Add(traynews);
page.Add(traysearch);
page.Output();
Console.Read();
}
}
}
ListFactories 命名空间下
using AbstractFactoryPattern.Factories;
namespace AbstractFactoryPattern.ListFactories
{
public class ListFactory : Factory
{
public override Link CreateLink(string caption, string url)
{
return new ListLink(caption, url);
}
public override Tray CreateTray(string caption)
{
return new ListTray(caption);
}
public override Page CreatePage(string title, string author)
{
return new ListPage(title, author);
}
}
}
using AbstractFactoryPattern.Factories;
namespace AbstractFactoryPattern.ListFactories
{
public class ListLink : Link
{
public ListLink(string caption, string url) : base(caption, url)
{
}
public override string MakeHtml()
{
return $"<li><a href='{Url}'>{Caption}</a></li>\n";
}
}
}
using System.Text;
using AbstractFactoryPattern.Factories;
namespace AbstractFactoryPattern.ListFactories
{
public class ListTray : Tray
{
public ListTray(string caption) : base(caption)
{
}
public override string MakeHtml()
{
var sb = new StringBuilder();
sb.AppendLine("<li>");
sb.AppendLine(Caption);
sb.AppendLine("<ul>");
foreach (var tray in Traies)
{
sb.Append(tray.MakeHtml());
}
sb.AppendLine("</ul>");
sb.AppendLine("</li>");
return sb.ToString();
}
}
}
using System.Text;
using AbstractFactoryPattern.Factories;
namespace AbstractFactoryPattern.ListFactories
{
public class ListPage : Page
{
public ListPage(string title, string author) : base(title, author)
{
}
public override string MakeHtml()
{
var sb = new StringBuilder();
sb.AppendLine($"<html><head><title>{Title}</title></head>");
sb.AppendLine("<body>");
sb.AppendLine($"<h1>{Title}</h1>");
sb.AppendLine("<ul>");
foreach (var content in Contents)
{
sb.AppendLine(content.MakeHtml());
}
sb.AppendLine("</ul>");
sb.AppendLine($"<hr><address>{Author}</address>");
sb.AppendLine("</body></html>");
return sb.ToString();
}
}
}
其他工厂,TableFactories 命名空间下
using AbstractFactoryPattern.Factories;
namespace AbstractFactoryPattern.TableFactories
{
public class TableFactory : Factory
{
public override Link CreateLink(string caption, string url)
{
return new TableLink(caption, url);
}
public override Tray CreateTray(string caption)
{
return new TableTray(caption);
}
public override Page CreatePage(string title, string author)
{
return new TablePage(title, author);
}
}
}
using AbstractFactoryPattern.Factories;
namespace AbstractFactoryPattern.TableFactories
{
internal class TableLink : Link
{
public TableLink(string caption, string url) : base(caption, url)
{
}
public override string MakeHtml()
{
return $"<td><a href='{Url}'>{Caption}</a></td>\n";
}
}
}
using System.Text;
using AbstractFactoryPattern.Factories;
namespace AbstractFactoryPattern.TableFactories
{
internal class TableTray : Tray
{
public TableTray(string caption) : base(caption)
{
}
public override string MakeHtml()
{
var sb = new StringBuilder();
sb.AppendLine("<td>");
sb.AppendLine($"<table width='100%' border='1'><tr>");
sb.AppendLine($"<td bgcolor='#cccccc' align='center' colspan='{Traies.Count}'><b>{Caption}</b></td>");
sb.AppendLine("</tr>");
sb.AppendLine("<tr>");
foreach (var tray in Traies)
{
sb.AppendLine(tray.MakeHtml());
}
sb.AppendLine("</tr><table>");
sb.AppendLine("</td>");
return sb.ToString();
}
}
}
using System.Text;
using AbstractFactoryPattern.Factories;
namespace AbstractFactoryPattern.TableFactories
{
internal class TablePage : Page
{
public TablePage(string title, string author) : base(title, author)
{
}
public override string MakeHtml()
{
var sb = new StringBuilder();
sb.AppendLine($"<html><head><title>{Title}</title></head>");
sb.AppendLine("<body>");
sb.AppendLine($"<h1>{Title}</h1>");
sb.AppendLine($"<table width='80%' border='3'>{Title}</h1>");
foreach (var content in Contents)
{
sb.AppendLine($"<tr>{content.MakeHtml()}</tr>");
}
sb.AppendLine("</table>");
sb.AppendLine($"<hr><address>{Author}</address>");
sb.AppendLine("</body></html>");
return sb.ToString();
}
}
}
角色梳理
image.pngAbstractProduct:抽象产品
AbstractProduct 角色负责定义 AbstractFactory 角色所生成的抽象零件(Item、Tray、Link)和产品(Page)的接口。
AbstractFactory:抽象工厂
AbstractFactory 角色负责定义用于生成抽象产品的接口。
Client:委托者
示例中的 Progress 类扮演。
ConcreteProduct:具体产品
ConcreteProduct 角色负责实现 AbstractProduct 角色定义的接口。
ConcreteFactory:具体工厂
ConcreteFactory 角色负责实现 AbstractFactory 角色定义的接口
相关模式
Builder 模式
Abstract Factory 模式通过调用抽象产品的接口来组装抽象产品,生成具有复杂结构大的实例;
Builder 模式则是分阶段地制作复杂实例。
Factory Method 模式
Composite 模式
Singleton 模式
备注
感觉该篇文章代码多且复杂,主要看下类图就可以了。