设计模式

第 8 章 Abstract Factory 模式 -- 将关联

2018-09-03  本文已影响26人  oO反骨仔Oo
image.png

Abstract Factory 模式

抽象工厂的工作是将“抽象零件”组装为“抽象产品”。

Show me the code

image.png
namespace 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.png

AbstractProduct:抽象产品

AbstractProduct 角色负责定义 AbstractFactory 角色所生成的抽象零件(Item、Tray、Link)和产品(Page)的接口。

AbstractFactory:抽象工厂

AbstractFactory 角色负责定义用于生成抽象产品的接口。

Client:委托者

示例中的 Progress 类扮演。

ConcreteProduct:具体产品

ConcreteProduct 角色负责实现 AbstractProduct 角色定义的接口。

ConcreteFactory:具体工厂

ConcreteFactory 角色负责实现 AbstractFactory 角色定义的接口

相关模式

Builder 模式

Abstract Factory 模式通过调用抽象产品的接口来组装抽象产品,生成具有复杂结构大的实例;
Builder 模式则是分阶段地制作复杂实例。

Factory Method 模式

Composite 模式

Singleton 模式

备注

感觉该篇文章代码多且复杂,主要看下类图就可以了。

上一篇 下一篇

猜你喜欢

热点阅读